From 2a554cb1385d20f0907e039ef03af748ac952840 Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Mon, 18 Jan 2016 23:46:35 +0100 Subject: [PATCH 001/688] added or/and improved closable, minimizable, movable, resizable features for windows on os x and windows --- atom/browser/api/atom_api_window.cc | 30 +++++++ atom/browser/api/atom_api_window.h | 6 ++ atom/browser/native_window.cc | 8 ++ atom/browser/native_window.h | 6 ++ atom/browser/native_window_mac.h | 7 ++ atom/browser/native_window_mac.mm | 70 ++++++++++++++- atom/browser/native_window_views.cc | 110 ++++++++++++++++++++---- atom/browser/native_window_views.h | 9 ++ atom/browser/native_window_views_win.cc | 9 ++ atom/common/options_switches.cc | 34 ++++---- atom/common/options_switches.h | 2 + 11 files changed, 255 insertions(+), 36 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 09d88edb9b7..5ff9cabc909 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -408,6 +408,30 @@ bool Window::IsResizable() { return window_->IsResizable(); } +void Window::SetMovable(bool movable) { + window_->SetMovable(movable); +} + +bool Window::IsMovable() { + return window_->IsMovable(); +} + +void Window::SetMinimizable(bool minimizable) { + window_->SetMinimizable(minimizable); +} + +bool Window::IsMinimizable() { + return window_->IsMinimizable(); +} + +void Window::SetClosable(bool closable) { + window_->SetClosable(closable); +} + +bool Window::IsClosable() { + return window_->IsClosable(); +} + void Window::SetAlwaysOnTop(bool top) { window_->SetAlwaysOnTop(top); } @@ -659,6 +683,12 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("getMaximumSize", &Window::GetMaximumSize) .SetMethod("setResizable", &Window::SetResizable) .SetMethod("isResizable", &Window::IsResizable) + .SetMethod("setMovable", &Window::SetMovable) + .SetMethod("isMovable", &Window::IsMovable) + .SetMethod("setMinimizable", &Window::SetMinimizable) + .SetMethod("isMinimizable", &Window::IsMinimizable) + .SetMethod("setClosable", &Window::SetClosable) + .SetMethod("isClosable", &Window::IsClosable) .SetMethod("setAlwaysOnTop", &Window::SetAlwaysOnTop) .SetMethod("isAlwaysOnTop", &Window::IsAlwaysOnTop) .SetMethod("center", &Window::Center) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index d8e25965d89..ae10fa951db 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -106,6 +106,12 @@ class Window : public mate::TrackableObject, std::vector GetMaximumSize(); void SetResizable(bool resizable); bool IsResizable(); + void SetMovable(bool movable); + bool IsMovable(); + void SetMinimizable(bool minimizable); + bool IsMinimizable(); + void SetClosable(bool closable); + bool IsClosable(); void SetAlwaysOnTop(bool top); bool IsAlwaysOnTop(); void Center(); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 4df4b491696..1f330a261cf 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -120,6 +120,14 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { if (options.Get(options::kResizable, &resizable)) { SetResizable(resizable); } + bool minimizable; + if (options.Get(options::kMinimizable, &minimizable)) { + SetMinimizable(minimizable); + } + bool closable; + if (options.Get(options::kClosable, &closable)) { + SetClosable(closable); + } #endif bool top; if (options.Get(options::kAlwaysOnTop, &top) && top) { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 0ccf3dfbc2e..d379db2b491 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -125,6 +125,12 @@ class NativeWindow : public base::SupportsUserData, virtual gfx::Size GetMaximumSize(); virtual void SetResizable(bool resizable) = 0; virtual bool IsResizable() = 0; + virtual void SetMovable(bool movable) = 0; + virtual bool IsMovable() = 0; + virtual void SetMinimizable(bool minimizable) = 0; + virtual bool IsMinimizable() = 0; + virtual void SetClosable(bool closable) = 0; + virtual bool IsClosable() = 0; virtual void SetAlwaysOnTop(bool top) = 0; virtual bool IsAlwaysOnTop() = 0; virtual void Center() = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index ef3ccb15021..45c974c0793 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -48,6 +48,12 @@ class NativeWindowMac : public NativeWindow { const extensions::SizeConstraints& size_constraints) override; void SetResizable(bool resizable) override; bool IsResizable() override; + void SetMovable(bool movable) override; + bool IsMovable() override; + void SetMinimizable(bool minimizable) override; + bool IsMinimizable() override; + void SetClosable(bool closable) override; + bool IsClosable() override; void SetAlwaysOnTop(bool top) override; bool IsAlwaysOnTop() override; void Center() override; @@ -100,6 +106,7 @@ class NativeWindowMac : public NativeWindow { gfx::Size WindowSizeToContentSize(const gfx::Size& size) override; void UpdateDraggableRegions( const std::vector& regions) override; + void FixZoomButton(); void InstallView(); void UninstallView(); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index f128f3b2cb7..1c91c5efa51 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -369,6 +369,12 @@ NativeWindowMac::NativeWindowMac( bool resizable = true; options.Get(options::kResizable, &resizable); + bool minimizable = true; + options.Get(options::kMinimizable, &minimizable); + + bool closable = true; + options.Get(options::kClosable, &closable); + // New title bar styles are available in Yosemite or newer std::string titleBarStyle; if (base::mac::IsOSYosemiteOrLater()) @@ -385,8 +391,13 @@ NativeWindowMac::NativeWindowMac( useStandardWindow = false; } - NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask; + NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask; + if (minimizable) { + styleMask |= NSMiniaturizableWindowMask; + } + if (!closable) { + styleMask &= ~NSClosableWindowMask; + } if (!useStandardWindow || transparent() || !has_frame()) { styleMask |= NSTexturedBackgroundWindowMask; } @@ -487,6 +498,11 @@ NativeWindowMac::NativeWindowMac( [window_ setCollectionBehavior:collectionBehavior]; } + // Disable zoom button if window is not resizable + if (!resizable) { + [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; + } + NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; @@ -635,8 +651,10 @@ void NativeWindowMac::SetResizable(bool resizable) { [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:YES]; [window_ setStyleMask:[window_ styleMask] | NSResizableWindowMask]; } else { - [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; + // If we disable the button before changing the styleMask, button is not + // disabled. Looks like a bug in Cocoa (OS X 10.10.5) [window_ setStyleMask:[window_ styleMask] & (~NSResizableWindowMask)]; + [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; } } @@ -644,10 +662,56 @@ bool NativeWindowMac::IsResizable() { return [window_ styleMask] & NSResizableWindowMask; } +void NativeWindowMac::SetMovable(bool movable) { + [window_ setMovable:movable]; +} + +bool NativeWindowMac::IsMovable() { + return [window_ isMovable]; +} + +void NativeWindowMac::SetMinimizable(bool minimizable) { + if (minimizable) { + [window_ setStyleMask:[window_ styleMask] | NSMiniaturizableWindowMask]; + } else { + [window_ setStyleMask:[window_ styleMask] & (~NSMiniaturizableWindowMask)]; + } + FixZoomButton(); +} + +bool NativeWindowMac::IsMinimizable() { + return [window_ styleMask] & NSMiniaturizableWindowMask; +} + +void NativeWindowMac::SetClosable(bool closable) { + if (closable) { + [window_ setStyleMask:[window_ styleMask] | NSClosableWindowMask]; + } else { + [window_ setStyleMask:[window_ styleMask] & (~NSClosableWindowMask)]; + } + FixZoomButton(); +} + +bool NativeWindowMac::IsClosable() { + return [window_ styleMask] & NSClosableWindowMask; +} + void NativeWindowMac::SetAlwaysOnTop(bool top) { [window_ setLevel:(top ? NSFloatingWindowLevel : NSNormalWindowLevel)]; } +void NativeWindowMac::FixZoomButton() { + // If fullscreen has not been disabled via `fullscreen: false` (i.e. when + // collectionBehavior has NSWindowCollectionBehaviorFullScreenPrimary mask), + // zoom button is reset to it's default (enabled) state when window's + // styleMask has been changed. So if the button was disabled, we have to + // disable it again. I think it's a bug in Cocoa. + if ([window_ collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary + && !([window_ styleMask] & NSResizableWindowMask)) { + [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; + } +} + bool NativeWindowMac::IsAlwaysOnTop() { return [window_ level] == NSFloatingWindowLevel; } diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index ad08604235b..25e45ea6f1c 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -126,7 +126,10 @@ NativeWindowViews::NativeWindowViews( menu_bar_alt_pressed_(false), keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), use_content_size_(false), - resizable_(true) { + resizable_(true), + maximizable_(true), + movable_(true), + minimizable_(true) { options.Get(options::kTitle, &title_); options.Get(options::kAutoHideMenuBar, &menu_bar_autohide_); @@ -134,6 +137,8 @@ NativeWindowViews::NativeWindowViews( // On Windows we rely on the CanResize() to indicate whether window can be // resized, and it should be set before window is created. options.Get(options::kResizable, &resizable_); + options.Get(options::kMovable, &movable_); + options.Get(options::kMinimizable, &minimizable_); #endif if (enable_larger_than_screen()) @@ -182,7 +187,9 @@ NativeWindowViews::NativeWindowViews( window_->Init(params); bool fullscreen = false; - options.Get(options::kFullscreen, &fullscreen); + if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) { + maximizable_ = false; + } #if defined(USE_X11) // Start monitoring window states. @@ -236,22 +243,27 @@ NativeWindowViews::NativeWindowViews( last_normal_size_ = gfx::Size(widget_size_); - if (!has_frame()) { - // Set Window style so that we get a minimize and maximize animation when - // frameless. - DWORD frame_style = WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | - WS_CAPTION; - // We should not show a frame for transparent window. - if (transparent()) - frame_style &= ~(WS_THICKFRAME | WS_CAPTION); - ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style); + DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); + style |= WS_THICKFRAME | WS_CAPTION | WS_MINIMIZEBOX; + if (!maximizable_) { + style &= (~WS_MAXIMIZEBOX); + } else { + style |= WS_MAXIMIZEBOX; } if (transparent()) { - // Transparent window on Windows has to have WS_EX_COMPOSITED style. - LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); + DWORD ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); ex_style |= WS_EX_COMPOSITED; ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); + + if (!has_frame()) { + // We should not show a frame for transparent window. + style &= ~(WS_THICKFRAME | WS_CAPTION); + } + } + + if (!transparent() || !has_frame()) { + ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); } #endif @@ -427,10 +439,12 @@ void NativeWindowViews::SetResizable(bool resizable) { // WS_THICKFRAME => Resize handle if (!transparent()) { DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); - if (resizable) - style |= WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME; - else - style = (style & ~(WS_MAXIMIZEBOX | WS_THICKFRAME)) | WS_MINIMIZEBOX; + if (resizable) { + style |= WS_THICKFRAME; + if (maximizable_) style |= WS_MAXIMIZEBOX; + } else { + style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX); + } ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); } #elif defined(USE_X11) @@ -456,6 +470,64 @@ bool NativeWindowViews::IsResizable() { return resizable_; } +void NativeWindowViews::SetMovable(bool movable) { + movable_ = movable; +} + +bool NativeWindowViews::IsMovable() { + return movable_; +} + +void NativeWindowViews::SetMinimizable(bool minimizable) { +#if defined(OS_WIN) + if (!transparent()) { + DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); + if (minimizable) + style |= WS_MINIMIZEBOX; + else + style &= (~WS_MINIMIZEBOX); + ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); + } +#endif + + minimizable_ = minimizable; +} + +bool NativeWindowViews::IsMinimizable() { +#if defined(OS_WIN) + return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MINIMIZEBOX; +#elif defined(USE_X11) + return true; +#endif +} + +void NativeWindowViews::SetClosable(bool closable) { +#if defined(OS_WIN) + HMENU menu = GetSystemMenu(GetAcceleratedWidget(), false); + if (closable) { + EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED); + } else { + EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } +#endif +} + +bool NativeWindowViews::IsClosable() { +#if defined(OS_WIN) + HMENU menu = GetSystemMenu(GetAcceleratedWidget(), false); + MENUITEMINFO info; + memset(&info, 0, sizeof(info)); + info.cbSize = sizeof(info); + info.fMask = MIIM_STATE; + if (!GetMenuItemInfo(menu, SC_CLOSE, false, &info)) { + return false; + } + return !(info.fState & MFS_DISABLED); +#elif defined(USE_X11) + return true; +#endif +} + void NativeWindowViews::SetAlwaysOnTop(bool top) { window_->SetAlwaysOnTop(top); } @@ -717,7 +789,11 @@ bool NativeWindowViews::CanMaximize() const { } bool NativeWindowViews::CanMinimize() const { +#ifdef (OS_WIN) + return minimizable_; +#elif defined(USE_X11) return true; +#endif } base::string16 NativeWindowViews::GetWindowTitle() const { diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 6592242210f..d3117e5b2f6 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -68,6 +68,12 @@ class NativeWindowViews : public NativeWindow, const extensions::SizeConstraints& size_constraints) override; void SetResizable(bool resizable) override; bool IsResizable() override; + void SetMovable(bool movable) override; + bool IsMovable() override; + void SetMinimizable(bool minimizable) override; + bool IsMinimizable() override; + void SetClosable(bool closable) override; + bool IsClosable() override; void SetAlwaysOnTop(bool top) override; bool IsAlwaysOnTop() override; void Center() override; @@ -197,6 +203,9 @@ class NativeWindowViews : public NativeWindow, bool use_content_size_; bool resizable_; + bool maximizable_; + bool movable_; + bool minimizable_; std::string title_; gfx::Size widget_size_; diff --git a/atom/browser/native_window_views_win.cc b/atom/browser/native_window_views_win.cc index 513b33bcb85..53228d5fdf9 100644 --- a/atom/browser/native_window_views_win.cc +++ b/atom/browser/native_window_views_win.cc @@ -89,10 +89,19 @@ bool NativeWindowViews::PreHandleMSG( if (HIWORD(w_param) == THBN_CLICKED) return taskbar_host_.HandleThumbarButtonEvent(LOWORD(w_param)); return false; + case WM_SIZE: // Handle window state change. HandleSizeEvent(w_param, l_param); return false; + + case WM_MOVING: { + if (!movable_) { + ::GetWindowRect(GetAcceleratedWidget(), (LPRECT)l_param); + } + return false; + } + default: return false; } diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 477fe6755fa..e14a63ea928 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -8,22 +8,24 @@ namespace atom { namespace options { -const char kTitle[] = "title"; -const char kIcon[] = "icon"; -const char kFrame[] = "frame"; -const char kShow[] = "show"; -const char kCenter[] = "center"; -const char kX[] = "x"; -const char kY[] = "y"; -const char kWidth[] = "width"; -const char kHeight[] = "height"; -const char kMinWidth[] = "minWidth"; -const char kMinHeight[] = "minHeight"; -const char kMaxWidth[] = "maxWidth"; -const char kMaxHeight[] = "maxHeight"; -const char kResizable[] = "resizable"; -const char kMovable[] = "movable"; -const char kFullscreen[] = "fullscreen"; +const char kTitle[] = "title"; +const char kIcon[] = "icon"; +const char kFrame[] = "frame"; +const char kShow[] = "show"; +const char kCenter[] = "center"; +const char kX[] = "x"; +const char kY[] = "y"; +const char kWidth[] = "width"; +const char kHeight[] = "height"; +const char kMinWidth[] = "minWidth"; +const char kMinHeight[] = "minHeight"; +const char kMaxWidth[] = "maxWidth"; +const char kMaxHeight[] = "maxHeight"; +const char kResizable[] = "resizable"; +const char kMovable[] = "movable"; +const char kMinimizable[] = "minimizable"; +const char kClosable[] = "closable"; +const char kFullscreen[] = "fullscreen"; // Whether the window should show in taskbar. const char kSkipTaskbar[] = "skipTaskbar"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 78de53b825f..f7b68f218b7 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -24,6 +24,8 @@ extern const char kMaxWidth[]; extern const char kMaxHeight[]; extern const char kResizable[]; extern const char kMovable[]; +extern const char kMinimizable[]; +extern const char kClosable[]; extern const char kFullscreen[]; extern const char kSkipTaskbar[]; extern const char kKiosk[]; From c3049e1e991037ec9665d3fffb9bb65d31041c2d Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Tue, 19 Jan 2016 16:07:51 +0100 Subject: [PATCH 002/688] docs updated --- atom/browser/native_window_views.cc | 2 +- docs/api/browser-window.md | 47 ++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 25e45ea6f1c..d50b4cc2c84 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -789,7 +789,7 @@ bool NativeWindowViews::CanMaximize() const { } bool NativeWindowViews::CanMinimize() const { -#ifdef (OS_WIN) +#ifdef(OS_WIN) return minimizable_; #elif defined(USE_X11) return true; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 17e598cb466..820cf3e2b20 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -47,13 +47,18 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `maxWidth` Integer - Window's maximum width. Default is no limit. * `maxHeight` Integer - Window's maximum height. Default is no limit. * `resizable` Boolean - Whether window is resizable. Default is `true`. - * `movable` Boolean - Whether window is movable. This is only implemented - on OS X. Default is `true`. + * `movable` Boolean - Whether window is movable. This is not implemented + on Linux. Default is `true`. + * `minimizable` Boolean - Whether window is minimizable. This is not + implemented on Linux. Default is `true`. + * `closable` Boolean - Whether window is closable. This is not implemented + on Linux. Default is `true`. * `alwaysOnTop` Boolean - Whether the window should always stay on top of other windows. Default is `false`. * `fullscreen` Boolean - Whether the window should show in fullscreen. When - set to `false` the fullscreen button will be hidden or disabled on OS X. - Default is `false`. + explicity set to `false` the fullscreen button will be hidden or disabled + on OS X, or the maximize button will be disabled on Windows. Default is + `false`. * `skipTaskbar` Boolean - Whether to show the window in taskbar. Default is `false`. * `kiosk` Boolean - The kiosk mode. Default is `false`. @@ -523,6 +528,40 @@ Sets whether the window can be manually resized by user. Returns whether the window can be manually resized by user. +### `win.setMovable(movable)` _OS X_ _Windows_ + +* `movable` Boolean + +Sets whether the window can be moved by user. On Linux does nothing. + +### `win.isMovable()` _OS X_ _Windows_ + +Returns whether the window can be moved by user. On Linux always returns +`true`. + +### `win.setMinimizable(minimizable)` _OS X_ _Windows_ + +* `minimizable` Boolean + +Sets whether the window can be manually minimized by user. On Linux does +nothing. + +### `win.isMinimizable()` _OS X_ _Windows_ + +Returns whether the window can be manually minimized by user. On Linux always +returns `true`. + +### `win.setClosable(closable)` _OS X_ _Windows_ + +* `closable` Boolean + +Sets whether the window can be manually closed by user. On Linux does nothing. + +### `win.isClosable()` _OS X_ _Windows_ + +Returns whether the window can be manually closed by user. On Linux always +returns `true`. + ### `win.setAlwaysOnTop(flag)` * `flag` Boolean From 0a79204abb7122d69bb60dbdd3636516b49afe92 Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Tue, 19 Jan 2016 16:43:52 +0100 Subject: [PATCH 003/688] IsMovable to return true on Linux --- atom/browser/native_window_views.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index d50b4cc2c84..9b4c27ead88 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -475,7 +475,11 @@ void NativeWindowViews::SetMovable(bool movable) { } bool NativeWindowViews::IsMovable() { +#if defined(OS_WIN) return movable_; +#elif defined(USE_X11) + return true; +#endif } void NativeWindowViews::SetMinimizable(bool minimizable) { From fd5c249cb8cc1ff8365bb9d5d308eda468ef9a5c Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Tue, 19 Jan 2016 16:57:14 +0100 Subject: [PATCH 004/688] fix for windows --- atom/browser/native_window_views.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 9b4c27ead88..e97a1f3c410 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -793,7 +793,7 @@ bool NativeWindowViews::CanMaximize() const { } bool NativeWindowViews::CanMinimize() const { -#ifdef(OS_WIN) +#if defined(OS_WIN) return minimizable_; #elif defined(USE_X11) return true; From bd2252ea559db6d95a9eae12913ff4d2e8472c78 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 21 Jan 2016 09:40:21 -0800 Subject: [PATCH 005/688] Extend NativeWindow to track touch-based scroll events on OS X In N1, we want to implement the famous "swipe to archive" action on threads in the user's inbox. Chrome exposes `scroll` and `wheel` events, but these aren't sufficient to implement the interaction because the element needs to "snap" when the user lifts their fingers from the trackpad, not when they / we stop receiving `wheel` / `scroll` events. These events may stop before the user lifts their fingers, or continue after the user has lifted their fingers if they had enough momentum for the gesture to continue. This exposes BrowserWindow `scroll-touch-down` and `scroll-touch-up`, which fire immeditaely when the user touches two fingers to the trackpad, and again when the user lifts their fingers. Combined with the existing wheel event should allow for "swipe-to-archive" and other similar interactions. Note: This is only implemented on Mac OS X and the events don't fire unless you're using a trackpad! Related: #1486, #2683, https://github.com/nylas/N1/issues/541 --- atom/browser/api/atom_api_window.cc | 8 ++++++++ atom/browser/api/atom_api_window.h | 2 ++ atom/browser/native_window.cc | 10 ++++++++++ atom/browser/native_window.h | 2 ++ atom/browser/native_window_mac.mm | 19 +++++++++++++++++++ atom/browser/native_window_observer.h | 2 ++ 6 files changed, 43 insertions(+) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 09d88edb9b7..ef38490d8f7 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -227,6 +227,14 @@ void Window::OnWindowLeaveFullScreen() { Emit("leave-full-screen"); } +void Window::OnWindowScrollTouchUp() { + Emit("scroll-touch-up"); +} + +void Window::OnWindowScrollTouchDown() { + Emit("scroll-touch-down"); +} + void Window::OnWindowEnterHtmlFullScreen() { Emit("enter-html-full-screen"); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index d8e25965d89..12eec04680f 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -65,6 +65,8 @@ class Window : public mate::TrackableObject, void OnWindowResize() override; void OnWindowMove() override; void OnWindowMoved() override; + void OnWindowScrollTouchUp() override; + void OnWindowScrollTouchDown() override; void OnWindowEnterFullScreen() override; void OnWindowLeaveFullScreen() override; void OnWindowEnterHtmlFullScreen() override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 4df4b491696..89354381bea 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -442,6 +442,16 @@ void NativeWindow::NotifyWindowEnterFullScreen() { OnWindowEnterFullScreen()); } +void NativeWindow::NotifyWindowScrollTouchUp() { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnWindowScrollTouchUp()); +} + +void NativeWindow::NotifyWindowScrollTouchDown() { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnWindowScrollTouchDown()); +} + void NativeWindow::NotifyWindowLeaveFullScreen() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowLeaveFullScreen()); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 0ccf3dfbc2e..f1dac26650c 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -205,6 +205,8 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowMove(); void NotifyWindowResize(); void NotifyWindowMoved(); + void NotifyWindowScrollTouchUp(); + void NotifyWindowScrollTouchDown(); void NotifyWindowEnterFullScreen(); void NotifyWindowLeaveFullScreen(); void NotifyWindowEnterHtmlFullScreen(); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index f128f3b2cb7..198a78e3f59 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -490,6 +490,25 @@ NativeWindowMac::NativeWindowMac( NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + BOOL __block down = NO; + [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask handler:^NSEvent * _Nullable(NSEvent * event) { + if (![window_ isKeyWindow]) + return event; + + if (!web_contents) + return event; + + if (!down && (([event phase] == NSEventPhaseMayBegin) || ([event phase] == NSEventPhaseBegan))) { + this->NotifyWindowScrollTouchDown(); + down = YES; + } + if (down && (([event phase] == NSEventPhaseEnded) || ([event phase] == NSEventPhaseCancelled))) { + this->NotifyWindowScrollTouchUp(); + down = NO; + } + return event; + }]; + InstallView(); } diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index ce2d41c6fad..b7ba9d756f1 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -50,6 +50,8 @@ class NativeWindowObserver { virtual void OnWindowResize() {} virtual void OnWindowMove() {} virtual void OnWindowMoved() {} + virtual void OnWindowScrollTouchUp() {} + virtual void OnWindowScrollTouchDown() {} virtual void OnWindowEnterFullScreen() {} virtual void OnWindowLeaveFullScreen() {} virtual void OnWindowEnterHtmlFullScreen() {} From 0e2323c9c8753e6eb61e10b90a5a06357f2ec749 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 21 Jan 2016 23:52:23 +0530 Subject: [PATCH 006/688] browser: add webContents.debugger api --- atom/browser/api/atom_api_debugger.cc | 152 ++++++++++++++++++++++ atom/browser/api/atom_api_debugger.h | 81 ++++++++++++ atom/browser/api/atom_api_web_contents.cc | 12 +- atom/browser/api/atom_api_web_contents.h | 2 + docs/api/web-contents.md | 63 +++++++++ filenames.gypi | 2 + 6 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 atom/browser/api/atom_api_debugger.cc create mode 100644 atom/browser/api/atom_api_debugger.h diff --git a/atom/browser/api/atom_api_debugger.cc b/atom/browser/api/atom_api_debugger.cc new file mode 100644 index 00000000000..39fb5782ff0 --- /dev/null +++ b/atom/browser/api/atom_api_debugger.cc @@ -0,0 +1,152 @@ +// Copyright (c) 2015 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_debugger.h" + +#include + +#include "atom/common/native_mate_converters/callback.h" +#include "atom/common/native_mate_converters/value_converter.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "content/public/browser/devtools_agent_host.h" +#include "content/public/browser/web_contents.h" +#include "native_mate/object_template_builder.h" + +using content::DevToolsAgentHost; + +namespace atom { + +namespace api { + +Debugger::Debugger(content::WebContents* web_contents) + : web_contents_(web_contents), + previous_request_id_(0) { +} + +Debugger::~Debugger() { +} + +void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host, + bool replaced_with_another_client) { + std::string detach_reason = "target closed"; + if (replaced_with_another_client) + detach_reason = "replaced with devtools"; + if (!detach_callback_.is_null()) + detach_callback_.Run(detach_reason); +} + +void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host, + const std::string& message) { + DCHECK(agent_host == agent_host_.get()); + + scoped_ptr parsed_message(base::JSONReader::Read(message)); + if (!parsed_message->IsType(base::Value::TYPE_DICTIONARY)) + return; + + base::DictionaryValue* dict = + static_cast(parsed_message.get()); + int id; + if (!dict->GetInteger("id", &id)) { + std::string method; + if (!dict->GetString("method", &method)) + return; + base::DictionaryValue* params = nullptr; + dict->GetDictionary("params", ¶ms); + if (!response_callback_.is_null()) + response_callback_.Run(method, *params); + } else { + auto send_command_callback = pending_requests_[id]; + pending_requests_.erase(id); + if (send_command_callback.is_null()) + return; + base::DictionaryValue* result = nullptr; + dict->GetDictionary("result", &result); + send_command_callback.Run(*result); + } +} + +void Debugger::Attach(mate::Arguments* args) { + std::string protocol_version; + args->GetNext(&protocol_version); + + if (!protocol_version.empty() && + !DevToolsAgentHost::IsSupportedProtocolVersion(protocol_version)) { + args->ThrowError("Requested protocol version is not supported"); + return; + } + agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents_); + if (!agent_host_.get()) { + args->ThrowError("No target available"); + return; + } + if (agent_host_->IsAttached()) { + args->ThrowError("Another debugger is already attached to this target"); + return; + } + + agent_host_->AttachClient(this); +} + +void Debugger::Detach() { + agent_host_->DetachClient(); + agent_host_ = nullptr; +} + +void Debugger::SendCommand(mate::Arguments* args) { + if (!agent_host_.get()) + args->ThrowError("Debugger is not attached to a target"); + + std::string method; + if (!args->GetNext(&method)) { + args->ThrowError(); + return; + } + base::DictionaryValue command_params; + args->GetNext(&command_params); + SendCommandCallback callback; + args->GetNext(&callback); + + base::DictionaryValue request; + int request_id = ++previous_request_id_; + pending_requests_[request_id] = callback; + request.SetInteger("id", request_id); + request.SetString("method", method); + if (!command_params.empty()) + request.Set("params", command_params.DeepCopy()); + + std::string json_args; + base::JSONWriter::Write(request, &json_args); + agent_host_->DispatchProtocolMessage(json_args); +} + +void Debugger::OnDetach(const DetachCallback& callback) { + detach_callback_ = callback; +} + +void Debugger::OnEvent(const ResponseCallback& callback) { + response_callback_ = callback; +} + +// static +mate::Handle Debugger::Create( + v8::Isolate* isolate, + content::WebContents* web_contents) { + return mate::CreateHandle(isolate, new Debugger(web_contents)); +} + +// static +void Debugger::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("attach", &Debugger::Attach) + .SetMethod("detach", &Debugger::Detach) + .SetMethod("sendCommand", &Debugger::SendCommand) + .SetMethod("onDetach", &Debugger::OnDetach) + .SetMethod("onEvent", &Debugger::OnEvent); +} + +} // namespace api + +} // namespace atom diff --git a/atom/browser/api/atom_api_debugger.h b/atom/browser/api/atom_api_debugger.h new file mode 100644 index 00000000000..51b5749d2b1 --- /dev/null +++ b/atom/browser/api/atom_api_debugger.h @@ -0,0 +1,81 @@ +// Copyright (c) 2015 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_DEBUGGER_H_ +#define ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_ + +#include +#include + +#include "atom/browser/api/trackable_object.h" +#include "base/callback.h" +#include "base/values.h" +#include "content/public/browser/devtools_agent_host_client.h" +#include "native_mate/handle.h" + +namespace content { +class DevToolsAgentHost; +class WebContents; +} + +namespace mate { +class Arguments; +} + +namespace atom { + +namespace api { + +class Debugger: public mate::TrackableObject, + public content::DevToolsAgentHostClient { + public: + using ResponseCallback = + base::Callback; + using SendCommandCallback = + base::Callback; + using DetachCallback = base::Callback; + + static mate::Handle Create( + v8::Isolate* isolate, content::WebContents* web_contents); + + // mate::TrackableObject: + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + + protected: + explicit Debugger(content::WebContents* web_contents); + ~Debugger(); + + // content::DevToolsAgentHostClient: + void AgentHostClosed(content::DevToolsAgentHost* agent_host, + bool replaced_with_another_client) override; + void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host, + const std::string& message) override; + + private: + using PendingRequestMap = std::map; + + void Attach(mate::Arguments* args); + void Detach(); + void SendCommand(mate::Arguments* args); + void OnDetach(const DetachCallback& callback); + void OnEvent(const ResponseCallback& callback); + + content::WebContents* web_contents_; // Weak Reference. + scoped_refptr agent_host_; + + DetachCallback detach_callback_; + ResponseCallback response_callback_; + + PendingRequestMap pending_requests_; + int previous_request_id_; + + DISALLOW_COPY_AND_ASSIGN(Debugger); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_ diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 0173abf4eef..2b14bdc60d8 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -7,6 +7,7 @@ #include #include +#include "atom/browser/api/atom_api_debugger.h" #include "atom/browser/api/atom_api_session.h" #include "atom/browser/api/atom_api_window.h" #include "atom/browser/atom_browser_client.h" @@ -1076,6 +1077,14 @@ v8::Local WebContents::DevToolsWebContents(v8::Isolate* isolate) { return v8::Local::New(isolate, devtools_web_contents_); } +v8::Local WebContents::Debugger(v8::Isolate* isolate) { + if (debugger_.IsEmpty()) { + auto handle = atom::api::Debugger::Create(isolate, web_contents()); + debugger_.Reset(isolate, handle.ToV8()); + } + return v8::Local::New(isolate, debugger_); +} + // static void WebContents::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { @@ -1144,7 +1153,8 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) .SetProperty("session", &WebContents::Session) - .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents); + .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents) + .SetProperty("debugger", &WebContents::Debugger); } AtomBrowserContext* WebContents::GetBrowserContext() const { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index bcef57b9a4a..10ac7a4f769 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -142,6 +142,7 @@ class WebContents : public mate::TrackableObject, // Properties. v8::Local Session(v8::Isolate* isolate); v8::Local DevToolsWebContents(v8::Isolate* isolate); + v8::Local Debugger(v8::Isolate* isolate); // mate::TrackableObject: static void BuildPrototype(v8::Isolate* isolate, @@ -265,6 +266,7 @@ class WebContents : public mate::TrackableObject, v8::Global session_; v8::Global devtools_web_contents_; + v8::Global debugger_; scoped_ptr guest_delegate_; diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 48658a29459..c64f1886aba 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -833,3 +833,66 @@ Get the `WebContents` of DevTools for this `WebContents`. **Note:** Users should never store this object because it may become `null` when the DevTools has been closed. + +### `webContents.debugger` + +Debugger API serves as an alternate transport for remote debugging protocol. + +```javascript +try { + win.webContents.debugger.attach("1.1"); +} catch(err) { + console.log("Debugger attach failed : ", err); +}; + +win.webContents.debugger.onDetach(function(reason) { + console.log("Debugger detached due to : ", reason); +}); + +win.webContents.debugger.onEvent(function(method, params) { + if (method == "Network.requestWillBeSent") { + if (params.request.url == "https://www.github.com") + win.webContents.debugger.detach(); + } +}) + +win.webContents.debugger.sendCommand("Network.enable"); +``` + +#### `webContents.debugger.attach([protocolVersion])` + +* `protocolVersion` String - Required debugging protocol version. + +Attaches the debugger to the `webContents`. + +#### `webContents.debugger.detach()` + +Detaches the debugger from the `webContents`. + +#### `webContents.debugger.sendCommand(method[, commandParams, callback])` + +* `method` String - Method name, should be one of the methods defined by the + remote debugging protocol. +* `commandParams` Object - JSON object with request parameters. +* `callback` Function - Response + * `result` Object - Response defined by the 'returns' attribute of + the command description in the remote debugging protocol. + +Send given command to the debugging target. + +#### `webContents.debugger.onDetach(callback)` + +* `callback` Function + * `reason` String - Reason for detaching debugger. + +`callback` is fired when debugging session is terminated. This happens either when +`webContents` is closed or devtools is invoked for the attached `webContents`. + +#### `webContents.debugger.onEvent(callback)` + +* `callback` Function + * `method` String - Method name. + * `params` Object - Event parameters defined by the 'parameters' + attribute in the remote debugging protocol. + +`callback` is fired whenever debugging target issues instrumentation event. diff --git a/filenames.gypi b/filenames.gypi index 61aa3d43d4a..4aa47fc3580 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -83,6 +83,8 @@ 'atom/browser/api/atom_api_content_tracing.cc', 'atom/browser/api/atom_api_cookies.cc', 'atom/browser/api/atom_api_cookies.h', + 'atom/browser/api/atom_api_debugger.cc', + 'atom/browser/api/atom_api_debugger.h', 'atom/browser/api/atom_api_desktop_capturer.cc', 'atom/browser/api/atom_api_desktop_capturer.h', 'atom/browser/api/atom_api_download_item.cc', From 859d9763e92d26816e85441298834cbea72639d4 Mon Sep 17 00:00:00 2001 From: Rose Robertson Date: Thu, 21 Jan 2016 14:31:18 -0800 Subject: [PATCH 007/688] :memo: Use correct shortcut for 'Hide Others' menu item example As per https://support.apple.com/en-gb/HT201236, the correct keyboard shortcut for hiding all but the current window is Command-Option(Alt)-H. --- docs/api/menu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index 38069140ad3..49c4ff04fbe 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -169,7 +169,7 @@ if (process.platform == 'darwin') { }, { label: 'Hide Others', - accelerator: 'Command+Shift+H', + accelerator: 'Command+Alt+H', role: 'hideothers' }, { From a3b6f6977219fe7b98a9e383186486a772ba6afd Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Tue, 22 Dec 2015 12:20:50 -0700 Subject: [PATCH 008/688] Log ASAR file access to build ordering hint file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a work in progress—need to make this behavior optional via a new flag. --- atom/common/lib/asar.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/atom/common/lib/asar.js b/atom/common/lib/asar.js index 7033a956420..f45e62b176d 100644 --- a/atom/common/lib/asar.js +++ b/atom/common/lib/asar.js @@ -203,7 +203,24 @@ // Override fs APIs. exports.wrapFsWithAsar = function(fs) { - var exists, existsSync, internalModuleReadFile, internalModuleStat, lstat, lstatSync, mkdir, mkdirSync, readFile, readFileSync, readdir, readdirSync, realpath, realpathSync, stat, statSync, statSyncNoException; + var exists, existsSync, internalModuleReadFile, internalModuleStat, lstat, lstatSync, mkdir, mkdirSync, readFile, readFileSync, readdir, readdirSync, realpath, realpathSync, stat, statSync, statSyncNoException, logFDs, logASARAccess; + + logFDs = {}; + logASARAccess = function(asarPath, filePath, offset) { + if (!process.env.ELECTRON_LOG_ASAR_READS) { + return; + } + if (!logFDs[asarPath]) { + var logFilename, logPath; + const path = require('path'); + logFilename = path.basename(asarPath, '.asar') + '-access-log.txt'; + logPath = path.join(require('os').tmpdir(), logFilename); + logFDs[asarPath] = fs.openSync(logPath, 'a'); + console.log('Logging ' + asarPath + ' access to ' + logPath); + } + fs.writeSync(logFDs[asarPath], offset + ': ' + filePath + '\n'); + }; + lstatSync = fs.lstatSync; fs.lstatSync = function(p) { var archive, asarPath, filePath, isAsar, ref, stats; @@ -395,6 +412,7 @@ if (!(fd >= 0)) { return notFoundError(asarPath, filePath, callback); } + logASARAccess(asarPath, filePath, info.offset); return fs.read(fd, buffer, 0, info.size, info.offset, function(error) { return callback(error, encoding ? buffer.toString(encoding) : buffer); }); @@ -444,6 +462,7 @@ if (!(fd >= 0)) { notFoundError(asarPath, filePath); } + logASARAccess(asarPath, filePath, info.offset); fs.readSync(fd, buffer, 0, info.size, info.offset); if (encoding) { return buffer.toString(encoding); @@ -516,6 +535,7 @@ if (!(fd >= 0)) { return void 0; } + logASARAccess(asarPath, filePath, info.offset); fs.readSync(fd, buffer, 0, info.size, info.offset); return buffer.toString('utf8'); }; From b9d62d2cab4f28b4451a3580a6728b6ecc20d4e0 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Tue, 22 Dec 2015 19:05:14 -0500 Subject: [PATCH 009/688] Turn on logging via a command line env var --- docs/api/environment-variables.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/api/environment-variables.md b/docs/api/environment-variables.md index 6b000aaa108..0d6e68a76cb 100644 --- a/docs/api/environment-variables.md +++ b/docs/api/environment-variables.md @@ -25,6 +25,12 @@ Starts the process as a normal Node.js process. Prints Chrome's internal logging to console. +## `ELECTRON_LOG_ASAR_READS` + +When Electron reads from an ASAR file, log the the read offset and file path +to the system `tmpdir`. Th resulting file can be provided to the ASAR module +to optimize file ordering. + ## `ELECTRON_ENABLE_STACK_DUMPING` When Electron crashed, prints the stack trace to console. From ed34e33fbfd3b1ad45f9c648a69717eb9eb2dfe1 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 21 Jan 2016 10:57:50 -0800 Subject: [PATCH 010/688] Fix typos in environment-variables.md --- docs/api/environment-variables.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/environment-variables.md b/docs/api/environment-variables.md index 0d6e68a76cb..3483c19d643 100644 --- a/docs/api/environment-variables.md +++ b/docs/api/environment-variables.md @@ -27,8 +27,8 @@ Prints Chrome's internal logging to console. ## `ELECTRON_LOG_ASAR_READS` -When Electron reads from an ASAR file, log the the read offset and file path -to the system `tmpdir`. Th resulting file can be provided to the ASAR module +When Electron reads from an ASAR file, log the read offset and file path to +the system `tmpdir`. The resulting file can be provided to the ASAR module to optimize file ordering. ## `ELECTRON_ENABLE_STACK_DUMPING` From 980bc7bf3247ae8b0170989990673444fd154b5f Mon Sep 17 00:00:00 2001 From: Jessica Lord Date: Thu, 21 Jan 2016 15:48:06 -0700 Subject: [PATCH 011/688] Use Alt in accelerator --- atom/browser/default_app/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 2c4fb1d2eea..895e3df6366 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -198,7 +198,7 @@ app.once('ready', function() { }, { label: 'Hide Others', - accelerator: 'Command+Shift+H', + accelerator: 'Command+Alt+H', role: 'hideothers' }, { From a230a89de4f732f7595951194ac975dc183ea25a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 21 Jan 2016 17:04:38 -0700 Subject: [PATCH 012/688] Bump v0.36.5 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index 0960572dac2..074e95360b6 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.36.4', + 'version%': '0.36.5', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index f1de499afed..7d5571189e5 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.36.4 + 0.36.5 CFBundleShortVersionString - 0.36.4 + 0.36.5 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 5763cb7ba3c..2a80d5ff3a9 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,36,4,0 - PRODUCTVERSION 0,36,4,0 + FILEVERSION 0,36,5,0 + PRODUCTVERSION 0,36,5,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.36.4" + VALUE "FileVersion", "0.36.5" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.36.4" + VALUE "ProductVersion", "0.36.5" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 838eca35dbc..7399b847653 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 36 -#define ATOM_PATCH_VERSION 4 +#define ATOM_PATCH_VERSION 5 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index 5d897230851..a12107252da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.36.4", + "version": "0.36.5", "devDependencies": { "asar": "^0.9.0", "eslint": "^1.10.3", From 63ae73b2816ca3c3ab2ae8d8b674d15f5b366eb8 Mon Sep 17 00:00:00 2001 From: ragingwind Date: Fri, 22 Jan 2016 09:04:59 +0900 Subject: [PATCH 013/688] Using strict comparation --- spec/static/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/static/main.js b/spec/static/main.js index b295ba18552..c49b2318de6 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -93,7 +93,7 @@ app.on('ready', function() { message: 'Window is not responsing', detail: 'The window is not responding. Would you like to force close it or just keep waiting?' }); - if (chosen == 0) window.destroy(); + if (chosen === 0) window.destroy(); }); // For session's download test, listen 'will-download' event in browser, and From d492ff45d5eb03a9eaf4826661933a275fdb9db3 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 21 Jan 2016 16:31:09 -0800 Subject: [PATCH 014/688] Rename up/down => begin/end --- atom/browser/api/atom_api_window.cc | 8 ++++---- atom/browser/api/atom_api_window.h | 4 ++-- atom/browser/native_window.cc | 8 ++++---- atom/browser/native_window.h | 4 ++-- atom/browser/native_window_observer.h | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index ef38490d8f7..fc6c4eaffb7 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -227,12 +227,12 @@ void Window::OnWindowLeaveFullScreen() { Emit("leave-full-screen"); } -void Window::OnWindowScrollTouchUp() { - Emit("scroll-touch-up"); +void Window::OnWindowScrollTouchBegin() { + Emit("scroll-touch-begin"); } -void Window::OnWindowScrollTouchDown() { - Emit("scroll-touch-down"); +void Window::OnWindowScrollTouchEnd() { + Emit("scroll-touch-end"); } void Window::OnWindowEnterHtmlFullScreen() { diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 12eec04680f..ccbb9ab5f58 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -65,8 +65,8 @@ class Window : public mate::TrackableObject, void OnWindowResize() override; void OnWindowMove() override; void OnWindowMoved() override; - void OnWindowScrollTouchUp() override; - void OnWindowScrollTouchDown() override; + void OnWindowScrollTouchBegin() override; + void OnWindowScrollTouchEnd() override; void OnWindowEnterFullScreen() override; void OnWindowLeaveFullScreen() override; void OnWindowEnterHtmlFullScreen() override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 89354381bea..21b32797e8a 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -442,14 +442,14 @@ void NativeWindow::NotifyWindowEnterFullScreen() { OnWindowEnterFullScreen()); } -void NativeWindow::NotifyWindowScrollTouchUp() { +void NativeWindow::NotifyWindowScrollTouchBegin() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, - OnWindowScrollTouchUp()); + OnWindowScrollTouchBegin()); } -void NativeWindow::NotifyWindowScrollTouchDown() { +void NativeWindow::NotifyWindowScrollTouchEnd() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, - OnWindowScrollTouchDown()); + OnWindowScrollTouchEnd()); } void NativeWindow::NotifyWindowLeaveFullScreen() { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index f1dac26650c..418f0f35791 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -205,8 +205,8 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowMove(); void NotifyWindowResize(); void NotifyWindowMoved(); - void NotifyWindowScrollTouchUp(); - void NotifyWindowScrollTouchDown(); + void NotifyWindowScrollTouchBegin(); + void NotifyWindowScrollTouchEnd(); void NotifyWindowEnterFullScreen(); void NotifyWindowLeaveFullScreen(); void NotifyWindowEnterHtmlFullScreen(); diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index b7ba9d756f1..4af181085a0 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -50,8 +50,8 @@ class NativeWindowObserver { virtual void OnWindowResize() {} virtual void OnWindowMove() {} virtual void OnWindowMoved() {} - virtual void OnWindowScrollTouchUp() {} - virtual void OnWindowScrollTouchDown() {} + virtual void OnWindowScrollTouchBegin() {} + virtual void OnWindowScrollTouchEnd() {} virtual void OnWindowEnterFullScreen() {} virtual void OnWindowLeaveFullScreen() {} virtual void OnWindowEnterHtmlFullScreen() {} From e96e674201c7dfccf7f39f8b22711f3a803de7e9 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 21 Jan 2016 16:31:31 -0800 Subject: [PATCH 015/688] Properly clean up NSEvent monitor --- atom/browser/native_window_mac.h | 1 + atom/browser/native_window_mac.mm | 33 +++++++++++++++++-------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index ef3ccb15021..927e971d9bb 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -110,6 +110,7 @@ class NativeWindowMac : public NativeWindow { base::scoped_nsobject window_; base::scoped_nsobject window_delegate_; + base::scoped_nsobject event_monitor_; // The view that will fill the whole frameless window. base::scoped_nsobject content_view_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 198a78e3f59..88476eafbf5 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -491,28 +491,31 @@ NativeWindowMac::NativeWindowMac( [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; BOOL __block down = NO; - [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask handler:^NSEvent * _Nullable(NSEvent * event) { - if (![window_ isKeyWindow]) - return event; + event_monitor_.reset([[NSEvent + addLocalMonitorForEventsMatchingMask:NSScrollWheelMask + handler:^NSEvent * _Nullable(NSEvent * event) { + if (![window_ isKeyWindow]) + return event; - if (!web_contents) - return event; + if (!web_contents) + return event; - if (!down && (([event phase] == NSEventPhaseMayBegin) || ([event phase] == NSEventPhaseBegan))) { - this->NotifyWindowScrollTouchDown(); - down = YES; - } - if (down && (([event phase] == NSEventPhaseEnded) || ([event phase] == NSEventPhaseCancelled))) { - this->NotifyWindowScrollTouchUp(); - down = NO; - } - return event; - }]; + if (!down && (([event phase] == NSEventPhaseMayBegin) || ([event phase] == NSEventPhaseBegan))) { + this->NotifyWindowScrollTouchBegin(); + down = YES; + } + if (down && (([event phase] == NSEventPhaseEnded) || ([event phase] == NSEventPhaseCancelled))) { + this->NotifyWindowScrollTouchEnd(); + down = NO; + } + return event; + }] retain]); InstallView(); } NativeWindowMac::~NativeWindowMac() { + [NSEvent removeMonitor: event_monitor_.get()]; Observe(nullptr); } From d186dceb4bf6af7917e8bd5a076859d3ab34c901 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 21 Jan 2016 16:36:48 -0800 Subject: [PATCH 016/688] Add correct window check for wheel events. See description Tested that with two windows, events are fired on the correct BrowserWindow instance and not both, and that scrolling a window which is in the background works properly. --- atom/browser/native_window_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 88476eafbf5..133a0e6becc 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -494,7 +494,7 @@ NativeWindowMac::NativeWindowMac( event_monitor_.reset([[NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask handler:^NSEvent * _Nullable(NSEvent * event) { - if (![window_ isKeyWindow]) + if ([[event window] windowNumber] != [window_ windowNumber]) return event; if (!web_contents) From 072ab0ddeac8b975350d3467807e413fadbdc4fc Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Fri, 22 Jan 2016 03:18:04 +0100 Subject: [PATCH 017/688] specify positioning item for popup menus --- atom/browser/api/atom_api_menu.h | 3 ++- atom/browser/api/atom_api_menu_mac.h | 2 +- atom/browser/api/atom_api_menu_mac.mm | 10 ++++++++-- atom/browser/api/atom_api_menu_views.cc | 2 +- atom/browser/api/atom_api_menu_views.h | 2 +- atom/browser/api/lib/menu.js | 4 ++-- docs/api/menu.md | 7 +++++-- 7 files changed, 20 insertions(+), 10 deletions(-) diff --git a/atom/browser/api/atom_api_menu.h b/atom/browser/api/atom_api_menu.h index 17bb9073a71..d3452628100 100644 --- a/atom/browser/api/atom_api_menu.h +++ b/atom/browser/api/atom_api_menu.h @@ -52,7 +52,8 @@ class Menu : public mate::TrackableObject, void MenuWillShow(ui::SimpleMenuModel* source) override; virtual void Popup(Window* window) = 0; - virtual void PopupAt(Window* window, int x, int y) = 0; + virtual void PopupAt(Window* window, int x, int y, + int positioningItem = 0) = 0; scoped_ptr model_; Menu* parent_; diff --git a/atom/browser/api/atom_api_menu_mac.h b/atom/browser/api/atom_api_menu_mac.h index 5a086776a63..e71198315b6 100644 --- a/atom/browser/api/atom_api_menu_mac.h +++ b/atom/browser/api/atom_api_menu_mac.h @@ -20,7 +20,7 @@ class MenuMac : public Menu { MenuMac(); void Popup(Window* window) override; - void PopupAt(Window* window, int x, int y) override; + void PopupAt(Window* window, int x, int y, int positioningItem = 0) override; base::scoped_nsobject menu_controller_; diff --git a/atom/browser/api/atom_api_menu_mac.mm b/atom/browser/api/atom_api_menu_mac.mm index 071753218d6..7e505ccd9d3 100644 --- a/atom/browser/api/atom_api_menu_mac.mm +++ b/atom/browser/api/atom_api_menu_mac.mm @@ -50,7 +50,7 @@ void MenuMac::Popup(Window* window) { forView:web_contents->GetContentNativeView()]; } -void MenuMac::PopupAt(Window* window, int x, int y) { +void MenuMac::PopupAt(Window* window, int x, int y, int positioningItem) { NativeWindow* native_window = window->window(); if (!native_window) return; @@ -64,7 +64,13 @@ void MenuMac::PopupAt(Window* window, int x, int y) { NSView* view = web_contents->GetContentNativeView(); // Show the menu. - [menu popUpMenuPositioningItem:[menu itemAtIndex:0] + if (positioningItem >= [menu numberOfItems]) { + positioningItem = [menu numberOfItems] - 1; + } + if (positioningItem < 0) { + positioningItem = 0; + } + [menu popUpMenuPositioningItem:[menu itemAtIndex:positioningItem] atLocation:NSMakePoint(x, [view frame].size.height - y) inView:view]; } diff --git a/atom/browser/api/atom_api_menu_views.cc b/atom/browser/api/atom_api_menu_views.cc index 45904dd8c03..67b55d5e988 100644 --- a/atom/browser/api/atom_api_menu_views.cc +++ b/atom/browser/api/atom_api_menu_views.cc @@ -20,7 +20,7 @@ void MenuViews::Popup(Window* window) { PopupAtPoint(window, gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); } -void MenuViews::PopupAt(Window* window, int x, int y) { +void MenuViews::PopupAt(Window* window, int x, int y, int positioningItem) { NativeWindow* native_window = static_cast(window->window()); if (!native_window) return; diff --git a/atom/browser/api/atom_api_menu_views.h b/atom/browser/api/atom_api_menu_views.h index de0d2e8b014..9e306b4e72b 100644 --- a/atom/browser/api/atom_api_menu_views.h +++ b/atom/browser/api/atom_api_menu_views.h @@ -18,7 +18,7 @@ class MenuViews : public Menu { protected: void Popup(Window* window) override; - void PopupAt(Window* window, int x, int y) override; + void PopupAt(Window* window, int x, int y, int positioningItem = 0) override; private: void PopupAtPoint(Window* window, const gfx::Point& point); diff --git a/atom/browser/api/lib/menu.js b/atom/browser/api/lib/menu.js index 69ad4fec051..d6b276ddc1e 100644 --- a/atom/browser/api/lib/menu.js +++ b/atom/browser/api/lib/menu.js @@ -158,7 +158,7 @@ Menu.prototype._init = function() { }; }; -Menu.prototype.popup = function(window, x, y) { +Menu.prototype.popup = function(window, x, y, positioningItem) { if ((window != null ? window.constructor : void 0) !== BrowserWindow) { // Shift. y = x; @@ -166,7 +166,7 @@ Menu.prototype.popup = function(window, x, y) { window = BrowserWindow.getFocusedWindow(); } if ((x != null) && (y != null)) { - return this._popupAt(window, x, y); + return this._popupAt(window, x, y, positioningItem || 0); } else { return this._popup(window); } diff --git a/docs/api/menu.md b/docs/api/menu.md index 38069140ad3..f0cfaccd7f1 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -237,15 +237,18 @@ Generally, the `template` is just an array of `options` for constructing a You can also attach other fields to the element of the `template` and they will become properties of the constructed menu items. -### `Menu.popup([browserWindow, x, y])` +### `Menu.popup([browserWindow, x, y, positioningItem])` * `browserWindow` BrowserWindow (optional) * `x` Number (optional) * `y` Number (**required** if `x` is used) +* `positioningItem` Number (optional) _OS X_ Pops up this menu as a context menu in the `browserWindow`. You can optionally provide a `x,y` coordinate to place the menu at, otherwise it -will be placed at the current mouse cursor position. +will be placed at the current mouse cursor position. `positioningItem` is the +index of the menu item to be positioned under the mouse cursor at the specified +coordinates (only supported on OS X). ### `Menu.append(menuItem)` From df5bad3f89a2946691416121b47af3b8cfae190f Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 22 Jan 2016 10:27:25 +0530 Subject: [PATCH 018/688] fix api and docs --- atom/browser/api/atom_api_debugger.cc | 23 +++++++------------- atom/browser/api/atom_api_debugger.h | 10 +-------- atom/browser/api/lib/web-contents.js | 3 +++ docs/api/web-contents.md | 30 ++++++++++++++------------- 4 files changed, 27 insertions(+), 39 deletions(-) diff --git a/atom/browser/api/atom_api_debugger.cc b/atom/browser/api/atom_api_debugger.cc index 39fb5782ff0..76ea46df9f3 100644 --- a/atom/browser/api/atom_api_debugger.cc +++ b/atom/browser/api/atom_api_debugger.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2015 GitHub, Inc. +// Copyright (c) 2016 GitHub, Inc. // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. @@ -33,8 +33,7 @@ void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host, std::string detach_reason = "target closed"; if (replaced_with_another_client) detach_reason = "replaced with devtools"; - if (!detach_callback_.is_null()) - detach_callback_.Run(detach_reason); + Emit("detach", detach_reason); } void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host, @@ -54,8 +53,7 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host, return; base::DictionaryValue* params = nullptr; dict->GetDictionary("params", ¶ms); - if (!response_callback_.is_null()) - response_callback_.Run(method, *params); + Emit("message", method, *params); } else { auto send_command_callback = pending_requests_[id]; pending_requests_.erase(id); @@ -90,7 +88,10 @@ void Debugger::Attach(mate::Arguments* args) { } void Debugger::Detach() { + if (!agent_host_.get()) + return; agent_host_->DetachClient(); + AgentHostClosed(agent_host_.get(), false); agent_host_ = nullptr; } @@ -121,14 +122,6 @@ void Debugger::SendCommand(mate::Arguments* args) { agent_host_->DispatchProtocolMessage(json_args); } -void Debugger::OnDetach(const DetachCallback& callback) { - detach_callback_ = callback; -} - -void Debugger::OnEvent(const ResponseCallback& callback) { - response_callback_ = callback; -} - // static mate::Handle Debugger::Create( v8::Isolate* isolate, @@ -142,9 +135,7 @@ void Debugger::BuildPrototype(v8::Isolate* isolate, mate::ObjectTemplateBuilder(isolate, prototype) .SetMethod("attach", &Debugger::Attach) .SetMethod("detach", &Debugger::Detach) - .SetMethod("sendCommand", &Debugger::SendCommand) - .SetMethod("onDetach", &Debugger::OnDetach) - .SetMethod("onEvent", &Debugger::OnEvent); + .SetMethod("sendCommand", &Debugger::SendCommand); } } // namespace api diff --git a/atom/browser/api/atom_api_debugger.h b/atom/browser/api/atom_api_debugger.h index 51b5749d2b1..894c2bc319c 100644 --- a/atom/browser/api/atom_api_debugger.h +++ b/atom/browser/api/atom_api_debugger.h @@ -1,4 +1,4 @@ -// Copyright (c) 2015 GitHub, Inc. +// Copyright (c) 2016 GitHub, Inc. // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. @@ -30,11 +30,8 @@ namespace api { class Debugger: public mate::TrackableObject, public content::DevToolsAgentHostClient { public: - using ResponseCallback = - base::Callback; using SendCommandCallback = base::Callback; - using DetachCallback = base::Callback; static mate::Handle Create( v8::Isolate* isolate, content::WebContents* web_contents); @@ -59,15 +56,10 @@ class Debugger: public mate::TrackableObject, void Attach(mate::Arguments* args); void Detach(); void SendCommand(mate::Arguments* args); - void OnDetach(const DetachCallback& callback); - void OnEvent(const ResponseCallback& callback); content::WebContents* web_contents_; // Weak Reference. scoped_refptr agent_host_; - DetachCallback detach_callback_; - ResponseCallback response_callback_; - PendingRequestMap pending_requests_; int previous_request_id_; diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index 2cce6e6cb9d..b71ddf4cb9f 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -70,6 +70,9 @@ let wrapWebContents = function(webContents) { var controller, method, name, ref1; webContents.__proto__ = EventEmitter.prototype; + // webContents.debugger is an EventEmitter. + webContents.debugger.__proto__ = EventEmitter.prototype; + // Every remote callback from renderer process would add a listenter to the // render-view-deleted event, so ignore the listenters warning. webContents.setMaxListeners(0); diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index c64f1886aba..2bf593d10f2 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -836,7 +836,7 @@ when the DevTools has been closed. ### `webContents.debugger` -Debugger API serves as an alternate transport for remote debugging protocol. +Debugger API serves as an alternate transport for [remote debugging protocol][rdp]. ```javascript try { @@ -845,11 +845,11 @@ try { console.log("Debugger attach failed : ", err); }; -win.webContents.debugger.onDetach(function(reason) { +win.webContents.debugger.on('detach', function(event, reason) { console.log("Debugger detached due to : ", reason); }); -win.webContents.debugger.onEvent(function(method, params) { +win.webContents.debugger.on('message', function(event, method, params) { if (method == "Network.requestWillBeSent") { if (params.request.url == "https://www.github.com") win.webContents.debugger.detach(); @@ -861,7 +861,7 @@ win.webContents.debugger.sendCommand("Network.enable"); #### `webContents.debugger.attach([protocolVersion])` -* `protocolVersion` String - Required debugging protocol version. +* `protocolVersion` String - Requested debugging protocol version. Attaches the debugger to the `webContents`. @@ -880,19 +880,21 @@ Detaches the debugger from the `webContents`. Send given command to the debugging target. -#### `webContents.debugger.onDetach(callback)` +#### Event: 'detach' -* `callback` Function - * `reason` String - Reason for detaching debugger. +* `event` Event +* `reason` String - Reason for detaching debugger. -`callback` is fired when debugging session is terminated. This happens either when +Emitted when debugging session is terminated. This happens either when `webContents` is closed or devtools is invoked for the attached `webContents`. -#### `webContents.debugger.onEvent(callback)` +#### Event: 'message' -* `callback` Function - * `method` String - Method name. - * `params` Object - Event parameters defined by the 'parameters' - attribute in the remote debugging protocol. +* `event` Event +* `method` String - Method name. +* `params` Object - Event parameters defined by the 'parameters' + attribute in the remote debugging protocol. -`callback` is fired whenever debugging target issues instrumentation event. +Emitted whenever debugging target issues instrumentation event. + +[rdp]: https://developer.chrome.com/devtools/docs/debugger-protocol From 3a60ab386c0d67d2126cff859ddbf20029001431 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 22 Jan 2016 14:17:23 +0530 Subject: [PATCH 019/688] add spec --- atom/browser/api/atom_api_debugger.cc | 28 ++++-- atom/browser/api/atom_api_debugger.h | 4 +- docs/api/web-contents.md | 11 ++- spec/api-debugger-spec.js | 136 ++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 11 deletions(-) create mode 100644 spec/api-debugger-spec.js diff --git a/atom/browser/api/atom_api_debugger.cc b/atom/browser/api/atom_api_debugger.cc index 76ea46df9f3..b40bb413427 100644 --- a/atom/browser/api/atom_api_debugger.cc +++ b/atom/browser/api/atom_api_debugger.cc @@ -51,17 +51,26 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host, std::string method; if (!dict->GetString("method", &method)) return; - base::DictionaryValue* params = nullptr; - dict->GetDictionary("params", ¶ms); - Emit("message", method, *params); + base::DictionaryValue* params_value = nullptr; + base::DictionaryValue params; + if (dict->GetDictionary("params", ¶ms_value)) + params.Swap(params_value); + Emit("message", method, params); } else { auto send_command_callback = pending_requests_[id]; pending_requests_.erase(id); if (send_command_callback.is_null()) return; - base::DictionaryValue* result = nullptr; - dict->GetDictionary("result", &result); - send_command_callback.Run(*result); + base::DictionaryValue* error_body = nullptr; + base::DictionaryValue error; + if (dict->GetDictionary("error", &error_body)) + error.Swap(error_body); + + base::DictionaryValue* result_body = nullptr; + base::DictionaryValue result; + if (dict->GetDictionary("result", &result_body)) + result.Swap(result_body); + send_command_callback.Run(error, result); } } @@ -87,6 +96,10 @@ void Debugger::Attach(mate::Arguments* args) { agent_host_->AttachClient(this); } +bool Debugger::IsAttached() { + return agent_host_.get() ? agent_host_->IsAttached() : false; +} + void Debugger::Detach() { if (!agent_host_.get()) return; @@ -97,7 +110,7 @@ void Debugger::Detach() { void Debugger::SendCommand(mate::Arguments* args) { if (!agent_host_.get()) - args->ThrowError("Debugger is not attached to a target"); + return; std::string method; if (!args->GetNext(&method)) { @@ -134,6 +147,7 @@ void Debugger::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { mate::ObjectTemplateBuilder(isolate, prototype) .SetMethod("attach", &Debugger::Attach) + .SetMethod("isAttached", &Debugger::IsAttached) .SetMethod("detach", &Debugger::Detach) .SetMethod("sendCommand", &Debugger::SendCommand); } diff --git a/atom/browser/api/atom_api_debugger.h b/atom/browser/api/atom_api_debugger.h index 894c2bc319c..5454108e8b0 100644 --- a/atom/browser/api/atom_api_debugger.h +++ b/atom/browser/api/atom_api_debugger.h @@ -31,7 +31,8 @@ class Debugger: public mate::TrackableObject, public content::DevToolsAgentHostClient { public: using SendCommandCallback = - base::Callback; + base::Callback; static mate::Handle Create( v8::Isolate* isolate, content::WebContents* web_contents); @@ -54,6 +55,7 @@ class Debugger: public mate::TrackableObject, using PendingRequestMap = std::map; void Attach(mate::Arguments* args); + bool IsAttached(); void Detach(); void SendCommand(mate::Arguments* args); diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 2bf593d10f2..939a0962997 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -861,10 +861,14 @@ win.webContents.debugger.sendCommand("Network.enable"); #### `webContents.debugger.attach([protocolVersion])` -* `protocolVersion` String - Requested debugging protocol version. +* `protocolVersion` String (optional) - Requested debugging protocol version. Attaches the debugger to the `webContents`. +#### `webContents.debugger.isAttached()` + +Returns a boolean indicating whether a debugger is attached to the `webContents`. + #### `webContents.debugger.detach()` Detaches the debugger from the `webContents`. @@ -873,8 +877,9 @@ Detaches the debugger from the `webContents`. * `method` String - Method name, should be one of the methods defined by the remote debugging protocol. -* `commandParams` Object - JSON object with request parameters. -* `callback` Function - Response +* `commandParams` Object (optional) - JSON object with request parameters. +* `callback` Function (optional) - Response + * `error` Object - Error message indicating the failure of the command. * `result` Object - Response defined by the 'returns' attribute of the command description in the remote debugging protocol. diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js new file mode 100644 index 00000000000..7a16ca7263c --- /dev/null +++ b/spec/api-debugger-spec.js @@ -0,0 +1,136 @@ +var assert, path, remote, BrowserWindow; + +assert = require('assert'); + +path = require('path'); + +remote = require('electron').remote; + +BrowserWindow = remote.BrowserWindow; + +describe('debugger module', function() { + var fixtures, w; + fixtures = path.resolve(__dirname, 'fixtures'); + w = null; + beforeEach(function() { + if (w != null) { + w.destroy(); + } + w = new BrowserWindow({ + show: false, + width: 400, + height: 400 + }); + }); + afterEach(function() { + if (w != null) { + w.destroy(); + } + w = null; + }); + + describe('debugger.attach', function() { + it('fails when devtools is already open', function(done) { + w.webContents.on('did-finish-load', function() { + w.webContents.openDevTools(); + try { + w.webContents.debugger.attach(); + } catch(err) { + assert(w.webContents.debugger.isAttached()); + done(); + } + }); + w.webContents.loadURL('file://' + path.join(fixtures, 'pages', 'a.html')); + }); + + it('fails when protocol version is not supported', function(done) { + try { + w.webContents.debugger.attach("2.0"); + } catch(err) { + assert(!w.webContents.debugger.isAttached()); + done(); + } + }); + + it('attaches when no protocol version is specified', function(done) { + try { + w.webContents.debugger.attach(); + } catch(err) { + done('unexpected error : ' + err); + } + assert(w.webContents.debugger.isAttached()); + done(); + }); + }); + + describe('debugger.detach', function() { + it('fires detach event', function(done) { + w.webContents.debugger.on('detach', function(e, reason) { + assert.equal(reason, 'target closed'); + assert(!w.webContents.debugger.isAttached()); + done(); + }); + try { + w.webContents.debugger.attach(); + } catch(err) { + done('unexpected error : ' + err); + } + w.webContents.debugger.detach(); + }); + }); + + describe('debugger.sendCommand', function() { + it('retuns response', function(done) { + w.webContents.loadURL('about:blank'); + try { + w.webContents.debugger.attach(); + } catch(err) { + done('unexpected error : ' + err); + } + var callback = function(err, res) { + assert(!res.wasThrown); + assert.equal(res.result.value, 6); + w.webContents.debugger.detach(); + done(); + }; + const params = { + "expression": "4+2", + }; + w.webContents.debugger.sendCommand("Runtime.evaluate", params, callback); + }); + + it('fires message event', function(done) { + var url = 'file://' + path.join(fixtures, 'pages', 'a.html'); + w.webContents.loadURL(url); + try { + w.webContents.debugger.attach(); + } catch(err) { + done('unexpected error : ' + err); + } + w.webContents.debugger.on('message', function(e, method, params) { + if(method == "Console.messageAdded") { + assert.equal(params.message.type, 'log'); + assert.equal(params.message.url, url); + assert.equal(params.message.text, 'a'); + w.webContents.debugger.detach(); + done(); + } + }); + w.webContents.debugger.sendCommand("Console.enable"); + }); + + it('returns error message when command fails', function(done) { + w.webContents.loadURL('about:blank'); + try { + w.webContents.debugger.attach(); + } catch(err) { + done('unexpected error : ' + err); + } + w.webContents.debugger.sendCommand("Test", function(err) { + assert.equal(err.message, '\'Test\' wasn\'t found'); + w.webContents.debugger.detach(); + done(); + }); + }); + }); +}); From 360266ba5bdf7a66bfd18f878d6eba03a0738613 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 10:51:51 -0700 Subject: [PATCH 020/688] positioningItem => positioning_item --- atom/browser/api/atom_api_menu.h | 5 +++-- atom/browser/api/atom_api_menu_mac.h | 2 +- atom/browser/api/atom_api_menu_mac.mm | 12 ++++++------ atom/browser/api/atom_api_menu_views.cc | 2 +- atom/browser/api/atom_api_menu_views.h | 2 +- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/atom/browser/api/atom_api_menu.h b/atom/browser/api/atom_api_menu.h index d3452628100..1ea83653e78 100644 --- a/atom/browser/api/atom_api_menu.h +++ b/atom/browser/api/atom_api_menu.h @@ -52,8 +52,9 @@ class Menu : public mate::TrackableObject, void MenuWillShow(ui::SimpleMenuModel* source) override; virtual void Popup(Window* window) = 0; - virtual void PopupAt(Window* window, int x, int y, - int positioningItem = 0) = 0; + virtual void PopupAt(Window* window, + int x = -1, int y = -1, + int positioning_item = 0) = 0; scoped_ptr model_; Menu* parent_; diff --git a/atom/browser/api/atom_api_menu_mac.h b/atom/browser/api/atom_api_menu_mac.h index e71198315b6..34450bc8b58 100644 --- a/atom/browser/api/atom_api_menu_mac.h +++ b/atom/browser/api/atom_api_menu_mac.h @@ -20,7 +20,7 @@ class MenuMac : public Menu { MenuMac(); void Popup(Window* window) override; - void PopupAt(Window* window, int x, int y, int positioningItem = 0) override; + void PopupAt(Window* window, int x, int y, int positioning_item = 0) override; base::scoped_nsobject menu_controller_; diff --git a/atom/browser/api/atom_api_menu_mac.mm b/atom/browser/api/atom_api_menu_mac.mm index 7e505ccd9d3..d87617a5fc6 100644 --- a/atom/browser/api/atom_api_menu_mac.mm +++ b/atom/browser/api/atom_api_menu_mac.mm @@ -50,7 +50,7 @@ void MenuMac::Popup(Window* window) { forView:web_contents->GetContentNativeView()]; } -void MenuMac::PopupAt(Window* window, int x, int y, int positioningItem) { +void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { NativeWindow* native_window = window->window(); if (!native_window) return; @@ -64,13 +64,13 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioningItem) { NSView* view = web_contents->GetContentNativeView(); // Show the menu. - if (positioningItem >= [menu numberOfItems]) { - positioningItem = [menu numberOfItems] - 1; + if (positioning_item >= [menu numberOfItems]) { + positioning_item = [menu numberOfItems] - 1; } - if (positioningItem < 0) { - positioningItem = 0; + if (positioning_item < 0) { + positioning_item = 0; } - [menu popUpMenuPositioningItem:[menu itemAtIndex:positioningItem] + [menu popUpMenupositioning_item:[menu itemAtIndex:positioning_item] atLocation:NSMakePoint(x, [view frame].size.height - y) inView:view]; } diff --git a/atom/browser/api/atom_api_menu_views.cc b/atom/browser/api/atom_api_menu_views.cc index 67b55d5e988..93869df87f0 100644 --- a/atom/browser/api/atom_api_menu_views.cc +++ b/atom/browser/api/atom_api_menu_views.cc @@ -20,7 +20,7 @@ void MenuViews::Popup(Window* window) { PopupAtPoint(window, gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); } -void MenuViews::PopupAt(Window* window, int x, int y, int positioningItem) { +void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { NativeWindow* native_window = static_cast(window->window()); if (!native_window) return; diff --git a/atom/browser/api/atom_api_menu_views.h b/atom/browser/api/atom_api_menu_views.h index 9e306b4e72b..9f1b116a004 100644 --- a/atom/browser/api/atom_api_menu_views.h +++ b/atom/browser/api/atom_api_menu_views.h @@ -18,7 +18,7 @@ class MenuViews : public Menu { protected: void Popup(Window* window) override; - void PopupAt(Window* window, int x, int y, int positioningItem = 0) override; + void PopupAt(Window* window, int x, int y, int positioning_item = 0) override; private: void PopupAtPoint(Window* window, const gfx::Point& point); From 5f195a789ae326fb8a33188ef97686f8b44298f4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 11:17:12 -0700 Subject: [PATCH 021/688] mac: Remove duplicate code of Popup --- atom/browser/api/atom_api_menu_mac.mm | 55 +++++++++------------------ 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/atom/browser/api/atom_api_menu_mac.mm b/atom/browser/api/atom_api_menu_mac.mm index d87617a5fc6..cfd3f0a89c3 100644 --- a/atom/browser/api/atom_api_menu_mac.mm +++ b/atom/browser/api/atom_api_menu_mac.mm @@ -19,35 +19,7 @@ MenuMac::MenuMac() { } void MenuMac::Popup(Window* window) { - NativeWindow* native_window = window->window(); - if (!native_window) - return; - content::WebContents* web_contents = native_window->web_contents(); - if (!web_contents) - return; - - NSWindow* nswindow = native_window->GetNativeWindow(); - base::scoped_nsobject menu_controller( - [[AtomMenuController alloc] initWithModel:model_.get()]); - - // Fake out a context menu event. - NSEvent* currentEvent = [NSApp currentEvent]; - NSPoint position = [nswindow mouseLocationOutsideOfEventStream]; - NSTimeInterval eventTime = [currentEvent timestamp]; - NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown - location:position - modifierFlags:NSRightMouseDownMask - timestamp:eventTime - windowNumber:[nswindow windowNumber] - context:nil - eventNumber:0 - clickCount:1 - pressure:1.0]; - - // Show the menu. - [NSMenu popUpContextMenu:[menu_controller menu] - withEvent:clickEvent - forView:web_contents->GetContentNativeView()]; + PopupAt(window, -1, -1, 0); } void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { @@ -63,16 +35,23 @@ void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { NSMenu* menu = [menu_controller menu]; NSView* view = web_contents->GetContentNativeView(); + // Which menu item to show. + NSMenuItem* item = nil; + if (positioning_item < [menu numberOfItems] && positioning_item >= 0) + item = [menu itemAtIndex:positioning_item]; + + // (-1, -1) means showing on mouse location. + NSPoint position; + if (x == -1 || y == -1) { + NSWindow* nswindow = native_window->GetNativeWindow(); + position = [view convertPoint:[nswindow mouseLocationOutsideOfEventStream] + fromView:nil]; + } else { + position = NSMakePoint(x, [view frame].size.height - y); + } + // Show the menu. - if (positioning_item >= [menu numberOfItems]) { - positioning_item = [menu numberOfItems] - 1; - } - if (positioning_item < 0) { - positioning_item = 0; - } - [menu popUpMenupositioning_item:[menu itemAtIndex:positioning_item] - atLocation:NSMakePoint(x, [view frame].size.height - y) - inView:view]; + [menu popUpMenuPositioningItem:item atLocation:position inView:view]; } // static From 0e3a3d07484653bb50632cc8e2f7832b365dd6fc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 11:25:16 -0700 Subject: [PATCH 022/688] views: Remove PopupAtPoint --- atom/browser/api/atom_api_menu_views.cc | 17 +++++++++++------ atom/browser/api/atom_api_menu_views.h | 2 -- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_menu_views.cc b/atom/browser/api/atom_api_menu_views.cc index 93869df87f0..248523c4537 100644 --- a/atom/browser/api/atom_api_menu_views.cc +++ b/atom/browser/api/atom_api_menu_views.cc @@ -17,7 +17,7 @@ MenuViews::MenuViews() { } void MenuViews::Popup(Window* window) { - PopupAtPoint(window, gfx::Screen::GetNativeScreen()->GetCursorScreenPoint()); + PopupAt(window, -1, -1, 0); } void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { @@ -31,18 +31,23 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { if (!view) return; - gfx::Point origin = view->GetViewBounds().origin(); - PopupAtPoint(window, gfx::Point(origin.x() + x, origin.y() + y)); -} + // (-1, -1) means showing on mouse location. + gfx::Point location; + if (x == -1 || y == -1) { + location = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(); + } else { + gfx::Point origin = view->GetViewBounds().origin(); + location = gfx::Point(origin.x() + x, origin.y() + y); + } -void MenuViews::PopupAtPoint(Window* window, const gfx::Point& point) { + // Show the menu. views::MenuRunner menu_runner( model(), views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS); ignore_result(menu_runner.RunMenuAt( static_cast(window->window())->widget(), NULL, - gfx::Rect(point, gfx::Size()), + gfx::Rect(location, gfx::Size()), views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE)); } diff --git a/atom/browser/api/atom_api_menu_views.h b/atom/browser/api/atom_api_menu_views.h index 9f1b116a004..802e1405fd5 100644 --- a/atom/browser/api/atom_api_menu_views.h +++ b/atom/browser/api/atom_api_menu_views.h @@ -21,8 +21,6 @@ class MenuViews : public Menu { void PopupAt(Window* window, int x, int y, int positioning_item = 0) override; private: - void PopupAtPoint(Window* window, const gfx::Point& point); - DISALLOW_COPY_AND_ASSIGN(MenuViews); }; From ca77c95c6d5e5fe959f7b406acfeee8f558944b3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 11:27:17 -0700 Subject: [PATCH 023/688] No more need to override Menu::Popup --- atom/browser/api/atom_api_menu.cc | 4 ++++ atom/browser/api/atom_api_menu.h | 2 +- atom/browser/api/atom_api_menu_mac.h | 1 - atom/browser/api/atom_api_menu_mac.mm | 4 ---- atom/browser/api/atom_api_menu_views.cc | 4 ---- atom/browser/api/atom_api_menu_views.h | 1 - 6 files changed, 5 insertions(+), 11 deletions(-) diff --git a/atom/browser/api/atom_api_menu.cc b/atom/browser/api/atom_api_menu.cc index 96cba3fe991..ec565073900 100644 --- a/atom/browser/api/atom_api_menu.cc +++ b/atom/browser/api/atom_api_menu.cc @@ -69,6 +69,10 @@ void Menu::MenuWillShow(ui::SimpleMenuModel* source) { menu_will_show_.Run(); } +void Menu::Popup(Window* window) { + PopupAt(window); +} + void Menu::InsertItemAt( int index, int command_id, const base::string16& label) { model_->InsertItemAt(index, command_id, label); diff --git a/atom/browser/api/atom_api_menu.h b/atom/browser/api/atom_api_menu.h index 1ea83653e78..18cfae6a348 100644 --- a/atom/browser/api/atom_api_menu.h +++ b/atom/browser/api/atom_api_menu.h @@ -51,7 +51,7 @@ class Menu : public mate::TrackableObject, void ExecuteCommand(int command_id, int event_flags) override; void MenuWillShow(ui::SimpleMenuModel* source) override; - virtual void Popup(Window* window) = 0; + void Popup(Window* window); virtual void PopupAt(Window* window, int x = -1, int y = -1, int positioning_item = 0) = 0; diff --git a/atom/browser/api/atom_api_menu_mac.h b/atom/browser/api/atom_api_menu_mac.h index 34450bc8b58..85227fa2a9d 100644 --- a/atom/browser/api/atom_api_menu_mac.h +++ b/atom/browser/api/atom_api_menu_mac.h @@ -19,7 +19,6 @@ class MenuMac : public Menu { protected: MenuMac(); - void Popup(Window* window) override; void PopupAt(Window* window, int x, int y, int positioning_item = 0) override; base::scoped_nsobject menu_controller_; diff --git a/atom/browser/api/atom_api_menu_mac.mm b/atom/browser/api/atom_api_menu_mac.mm index cfd3f0a89c3..71c677b0476 100644 --- a/atom/browser/api/atom_api_menu_mac.mm +++ b/atom/browser/api/atom_api_menu_mac.mm @@ -18,10 +18,6 @@ namespace api { MenuMac::MenuMac() { } -void MenuMac::Popup(Window* window) { - PopupAt(window, -1, -1, 0); -} - void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { NativeWindow* native_window = window->window(); if (!native_window) diff --git a/atom/browser/api/atom_api_menu_views.cc b/atom/browser/api/atom_api_menu_views.cc index 248523c4537..4a3a97dd906 100644 --- a/atom/browser/api/atom_api_menu_views.cc +++ b/atom/browser/api/atom_api_menu_views.cc @@ -16,10 +16,6 @@ namespace api { MenuViews::MenuViews() { } -void MenuViews::Popup(Window* window) { - PopupAt(window, -1, -1, 0); -} - void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { NativeWindow* native_window = static_cast(window->window()); if (!native_window) diff --git a/atom/browser/api/atom_api_menu_views.h b/atom/browser/api/atom_api_menu_views.h index 802e1405fd5..e4d17c77ca6 100644 --- a/atom/browser/api/atom_api_menu_views.h +++ b/atom/browser/api/atom_api_menu_views.h @@ -17,7 +17,6 @@ class MenuViews : public Menu { MenuViews(); protected: - void Popup(Window* window) override; void PopupAt(Window* window, int x, int y, int positioning_item = 0) override; private: From 2d8e5e3a16cb624c4f69501ac3c70aa28bc1735a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 11:29:26 -0700 Subject: [PATCH 024/688] docs: Default parameter for Menu.popup --- docs/api/menu.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index 7b563d57801..ca35d4bb42a 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -239,16 +239,15 @@ will become properties of the constructed menu items. ### `Menu.popup([browserWindow, x, y, positioningItem])` -* `browserWindow` BrowserWindow (optional) -* `x` Number (optional) -* `y` Number (**required** if `x` is used) -* `positioningItem` Number (optional) _OS X_ +* `browserWindow` BrowserWindow (optional) - Default is `null`. +* `x` Number (optional) - Default is -1. +* `y` Number (**required** if `x` is used) - Default is -1. +* `positioningItem` Number (optional) _OS X_ - the index of the menu item to + be positioned under the mouse cursor at the specified coordinates. -Pops up this menu as a context menu in the `browserWindow`. You -can optionally provide a `x,y` coordinate to place the menu at, otherwise it -will be placed at the current mouse cursor position. `positioningItem` is the -index of the menu item to be positioned under the mouse cursor at the specified -coordinates (only supported on OS X). +Pops up this menu as a context menu in the `browserWindow`. You can optionally +provide a `x, y` coordinate to place the menu at, otherwise it will be placed +at the current mouse cursor position. ### `Menu.append(menuItem)` From d1051b55cc9d970fd64bd8ebdf767f294c1e400a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 11:32:14 -0700 Subject: [PATCH 025/688] docs: Default value of positioningItem --- docs/api/menu.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index ca35d4bb42a..0e66fc216d5 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -242,8 +242,9 @@ will become properties of the constructed menu items. * `browserWindow` BrowserWindow (optional) - Default is `null`. * `x` Number (optional) - Default is -1. * `y` Number (**required** if `x` is used) - Default is -1. -* `positioningItem` Number (optional) _OS X_ - the index of the menu item to - be positioned under the mouse cursor at the specified coordinates. +* `positioningItem` Number (optional) _OS X_ - The index of the menu item to + be positioned under the mouse cursor at the specified coordinates. Default is + -1. Pops up this menu as a context menu in the `browserWindow`. You can optionally provide a `x, y` coordinate to place the menu at, otherwise it will be placed From 984462be447593a1a7fe64964105b51a3154b344 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 11:59:08 -0700 Subject: [PATCH 026/688] Remove Menu::Popup --- atom/browser/api/atom_api_menu.cc | 7 +------ atom/browser/api/atom_api_menu.h | 1 - atom/browser/api/lib/menu.js | 15 +++++++++------ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_menu.cc b/atom/browser/api/atom_api_menu.cc index ec565073900..e40ba17f464 100644 --- a/atom/browser/api/atom_api_menu.cc +++ b/atom/browser/api/atom_api_menu.cc @@ -69,10 +69,6 @@ void Menu::MenuWillShow(ui::SimpleMenuModel* source) { menu_will_show_.Run(); } -void Menu::Popup(Window* window) { - PopupAt(window); -} - void Menu::InsertItemAt( int index, int command_id, const base::string16& label) { model_->InsertItemAt(index, command_id, label); @@ -173,8 +169,7 @@ void Menu::BuildPrototype(v8::Isolate* isolate, .SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt) .SetMethod("isEnabledAt", &Menu::IsEnabledAt) .SetMethod("isVisibleAt", &Menu::IsVisibleAt) - .SetMethod("_popup", &Menu::Popup) - .SetMethod("_popupAt", &Menu::PopupAt); + .SetMethod("popupAt", &Menu::PopupAt); } } // namespace api diff --git a/atom/browser/api/atom_api_menu.h b/atom/browser/api/atom_api_menu.h index 18cfae6a348..1ae708863a7 100644 --- a/atom/browser/api/atom_api_menu.h +++ b/atom/browser/api/atom_api_menu.h @@ -51,7 +51,6 @@ class Menu : public mate::TrackableObject, void ExecuteCommand(int command_id, int event_flags) override; void MenuWillShow(ui::SimpleMenuModel* source) override; - void Popup(Window* window); virtual void PopupAt(Window* window, int x = -1, int y = -1, int positioning_item = 0) = 0; diff --git a/atom/browser/api/lib/menu.js b/atom/browser/api/lib/menu.js index 506922fd4a8..62c771af6c6 100644 --- a/atom/browser/api/lib/menu.js +++ b/atom/browser/api/lib/menu.js @@ -159,17 +159,20 @@ Menu.prototype._init = function() { }; Menu.prototype.popup = function(window, x, y, positioningItem) { - if ((window != null ? window.constructor : void 0) !== BrowserWindow) { + if (typeof window != 'object' || window.constructor !== BrowserWindow) { // Shift. + positioningItem = y; y = x; x = window; window = BrowserWindow.getFocusedWindow(); } - if ((x != null) && (y != null)) { - return this._popupAt(window, x, y, positioningItem || 0); - } else { - return this._popup(window); - } + + // Default parameters. + if (typeof x !== 'number') x = -1; + if (typeof y !== 'number') y = -1; + if (typeof positioningItem !== 'number') positioningItem = 0; + + this.popupAt(window, x, y, positioningItem); }; Menu.prototype.append = function(item) { From ef51e4e1086de720b66b6e6e8f45b907f6aa7315 Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Fri, 22 Jan 2016 22:24:33 +0100 Subject: [PATCH 027/688] maximizable and fullscreenable --- atom/browser/api/atom_api_window.cc | 20 ++++++++ atom/browser/api/atom_api_window.h | 4 ++ atom/browser/native_window.cc | 4 ++ atom/browser/native_window.h | 4 ++ atom/browser/native_window_mac.h | 5 +- atom/browser/native_window_mac.mm | 76 +++++++++++++++++++---------- atom/browser/native_window_views.cc | 40 +++++++++++---- atom/browser/native_window_views.h | 4 ++ atom/common/options_switches.cc | 38 ++++++++------- atom/common/options_switches.h | 2 + 10 files changed, 143 insertions(+), 54 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 5ff9cabc909..5bf15a00ce0 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -424,6 +424,22 @@ bool Window::IsMinimizable() { return window_->IsMinimizable(); } +void Window::SetMaximizable(bool maximizable) { + window_->SetMaximizable(maximizable); +} + +bool Window::IsMaximizable() { + return window_->IsMaximizable(); +} + +void Window::SetFullscreenable(bool fullscreenable) { + window_->SetFullscreenable(fullscreenable); +} + +bool Window::IsFullscreenable() { + return window_->IsFullscreenable(); +} + void Window::SetClosable(bool closable) { window_->SetClosable(closable); } @@ -687,6 +703,10 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isMovable", &Window::IsMovable) .SetMethod("setMinimizable", &Window::SetMinimizable) .SetMethod("isMinimizable", &Window::IsMinimizable) + .SetMethod("setMaximizable", &Window::SetMaximizable) + .SetMethod("isMaximizable", &Window::IsMaximizable) + .SetMethod("setFullscreenable", &Window::SetFullscreenable) + .SetMethod("isFullscreenable", &Window::IsFullscreenable) .SetMethod("setClosable", &Window::SetClosable) .SetMethod("isClosable", &Window::IsClosable) .SetMethod("setAlwaysOnTop", &Window::SetAlwaysOnTop) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index ae10fa951db..97d7d45dcfd 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -110,6 +110,10 @@ class Window : public mate::TrackableObject, bool IsMovable(); void SetMinimizable(bool minimizable); bool IsMinimizable(); + void SetMaximizable(bool maximizable); + bool IsMaximizable(); + void SetFullscreenable(bool fullscreenable); + bool IsFullscreenable(); void SetClosable(bool closable); bool IsClosable(); void SetAlwaysOnTop(bool top); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 1f330a261cf..69bebc1e23b 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -128,6 +128,10 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { if (options.Get(options::kClosable, &closable)) { SetClosable(closable); } + bool maximizable; + if (options.Get(options::kMaximizable, &maximizable)) { + SetMaximizable(maximizable); + } #endif bool top; if (options.Get(options::kAlwaysOnTop, &top) && top) { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index d379db2b491..31a104bf0e3 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -129,6 +129,10 @@ class NativeWindow : public base::SupportsUserData, virtual bool IsMovable() = 0; virtual void SetMinimizable(bool minimizable) = 0; virtual bool IsMinimizable() = 0; + virtual void SetMaximizable(bool maximizable) = 0; + virtual bool IsMaximizable() = 0; + virtual void SetFullscreenable(bool fullscreenable) = 0; + virtual bool IsFullscreenable() = 0; virtual void SetClosable(bool closable) = 0; virtual bool IsClosable() = 0; virtual void SetAlwaysOnTop(bool top) = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 45c974c0793..9b9a702a9ee 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -52,6 +52,10 @@ class NativeWindowMac : public NativeWindow { bool IsMovable() override; void SetMinimizable(bool minimizable) override; bool IsMinimizable() override; + void SetMaximizable(bool maximizable) override; + bool IsMaximizable() override; + void SetFullscreenable(bool fullscreenable) override; + bool IsFullscreenable() override; void SetClosable(bool closable) override; bool IsClosable() override; void SetAlwaysOnTop(bool top) override; @@ -106,7 +110,6 @@ class NativeWindowMac : public NativeWindow { gfx::Size WindowSizeToContentSize(const gfx::Size& size) override; void UpdateDraggableRegions( const std::vector& regions) override; - void FixZoomButton(); void InstallView(); void UninstallView(); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 1c91c5efa51..db42b3754ed 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -371,6 +371,12 @@ NativeWindowMac::NativeWindowMac( bool minimizable = true; options.Get(options::kMinimizable, &minimizable); + + bool maximizable = true; + options.Get(options::kMaximizable, &maximizable); + + bool fullscreenable = true; + options.Get(options::kFullscreenable, &fullscreenable); bool closable = true; options.Get(options::kClosable, &closable); @@ -486,11 +492,10 @@ NativeWindowMac::NativeWindowMac( // Disable fullscreen button when 'fullscreen' is specified to false. bool fullscreen = false; - if (!(options.Get(options::kFullscreen, &fullscreen) && - !fullscreen)) { - NSUInteger collectionBehavior = [window_ collectionBehavior]; - collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; - [window_ setCollectionBehavior:collectionBehavior]; + options.Get(options::kFullscreen, &fullscreen); + + if (fullscreenable) { + SetFullscreenable(true); } else if (base::mac::IsOSElCapitanOrLater()) { // On EL Capitan this flag is required to hide fullscreen button. NSUInteger collectionBehavior = [window_ collectionBehavior]; @@ -499,8 +504,8 @@ NativeWindowMac::NativeWindowMac( } // Disable zoom button if window is not resizable - if (!resizable) { - [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; + if (!maximizable) { + SetMaximizable(false); } NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); @@ -648,12 +653,8 @@ void NativeWindowMac::SetResizable(bool resizable) { // to explicitly disables that. ScopedDisableResize disable_resize; if (resizable) { - [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:YES]; [window_ setStyleMask:[window_ styleMask] | NSResizableWindowMask]; } else { - // If we disable the button before changing the styleMask, button is not - // disabled. Looks like a bug in Cocoa (OS X 10.10.5) - [window_ setStyleMask:[window_ styleMask] & (~NSResizableWindowMask)]; [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; } } @@ -671,25 +672,62 @@ bool NativeWindowMac::IsMovable() { } void NativeWindowMac::SetMinimizable(bool minimizable) { + bool maximizable = IsMaximizable(); if (minimizable) { [window_ setStyleMask:[window_ styleMask] | NSMiniaturizableWindowMask]; } else { [window_ setStyleMask:[window_ styleMask] & (~NSMiniaturizableWindowMask)]; } - FixZoomButton(); + // If fullscreen has not been disabled via `fullscreenable: false` (i.e. when + // collectionBehavior has NSWindowCollectionBehaviorFullScreenPrimary mask), + // zoom button is reset to it's default (enabled) state when window's + // styleMask has been changed. So if the button was disabled, we have to + // disable it again. I think it's a bug in Cocoa. + if (!maximizable) { + SetMaximizable(false); + } } bool NativeWindowMac::IsMinimizable() { return [window_ styleMask] & NSMiniaturizableWindowMask; } +void NativeWindowMac::SetMaximizable(bool maximizable) { + [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:maximizable]; +} + +bool NativeWindowMac::IsMaximizable() { + return [[window_ standardWindowButton:NSWindowZoomButton] isEnabled]; +} + +void NativeWindowMac::SetFullscreenable(bool fullscreenable) { + bool maximizable = IsMaximizable(); + NSUInteger collectionBehavior = [window_ collectionBehavior]; + if (fullscreenable) { + collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; + } else { + collectionBehavior &= (~NSWindowCollectionBehaviorFullScreenPrimary); + } + [window_ setCollectionBehavior:collectionBehavior]; + if (!maximizable) { + SetMaximizable(false); + } +} + +bool NativeWindowMac::IsFullscreenable() { + return [window_ collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary; +} + void NativeWindowMac::SetClosable(bool closable) { + bool maximizable = IsMaximizable(); if (closable) { [window_ setStyleMask:[window_ styleMask] | NSClosableWindowMask]; } else { [window_ setStyleMask:[window_ styleMask] & (~NSClosableWindowMask)]; } - FixZoomButton(); + if (!maximizable) { + SetMaximizable(false); + } } bool NativeWindowMac::IsClosable() { @@ -700,18 +738,6 @@ void NativeWindowMac::SetAlwaysOnTop(bool top) { [window_ setLevel:(top ? NSFloatingWindowLevel : NSNormalWindowLevel)]; } -void NativeWindowMac::FixZoomButton() { - // If fullscreen has not been disabled via `fullscreen: false` (i.e. when - // collectionBehavior has NSWindowCollectionBehaviorFullScreenPrimary mask), - // zoom button is reset to it's default (enabled) state when window's - // styleMask has been changed. So if the button was disabled, we have to - // disable it again. I think it's a bug in Cocoa. - if ([window_ collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary - && !([window_ styleMask] & NSResizableWindowMask)) { - [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; - } -} - bool NativeWindowMac::IsAlwaysOnTop() { return [window_ level] == NSFloatingWindowLevel; } diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index e97a1f3c410..012f6c60fdd 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -139,6 +139,7 @@ NativeWindowViews::NativeWindowViews( options.Get(options::kResizable, &resizable_); options.Get(options::kMovable, &movable_); options.Get(options::kMinimizable, &minimizable_); + options.Get(options::kMaximizable, &maximizable_); #endif if (enable_larger_than_screen()) @@ -187,9 +188,7 @@ NativeWindowViews::NativeWindowViews( window_->Init(params); bool fullscreen = false; - if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) { - maximizable_ = false; - } + options.Get(options::kFullscreen, &fullscreen); #if defined(USE_X11) // Start monitoring window states. @@ -245,11 +244,6 @@ NativeWindowViews::NativeWindowViews( DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); style |= WS_THICKFRAME | WS_CAPTION | WS_MINIMIZEBOX; - if (!maximizable_) { - style &= (~WS_MAXIMIZEBOX); - } else { - style |= WS_MAXIMIZEBOX; - } if (transparent()) { DWORD ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); @@ -441,9 +435,8 @@ void NativeWindowViews::SetResizable(bool resizable) { DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); if (resizable) { style |= WS_THICKFRAME; - if (maximizable_) style |= WS_MAXIMIZEBOX; } else { - style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX); + style &= ~(WS_THICKFRAME); } ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); } @@ -505,6 +498,33 @@ bool NativeWindowViews::IsMinimizable() { #endif } +void NativeWindowViews::SetMaximizable(bool maximizable) { +#if defined(OS_WIN) + DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); + if (maximizable) { + style |= WS_MAXIMIZEBOX; + } else { + style &= (~WS_MAXIMIZEBOX); + } + ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); +#endif +} + +bool NativeWindowViews::IsMaximizable() { +#if defined(OS_WIN) + return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MAXIMIZEBOX; +#elif defined(USE_X11) + return true; +#endif +} + +void NativeWindowViews::SetFullscreenable(bool maximizable) { +} + +bool NativeWindowViews::IsFullscreenable() { + return true; +} + void NativeWindowViews::SetClosable(bool closable) { #if defined(OS_WIN) HMENU menu = GetSystemMenu(GetAcceleratedWidget(), false); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index d3117e5b2f6..7f947b8e983 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -72,6 +72,10 @@ class NativeWindowViews : public NativeWindow, bool IsMovable() override; void SetMinimizable(bool minimizable) override; bool IsMinimizable() override; + void SetMaximizable(bool maximizable) override; + bool IsMaximizable() override; + void SetFullscreenable(bool fullscreenable) override; + bool IsFullscreenable() override; void SetClosable(bool closable) override; bool IsClosable() override; void SetAlwaysOnTop(bool top) override; diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index e14a63ea928..505c3861cea 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -8,24 +8,26 @@ namespace atom { namespace options { -const char kTitle[] = "title"; -const char kIcon[] = "icon"; -const char kFrame[] = "frame"; -const char kShow[] = "show"; -const char kCenter[] = "center"; -const char kX[] = "x"; -const char kY[] = "y"; -const char kWidth[] = "width"; -const char kHeight[] = "height"; -const char kMinWidth[] = "minWidth"; -const char kMinHeight[] = "minHeight"; -const char kMaxWidth[] = "maxWidth"; -const char kMaxHeight[] = "maxHeight"; -const char kResizable[] = "resizable"; -const char kMovable[] = "movable"; -const char kMinimizable[] = "minimizable"; -const char kClosable[] = "closable"; -const char kFullscreen[] = "fullscreen"; +const char kTitle[] = "title"; +const char kIcon[] = "icon"; +const char kFrame[] = "frame"; +const char kShow[] = "show"; +const char kCenter[] = "center"; +const char kX[] = "x"; +const char kY[] = "y"; +const char kWidth[] = "width"; +const char kHeight[] = "height"; +const char kMinWidth[] = "minWidth"; +const char kMinHeight[] = "minHeight"; +const char kMaxWidth[] = "maxWidth"; +const char kMaxHeight[] = "maxHeight"; +const char kResizable[] = "resizable"; +const char kMovable[] = "movable"; +const char kMinimizable[] = "minimizable"; +const char kMaximizable[] = "maximizable"; +const char kFullscreenable[] = "fullscreenable"; +const char kClosable[] = "closable"; +const char kFullscreen[] = "fullscreen"; // Whether the window should show in taskbar. const char kSkipTaskbar[] = "skipTaskbar"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index f7b68f218b7..476baaf7de3 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -25,6 +25,8 @@ extern const char kMaxHeight[]; extern const char kResizable[]; extern const char kMovable[]; extern const char kMinimizable[]; +extern const char kMaximizable[]; +extern const char kFullscreenable[]; extern const char kClosable[]; extern const char kFullscreen[]; extern const char kSkipTaskbar[]; From 318250496942990ca42cede28b8c6f3206d9022b Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Fri, 22 Jan 2016 23:31:59 +0100 Subject: [PATCH 028/688] maximizable, fullscreenable docs --- docs/api/browser-window.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 820cf3e2b20..65aab96989c 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -51,6 +51,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. on Linux. Default is `true`. * `minimizable` Boolean - Whether window is minimizable. This is not implemented on Linux. Default is `true`. + * `maximizable` Boolean - Whether window is maximizable. This is not + implemented on Linux. Default is `true`. * `closable` Boolean - Whether window is closable. This is not implemented on Linux. Default is `true`. * `alwaysOnTop` Boolean - Whether the window should always stay on top of @@ -59,6 +61,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. explicity set to `false` the fullscreen button will be hidden or disabled on OS X, or the maximize button will be disabled on Windows. Default is `false`. + * `fullscreenable` Boolean - Whether the maximize/zoom button on OS X should + toggle full screen mode or maximize window. Default is `true`. * `skipTaskbar` Boolean - Whether to show the window in taskbar. Default is `false`. * `kiosk` Boolean - The kiosk mode. Default is `false`. @@ -551,6 +555,30 @@ nothing. Returns whether the window can be manually minimized by user. On Linux always returns `true`. +### `win.setMaximizable(maximizable)` _OS X_ _Windows_ + +* `maximizable` Boolean + +Sets whether the window can be manually maximized by user. On Linux does +nothing. + +### `win.isMaximizable()` _OS X_ _Windows_ + +Returns whether the window can be manually maximized by user. On Linux always +returns `true`. + +### `win.setFullscreenable(fullscreenable)` _OS X_ + +* `fullscreenable` Boolean + +Sets whether the maximize/zoom window button toggles fullscreen mode or +maximizes the window. On Windows and Linux does nothing. + +### `win.isFullscreenable()` _OS X_ + +Returns whether the maximize/zoom window button toggles fullscreen mode or +maximizes the window. On Windows and Linux always returns `true`. + ### `win.setClosable(closable)` _OS X_ _Windows_ * `closable` Boolean From 85991d312a64c542795205fcd4d73060653d3d26 Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Fri, 22 Jan 2016 23:44:05 +0100 Subject: [PATCH 029/688] mac: SetResizable fix --- atom/browser/native_window_mac.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index db42b3754ed..ab74de83229 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -649,13 +649,17 @@ void NativeWindowMac::SetContentSizeConstraints( } void NativeWindowMac::SetResizable(bool resizable) { + bool maximizable = IsMaximizable(); // Change styleMask for frameless causes the window to change size, so we have // to explicitly disables that. ScopedDisableResize disable_resize; if (resizable) { [window_ setStyleMask:[window_ styleMask] | NSResizableWindowMask]; } else { - [[window_ standardWindowButton:NSWindowZoomButton] setEnabled:NO]; + [window_ setStyleMask:[window_ styleMask] & (~NSResizableWindowMask)]; + } + if (!maximizable) { + SetMaximizable(false); } } From 2fcd3ce7cd5c6c07ecdabf2cd2c6118398770bc8 Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Sat, 23 Jan 2016 00:54:43 +0100 Subject: [PATCH 030/688] Support alpha in backgroundColor --- atom/browser/native_window.cc | 8 ++++---- atom/browser/native_window_mac.mm | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 1f1a98b0658..4d8f278fa7d 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -552,11 +552,11 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback, } SkColor NativeWindow::ParseHexColor(const std::string& name) { - SkColor result = 0xFF000000; - unsigned value = 0; auto color = name.substr(1); unsigned length = color.size(); - if (length != 3 && length != 6) + SkColor result = (length != 8 ? 0xFF000000 : 0x00000000); + unsigned value = 0; + if (length != 3 && length != 6 && length != 8) return result; for (unsigned i = 0; i < length; ++i) { if (!base::IsHexDigit(color[i])) @@ -564,7 +564,7 @@ SkColor NativeWindow::ParseHexColor(const std::string& name) { value <<= 4; value |= (color[i] < 'A' ? color[i] - '0' : (color[i] - 'A' + 10) & 0xF); } - if (length == 6) { + if (length == 6 || length == 8) { result |= value; return result; } diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 156017194ec..46ca1b34e09 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -710,7 +710,7 @@ void NativeWindowMac::SetBackgroundColor(const std::string& color_name) { NSColor *color = [NSColor colorWithCalibratedRed:SkColorGetR(background_color) green:SkColorGetG(background_color) blue:SkColorGetB(background_color) - alpha:1.0]; + alpha:SkColorGetA(background_color)/255.0f]; [window_ setBackgroundColor:color]; } From ff41b4a2677a5bcb4e48052e150607b96d8f5236 Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Sat, 23 Jan 2016 01:15:49 +0100 Subject: [PATCH 031/688] added hasShadow option to BrowserWindow (osx) --- atom/browser/api/atom_api_window.cc | 10 ++++++++++ atom/browser/api/atom_api_window.h | 2 ++ atom/browser/native_window.cc | 7 +++++++ atom/browser/native_window.h | 2 ++ atom/browser/native_window_mac.h | 2 ++ atom/browser/native_window_mac.mm | 14 ++++++++++++++ atom/common/options_switches.cc | 3 +++ atom/common/options_switches.h | 1 + docs/api/browser-window.md | 13 +++++++++++++ 9 files changed, 54 insertions(+) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 09d88edb9b7..e83b828581a 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -462,6 +462,14 @@ void Window::SetBackgroundColor(const std::string& color_name) { window_->SetBackgroundColor(color_name); } +void Window::SetHasShadow(bool has_shadow) { + window_->SetHasShadow(has_shadow); +} + +bool Window::HasShadow() { + return window_->HasShadow(); +} + void Window::FocusOnWebView() { window_->FocusOnWebView(); } @@ -671,6 +679,8 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("setKiosk", &Window::SetKiosk) .SetMethod("isKiosk", &Window::IsKiosk) .SetMethod("setBackgroundColor", &Window::SetBackgroundColor) + .SetMethod("setHasShadow", &Window::SetHasShadow) + .SetMethod("hasShadow", &Window::HasShadow) .SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename) .SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename) .SetMethod("setDocumentEdited", &Window::SetDocumentEdited) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index d8e25965d89..e7d38a60e66 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -118,6 +118,8 @@ class Window : public mate::TrackableObject, void SetKiosk(bool kiosk); bool IsKiosk(); void SetBackgroundColor(const std::string& color_name); + void SetHasShadow(bool has_shadow); + bool HasShadow(); void FocusOnWebView(); void BlurWebView(); bool IsWebViewFocused(); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 1f1a98b0658..d14df92deb6 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -551,6 +551,13 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback, callback.Run(bitmap); } +void NativeWindow::SetHasShadow(bool has_shadow) { +} + +bool NativeWindow::HasShadow() { + return true; +} + SkColor NativeWindow::ParseHexColor(const std::string& name) { SkColor result = 0xFF000000; unsigned value = 0; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 0a3ce124bd1..c3615ccb183 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -135,6 +135,8 @@ class NativeWindow : public base::SupportsUserData, virtual void SetKiosk(bool kiosk) = 0; virtual bool IsKiosk() = 0; virtual void SetBackgroundColor(const std::string& color_name) = 0; + virtual void SetHasShadow(bool has_shadow); + virtual bool HasShadow(); virtual void SetRepresentedFilename(const std::string& filename); virtual std::string GetRepresentedFilename(); virtual void SetDocumentEdited(bool edited); diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index ef3ccb15021..595b6a2d340 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -58,6 +58,8 @@ class NativeWindowMac : public NativeWindow { void SetKiosk(bool kiosk) override; bool IsKiosk() override; void SetBackgroundColor(const std::string& color_name) override; + void SetHasShadow(bool has_shadow) override; + bool HasShadow() override; void SetRepresentedFilename(const std::string& filename) override; std::string GetRepresentedFilename() override; void SetDocumentEdited(bool edited) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 156017194ec..d7499e244a1 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -435,6 +435,12 @@ NativeWindowMac::NativeWindowMac( if (!has_frame()) [window_ setOpaque:NO]; + bool has_shadow = true; + options.Get(options::kHasShadow, &has_shadow); + if (!has_shadow) { + SetHasShadow(false); + } + // We will manage window's lifetime ourselves. [window_ setReleasedWhenClosed:NO]; @@ -714,6 +720,14 @@ void NativeWindowMac::SetBackgroundColor(const std::string& color_name) { [window_ setBackgroundColor:color]; } +void NativeWindowMac::SetHasShadow(bool has_shadow) { + [window_ setHasShadow:has_shadow]; +} + +bool NativeWindowMac::HasShadow() { + return [window_ hasShadow]; +} + void NativeWindowMac::SetRepresentedFilename(const std::string& filename) { [window_ setRepresentedFilename:base::SysUTF8ToNSString(filename)]; } diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 477fe6755fa..2349368fc1b 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -68,6 +68,9 @@ const char kStandardWindow[] = "standardWindow"; // Default browser window background color. const char kBackgroundColor[] = "backgroundColor"; +// Whether the window should have a shadow. +const char kHasShadow[] = "hasShadow"; + // The WebPreferences. const char kWebPreferences[] = "webPreferences"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 78de53b825f..7ebcedc8740 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -39,6 +39,7 @@ extern const char kType[]; extern const char kDisableAutoHideCursor[]; extern const char kStandardWindow[]; extern const char kBackgroundColor[]; +extern const char kHasShadow[]; extern const char kWebPreferences[]; // WebPreferences. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 0bb47f17087..7cd1818b317 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -76,6 +76,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `backgroundColor` String - Window's background color as Hexadecimal value, like `#66CD00` or `#FFF`. Default is `#000` (black) for Linux and Windows, `#FFF` for Mac (or clear if transparent). + * `hasShadow` Boolean - Whether window should have a shadow. This is only + implemented on OS X. * `darkTheme` Boolean - Forces using dark theme for the window, only works on some GTK+3 desktop environments. Default is `false`. * `transparent` Boolean - Makes the window [transparent](frameless-window.md). @@ -710,6 +712,17 @@ screen readers Sets a 16px overlay onto the current taskbar icon, usually used to convey some sort of application status or to passively notify the user. +### `win.setHasShadow(hasShadow)` _OS X_ + +* `hasShadow` (Boolean) + +Sets whether the window should have a shadow. On Windows and Linux does +nothing. + +### `win.hasShadow()` _OS X_ + +Returns whether the window has a shadow. On Windows and Linux always returns +`true`. ### `win.setThumbarButtons(buttons)` _Windows 7+_ From e071e4f310a11b6bb37f2f32044549626e547a31 Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Sat, 23 Jan 2016 01:20:18 +0100 Subject: [PATCH 032/688] doc updated --- docs/api/browser-window.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 0bb47f17087..4a2ea301662 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -74,8 +74,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `enableLargerThanScreen` Boolean - Enable the window to be resized larger than screen. Default is `false`. * `backgroundColor` String - Window's background color as Hexadecimal value, - like `#66CD00` or `#FFF`. Default is `#000` (black) for Linux and Windows, - `#FFF` for Mac (or clear if transparent). + like `#66CD00` or `#FFF` or `#80FFFFFF` (alpha is supported). Default is + `#000` (black) for Linux and Windows, `#FFF` for Mac (or clear if + transparent). * `darkTheme` Boolean - Forces using dark theme for the window, only works on some GTK+3 desktop environments. Default is `false`. * `transparent` Boolean - Makes the window [transparent](frameless-window.md). From 000af78d41fdf344d92e2c7bd01dc4fedd90f17f Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Sat, 23 Jan 2016 01:37:05 +0100 Subject: [PATCH 033/688] doc fix --- docs/api/browser-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 7cd1818b317..a639571d3db 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -77,7 +77,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. like `#66CD00` or `#FFF`. Default is `#000` (black) for Linux and Windows, `#FFF` for Mac (or clear if transparent). * `hasShadow` Boolean - Whether window should have a shadow. This is only - implemented on OS X. + implemented on OS X. Default is `true`. * `darkTheme` Boolean - Forces using dark theme for the window, only works on some GTK+3 desktop environments. Default is `false`. * `transparent` Boolean - Makes the window [transparent](frameless-window.md). From d938dd68b01c5753e4bc7665c583b539b28e68f8 Mon Sep 17 00:00:00 2001 From: Robo Date: Sat, 23 Jan 2016 09:32:21 +0530 Subject: [PATCH 034/688] wrap debugger for lazy initialization --- atom/browser/api/atom_api_debugger.cc | 40 ++++++++++++++++++++++++++- atom/browser/api/lib/web-contents.js | 11 ++++++-- atom/common/node_bindings.cc | 1 + 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_debugger.cc b/atom/browser/api/atom_api_debugger.cc index b40bb413427..eab60311f3d 100644 --- a/atom/browser/api/atom_api_debugger.cc +++ b/atom/browser/api/atom_api_debugger.cc @@ -6,12 +6,15 @@ #include +#include "atom/browser/atom_browser_main_parts.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/value_converter.h" +#include "atom/common/node_includes.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/web_contents.h" +#include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" using content::DevToolsAgentHost; @@ -20,6 +23,14 @@ namespace atom { namespace api { +namespace { + +// The wrapDebugger funtion which is implemented in JavaScript. +using WrapDebuggerCallback = base::Callback)>; +WrapDebuggerCallback g_wrap_debugger; + +} // namespace + Debugger::Debugger(content::WebContents* web_contents) : web_contents_(web_contents), previous_request_id_(0) { @@ -139,7 +150,9 @@ void Debugger::SendCommand(mate::Arguments* args) { mate::Handle Debugger::Create( v8::Isolate* isolate, content::WebContents* web_contents) { - return mate::CreateHandle(isolate, new Debugger(web_contents)); + auto handle = mate::CreateHandle(isolate, new Debugger(web_contents)); + g_wrap_debugger.Run(handle.ToV8()); + return handle; } // static @@ -152,6 +165,31 @@ void Debugger::BuildPrototype(v8::Isolate* isolate, .SetMethod("sendCommand", &Debugger::SendCommand); } +void ClearWrapDebugger() { + g_wrap_debugger.Reset(); +} + +void SetWrapDebugger(const WrapDebuggerCallback& callback) { + g_wrap_debugger = callback; + + // Cleanup the wrapper on exit. + atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback( + base::Bind(ClearWrapDebugger)); +} + } // namespace api } // namespace atom + +namespace { + +void Initialize(v8::Local exports, v8::Local unused, + v8::Local context, void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + mate::Dictionary dict(isolate, exports); + dict.SetMethod("_setWrapDebugger", &atom::api::SetWrapDebugger); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_debugger, Initialize); diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index b71ddf4cb9f..4f2e98a0708 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -8,6 +8,7 @@ const NavigationController = require('electron').NavigationController; const Menu = require('electron').Menu; const binding = process.atomBinding('web_contents'); +const debuggerBinding = process.atomBinding('debugger'); let slice = [].slice; let nextId = 0; @@ -70,9 +71,6 @@ let wrapWebContents = function(webContents) { var controller, method, name, ref1; webContents.__proto__ = EventEmitter.prototype; - // webContents.debugger is an EventEmitter. - webContents.debugger.__proto__ = EventEmitter.prototype; - // Every remote callback from renderer process would add a listenter to the // render-view-deleted event, so ignore the listenters warning. webContents.setMaxListeners(0); @@ -219,7 +217,14 @@ let wrapWebContents = function(webContents) { }; }; +// Wrapper for native class. +let wrapDebugger = function(webContentsDebugger) { + // debugger is an EventEmitter. + webContentsDebugger.__proto__ = EventEmitter.prototype; +}; + binding._setWrapWebContents(wrapWebContents); +debuggerBinding._setWrapDebugger(wrapDebugger); module.exports.create = function(options) { if (options == null) { diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index b1cb84eead9..69e7906ffbb 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -35,6 +35,7 @@ REFERENCE_MODULE(atom_browser_app); REFERENCE_MODULE(atom_browser_auto_updater); 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_download_item); REFERENCE_MODULE(atom_browser_menu); From 85df3157c73b54c9c430b8cbe1ee132ec3ce2267 Mon Sep 17 00:00:00 2001 From: Takahito Yamatoya Date: Sat, 23 Jan 2016 20:03:10 +0900 Subject: [PATCH 035/688] Add Japanes translated docs. --- docs-translations/jp/api/dialog.md | 88 ++++++++++++ docs-translations/jp/api/menu-item.md | 50 +++++++ docs-translations/jp/api/tray.md | 199 ++++++++++++++++++++++++++ 3 files changed, 337 insertions(+) create mode 100644 docs-translations/jp/api/dialog.md create mode 100644 docs-translations/jp/api/menu-item.md create mode 100644 docs-translations/jp/api/tray.md diff --git a/docs-translations/jp/api/dialog.md b/docs-translations/jp/api/dialog.md new file mode 100644 index 00000000000..c01fef3fa33 --- /dev/null +++ b/docs-translations/jp/api/dialog.md @@ -0,0 +1,88 @@ +# dialog + +`dialog`モジュールは、ファイルやアラートを開くようなネイティブシステムダイアログを表示するためのAPIを提供します。そのため、ネイティブアプリケーションのようにウェブアプリケーションに同じユーザー体験を提供できます。 + +複数のファイルやディレクトリを選択するためのダイアログを表示する例です: + +```javascript +var win = ...; // BrowserWindow in which to show the dialog +const dialog = require('electron').dialog; +console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]})); +``` + +**Note for OS X**: シートとしてダイアログを表示したい場合、唯一しなければならないことは、`browserWindow`パラメーターを参照する`BrowserWindow`を提供することです。 + +## メソッド + +`dialog`モジュールは次のメソッドを持っています: + +### `dialog.showOpenDialog([browserWindow, ]options[, callback])` + +* `browserWindow` BrowserWindow (オプション) +* `options` Object + * `title` String + * `defaultPath` String + * `filters` Array + * `properties` Array - ダイアログが使うべき機能を含め、`openFile`と`openDirectory`、`multiSelections`、`createDirectory`を含められます。 +* `callback` Function (オプション) + +成功したら、このメソッドはユーザーが選択したファイルパスの配列を返し、さうでなければ`undefined`を返します。 + +ユーザーが選択できる種類を制限したいときに、`filters`で表示したり選択できるファイル種別の配列を指定します。 + +```javascript +{ + filters: [ + { name: 'Images', extensions: ['jpg', 'png', 'gif'] }, + { name: 'Movies', extensions: ['mkv', 'avi', 'mp4'] }, + { name: 'Custom File Type', extensions: ['as'] }, + { name: 'All Files', extensions: ['*'] } + ] +} +``` + +`extensions`配列は、ワイルドカードやドットなしで拡張子を指定すべきです(例えば、`'png'`は良いですが、`'.png'` と `'*.png'`はダメです)。すべてのファイルを表示するために、`'*'`ワイルドカードを使用します(それいがいのワイルドカードはサポートしていません)。 + +`callback`を通すと、APIは非同期に読み出し、結果は`callback(filenames)`経由で通します。 + +**Note:** WindowsとLinuxでは、オープンダイアログがファイル選択とディレクトリ選択の両方を選択することはできません。プラットフォーム上で `properties`に`['openFile', 'openDirectory']`を設定すると、ディレクトリ選択が表示されます。 + +### `dialog.showSaveDialog([browserWindow, ]options[, callback])` + +* `browserWindow` BrowserWindow (オプション) +* `options` Object + * `title` String + * `defaultPath` String + * `filters` Array +* `callback` Function (オプション) + +成功すると、このメソッドはユーザーが選択したファイルのパスが返され、そうでなければ`undefined`が返されます。 + +`filters`が表示できるファイル種別配列を指定します。例えば、`dialog.showOpenDialog`を参照してください。 + +`callback`を通すと、APIは非同期でコールされ、結果は`callback(filename)`経由で通します。 + +### `dialog.showMessageBox([browserWindow, ]options[, callback])` + +* `browserWindow` BrowserWindow (オプション) +* `options` Object + * `type` String - `"none"`と `"info"`、 `"error"`、 `"question"`、`"warning"`を設定できます。Windowsでは、 "icon"オプションを使用してアイコンを設定しない限り、"question"は"info"として同じアイコンを表示します。 + * `buttons` Array - ボタン用のテキスト配列。 + * `defaultId` Integer - メッセージボックスを開くとき、既定で選択されるボタン配列でのボタンインデックスです + * `title` String - メッセージボックスのタイトルで、いくつかのプラットフォームでは表示されません。 + * `message` String - メッセージボックスのコンテンツ。 + * `detail` String - メッセージの外部情報 + * `icon` [NativeImage](native-image.md) + * `cancelId` Integer - ダイアログのボタンをクリックする代わりにユーザーがダイアログをキャンセルしたときに返す値です。既定では、ラベルの "cancel"や"no"を持つボタンのインデックスまたは、そのようなボタンが無ければ0を返します。OS XやWindowsでは、 すでに指定されているかどうかは関係なく、"Cancel"ボタンのインデックスはいつでも `cancelId`が使われます。 + * `noLink` Boolean - Windowsでは、Electronは、 ("Cancel" または "Yes"のような)共通ボタンである`buttons`の一つを見つけようとし、ダイアログ内のコマンドリンクとして表示します。この挙動が気に入らない場合は、 `noLink` を `true`に設定できます。 +* `callback` Function + +メッセージボックスを表示し、メッセージボックスが閉じるまでプロセスをブロックします。クリックされたボタンのインデックスを返します。 + +`callback`が通されると、APIは非同期にコールし、結果は`callback(response)`経由で通されます。 + +### `dialog.showErrorBox(title, content)` + +エラーメッセージを表示するモデルダイアログを表示します。 + + `app`モジュールが`ready`イベントを出力する前に、このAPIは安全にコールできます。スタートアップの早い段階でエラーを報告するのに通常は使われます。Linuxで、アプリの`ready`イベントの前にコールすると、メッセージは標準エラーに出力され、GUIダイアログは表示されません。 diff --git a/docs-translations/jp/api/menu-item.md b/docs-translations/jp/api/menu-item.md new file mode 100644 index 00000000000..9e28582e622 --- /dev/null +++ b/docs-translations/jp/api/menu-item.md @@ -0,0 +1,50 @@ +# MenuItem + +`menu-item`モジュールは、アプリケーションまたはコンテキスト[`メニュー`](menu.md)に項目を追加することができます。 + +具体例は、 [`menu`](menu.md) を見てください。 + +## クラス: MenuItem + +次のメソッドで、新しい`MenuItem`を作成します。 + +### new MenuItem(options) + +* `options` Object + * `click` Function - メニューアイテムがクリックされたとき、`click(menuItem, browserWindow)`がコールされます。 + * `role` String - 指定されたとき、メニューアイテムの動作が定義され、`click`プロパティは無視されます。 + * `type` String - `normal`と `separator`、`submenu`、`checkbox`、`radio`を指定できます。 + * `label` String + * `sublabel` String + * `accelerator` [Accelerator](accelerator.md) + * `icon` [NativeImage](native-image.md) + * `enabled` Boolean + * `visible` Boolean + * `checked` Boolean + * `submenu` Menu - メニューアイテムを省略できる`type: 'submenu'`を指定したとき、`submenu`種類のメニューアイテムを指定すべきです。値が`Menu`でないとき、`Menu.buildFromTemplate`を使用して自動的に変換されます。 + * `id` String - 1つのメニュー内で一意です。定義されていたら、position属性によってアイテムへの参照として使用できます。 + * `position` String - このフィールドは、指定されたメニュー内の特定の位置を細かく定義できます。 + +メニューアイテムを作成するとき、適切な動作がある場合は、メニューでベストな自然な体験を提供するために、手動で実装する代わりに`role`を指定することを推奨します。 + +`role` プロパティは次の値を持ちます: + +* `undo` +* `redo` +* `cut` +* `copy` +* `paste` +* `selectall` +* `minimize` - 現在のウィンドウの最小化 +* `close` - 現在のウィンドウを閉じます + +OS Xでは、`role`は次の追加の値を取れます: + +* `about` - `orderFrontStandardAboutPanel`動作に紐づけられます +* `hide` - `hide`動作に紐づけられます +* `hideothers` - `hideOtherApplications`動作に紐づけられます +* `unhide` - `unhideAllApplications`動作に紐づけられます +* `front` - `arrangeInFront`動作に紐づけられます +* `window` - サブメニューは "Window"メニューです。 +* `help` - サブメニューは "Help"メニューです。 +* `services` - サブメニューは "Services"メニューです。 diff --git a/docs-translations/jp/api/tray.md b/docs-translations/jp/api/tray.md new file mode 100644 index 00000000000..5c76e740530 --- /dev/null +++ b/docs-translations/jp/api/tray.md @@ -0,0 +1,199 @@ +# Tray + +`Tray`は、オペレーティングシステムの通知エリアでアイコンで表示され、通常コンテキストメニューが付随します。 + +```javascript +const electron = require('electron'); +const app = electron.app; +const Menu = electron.Menu; +const Tray = electron.Tray; + +var appIcon = null; +app.on('ready', function(){ + appIcon = new Tray('/path/to/my/icon'); + var contextMenu = Menu.buildFromTemplate([ + { label: 'Item1', type: 'radio' }, + { label: 'Item2', type: 'radio' }, + { label: 'Item3', type: 'radio', checked: true }, + { label: 'Item4', type: 'radio' } + ]); + appIcon.setToolTip('This is my application.'); + appIcon.setContextMenu(contextMenu); +}); + +``` + +__プラットフォームの制限:__ + +* Linuxでは、サポートしている場合アプリインディケーターが使われ、サポートされていなければ代わりに`GtkStatusIcon`が使われます。 +* アプリインディケーターを持っているLinuxディストリビューションでは、トレイアイコンを動作させるために`libappindicator1`をインストールする必要があります。 +* コンテキストメニューがあるときは、インディケーターのみが表示されます。 +* アプリインディケーターがLinuxで使われると、`click`イベントは無視されます。 + +すべてのプラットフォームで正確に同じ挙動を維持したい場合は、`click`イベントに依存せず、常にトレイアイコンにコンテキストメニューを付随させるようにします。 + +## クラス: Tray + +`Tray`は[EventEmitter][event-emitter]です。 + +### `new Tray(image)` + +* `image` [NativeImage](native-image.md) + +`image`で新しいトレイアイコンを作成します。 + +## イベント + +`Tray`モジュールは次のイベントを出力します。 + +**Note:** いくつかのイベントは、特定のオペレーティングシステム向けに提供され、そのようにラベルで表示します。 + +### イベント: 'click' + +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean + * `metaKey` Boolean +* `bounds` Object - トレイアイコンのバウンド + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer + +トレイアイコンがクリックされたときに出力されます。 + +__Note:__ `バウンド` 再生はOS XとWindoesのみで実装されています。 + +### イベント: 'right-click' _OS X_ _Windows_ + +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean + * `metaKey` Boolean +* `bounds` Object - トレイアイコンのバウンド + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer + +トレイアイコンが右クリックされると出力されます。 + +### イベント: 'double-click' _OS X_ _Windows_ + +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean + * `metaKey` Boolean +* `bounds` Object - トレイアイコンのバウンド + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer + +トレイアイコンがダブルクリックされたら出力されます。 + +### イベント: 'balloon-show' _Windows_ + +トレイバルーンを表示したときに出力されます。 + +### イベント: 'balloon-click' _Windows_ + +トレイバルーンがクリックされたときに出力されます。 + +### イベント: 'balloon-closed' _Windows_ + +タイムアウトもしくはユーザーの操作で閉じて、トレイバルーンがクロースされたときに出力されます。 + +### イベント: 'drop' _OS X_ + +トレイアイコンでアイテムがドラグアンドドロップされたときに出力されます。 + +### イベント: 'drop-files' _OS X_ + +* `event` +* `files` Array - ドロップされたアイテムのフルパス + +トレイアイコンでファイルがドロップされたときに出力されます。 + +### イベント: 'drag-enter' _OS X_ + +トレイアイコンにドラッグ操作が入ったときに出力されます。 + +### イベント: 'drag-leave' _OS X_ + +トレイアイコンででドラッグ操作が行われたときに出力されます。 + +### イベント: 'drag-end' _OS X_ + +トレイ上でドラッグ操作が終了したか、ほかの場所で終了したときに出力されます。 + +## Methods + +`Tray`モジュールは次のメソッドを持ちます。 + +**Note:** いくつかのメソッドは、特定のオペレーティングシステム向けに提供され、そのようにラベルで表示します。 + +### `Tray.destroy()` + +ただちにトレイアイコンを終了します。 + +### `Tray.setImage(image)` + +* `image` [NativeImage](native-image.md) + +トレイアイコンの`image`を設定します。 + +### `Tray.setPressedImage(image)` _OS X_ + +* `image` [NativeImage](native-image.md) + +OS Xで押されたときにトレイアイコンの`image`を設定します。 + +### `Tray.setToolTip(toolTip)` + +* `toolTip` String + +トレイアイコン用のホバーテキストを設定します。 + +### `Tray.setTitle(title)` _OS X_ + +* `title` String + +ステータスバーで、トレイアイコンのわきに表示するタイトルを設定します。 + +### `Tray.setHighlightMode(highlight)` _OS X_ + +* `highlight` Boolean + +トレイアイコンがクリックされた時、トレイアイコンの背景をハイライト(青色)するかどうかを設定します。既定ではTrueです。 + +### `Tray.displayBalloon(options)` _Windows_ + +* `options` Object + * `icon` [NativeImage](native-image.md) + * `title` String + * `content` String + +トレイバルーンを表示します。 + +### `Tray.popUpContextMenu([menu, position])` _OS X_ _Windows_ + +* `menu` Menu (optional) +* `position` Object (optional) - ポップアップ位置 + * `x` Integer + * `y` Integer + +トレイアイコンのコンテキストメニューをポップアップします。`menu`が渡されたとき、`menu`はトレイコンテキストメニューの代わりに表示されます。 + +`position`はWindowsのみで提供され、既定では(0, 0) です。 + +### `Tray.setContextMenu(menu)` + +* `menu` Menu + +アイコン用のコンテキストメニューを設定します。 + +[event-emitter]: http://nodejs.org/api/events.html#events_class_events_eventemitter From 09966aec38e8920bc7c4d759fbeda128fa515582 Mon Sep 17 00:00:00 2001 From: ragingwind Date: Sat, 23 Jan 2016 22:59:05 +0900 Subject: [PATCH 036/688] Update name of paramter for consistency --- atom/browser/browser_mac.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 8b1dd31f355..50040c9d8da 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -48,8 +48,8 @@ int Browser::DockBounce(BounceType type) { requestUserAttention:(NSRequestUserAttentionType)type]; } -void Browser::DockCancelBounce(int rid) { - [[AtomApplication sharedApplication] cancelUserAttentionRequest:rid]; +void Browser::DockCancelBounce(int request_id) { + [[AtomApplication sharedApplication] cancelUserAttentionRequest:request_id]; } void Browser::DockSetBadgeText(const std::string& label) { From 7229d2462a7df262c5c3f54e88c4b5472daffa18 Mon Sep 17 00:00:00 2001 From: ragingwind Date: Sun, 24 Jan 2016 08:30:14 +0900 Subject: [PATCH 037/688] Add app.dock.setIcon to change icon of dock --- atom/browser/api/atom_api_app.cc | 3 +++ atom/browser/api/lib/app.js | 3 ++- atom/browser/browser.h | 7 +++++++ atom/browser/browser_mac.mm | 5 +++++ docs/api/app.md | 6 ++++++ 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index b0c87064ea6..394014e8b27 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -18,6 +18,7 @@ #include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" +#include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/node_includes.h" #include "atom/common/options_switches.h" #include "base/command_line.h" @@ -34,6 +35,7 @@ #include "native_mate/object_template_builder.h" #include "net/ssl/ssl_cert_request_info.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/image/image.h" #if defined(OS_WIN) #include "base/strings/utf_string_conversions.h" @@ -448,6 +450,7 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("dockHide", base::Bind(&Browser::DockHide, browser)); dict.SetMethod("dockShow", base::Bind(&Browser::DockShow, browser)); dict.SetMethod("dockSetMenu", &DockSetMenu); + dict.SetMethod("dockSetIcon", base::Bind(&Browser::DockSetIcon, browser)); #endif } diff --git a/atom/browser/api/lib/app.js b/atom/browser/api/lib/app.js index b99c069b558..f7c9cd97583 100644 --- a/atom/browser/api/lib/app.js +++ b/atom/browser/api/lib/app.js @@ -37,7 +37,8 @@ if (process.platform === 'darwin') { getBadge: bindings.dockGetBadgeText, hide: bindings.dockHide, show: bindings.dockShow, - setMenu: bindings.dockSetMenu + setMenu: bindings.dockSetMenu, + setIcon: bindings.dockSetIcon }; } diff --git a/atom/browser/browser.h b/atom/browser/browser.h index e46624b158d..0b55fb600cf 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -27,6 +27,10 @@ namespace ui { class MenuModel; } +namespace gfx { +class Image; +} + namespace atom { class LoginHandler; @@ -91,6 +95,9 @@ class Browser : public WindowListObserver { // Set docks' menu. void DockSetMenu(ui::MenuModel* model); + + // Set docks' icon. + void DockSetIcon(const gfx::Image& image); #endif // defined(OS_MACOSX) #if defined(OS_WIN) diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 8b1dd31f355..e3c4eaf705e 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -102,4 +102,9 @@ void Browser::DockSetMenu(ui::MenuModel* model) { [delegate setApplicationDockMenu:model]; } +void Browser::DockSetIcon(const gfx::Image& image) { + [[NSApplication sharedApplication] + setApplicationIconImage:image.AsNSImage()]; +} + } // namespace atom diff --git a/docs/api/app.md b/docs/api/app.md index 13cb66e5f5a..a26defb447a 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -512,6 +512,12 @@ Shows the dock icon. Sets the application's [dock menu][dock-menu]. +### `app.dock.setIcon(image)` _OS X_ + +* `image` [NativeImage](native-image.md) + +Sets the `image` associated with this dock icon. + [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx From d6f2b7c9829f88c59a5c8f59052dea4251feecfb Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Sun, 24 Jan 2016 02:33:45 +0900 Subject: [PATCH 038/688] :memo: Update as upstream * Update as upstream * Fix typos * Improve grammar [ci skip] --- README-ko.md | 3 +- docs-translations/ko-KR/api/app.md | 26 ++-- docs-translations/ko-KR/api/browser-window.md | 147 ++++++++++++++---- .../ko-KR/api/environment-variables.md | 8 +- .../ko-KR/api/frameless-window.md | 2 +- docs-translations/ko-KR/api/menu.md | 14 +- docs-translations/ko-KR/api/web-contents.md | 4 +- docs-translations/ko-KR/api/web-view-tag.md | 23 +++ 8 files changed, 176 insertions(+), 51 deletions(-) diff --git a/README-ko.md b/README-ko.md index a2db99929c0..664075dd481 100644 --- a/README-ko.md +++ b/README-ko.md @@ -70,7 +70,8 @@ API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝 - Atom 포럼의 [`electron`](http://discuss.atom.io/c/electron) 카테고리 - Freenode 채팅의 `#atom-shell` 채널 - Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널 -- [`electron-br`](https://electron-br.slack.com) *(브라질 포르투갈어)* +- [`electron-br`](https://electron-br.slack.com) *(브라질 포르투갈어)* 커뮤니티 +- [`electron-kr`](http://www.meetup.com/electron-kr/) *(한국어)* 커뮤니티 [awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에 커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기 diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 83921b3e39e..5044a6de3e7 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -2,7 +2,7 @@ `app` 모듈은 어플리케이션의 생명주기 제어를 책임집니다. -밑의 예제는 마지막 윈도우 창이 종료되었을 때, 어플리케이션을 종료시키는 예제입니다: +밑의 예제는 마지막 윈도우가 종료되었을 때, 어플리케이션을 종료시키는 예제입니다: ```javascript const app = require('electron').app; @@ -32,15 +32,15 @@ Electron이 초기화를 끝냈을 때 발생하는 이벤트입니다. ### Event: 'window-all-closed' -모든 윈도우 창이 종료되었을 때 발생하는 이벤트입니다. +모든 윈도우가 종료되었을 때 발생하는 이벤트입니다. 이 이벤트는 어플리케이션이 완전히 종료되지 않았을 때만 발생합니다. 만약 사용자가 `Cmd + Q`를 입력했거나 개발자가 `app.quit()`를 호출했다면, -Electron은 먼저 모든 윈도우 창의 종료를 시도하고 `will-quit` 이벤트를 발생시킵니다. +Electron은 먼저 모든 윈도우의 종료를 시도하고 `will-quit` 이벤트를 발생시킵니다. 그리고 `will-quit` 이벤트가 발생했을 땐 `window-all-closed` 이벤트가 발생하지 않습니다. -**역주:** 이 이벤트는 말 그대로 현재 어플리케이션에서 윈도우 창만 완전히 종료됬을 때 +**역주:** 이 이벤트는 말 그대로 현재 어플리케이션에서 윈도우만 완전히 종료됬을 때 발생하는 이벤트 입니다. 따라서 어플리케이션을 완전히 종료하려면 이 이벤트에서 `app.quit()`를 호출해 주어야 합니다. @@ -50,7 +50,7 @@ Returns: * `event` Event -어플리케이션 윈도우 창들이 닫히기 시작할 때 발생하는 이벤트입니다. +어플리케이션 윈도우들이 닫히기 시작할 때 발생하는 이벤트입니다. `event.preventDefault()` 호출은 이벤트의 기본 동작을 방지하기 때문에 이를 통해 어플리케이션의 종료를 방지할 수 있습니다. @@ -60,7 +60,7 @@ Returns: * `event` Event -모든 윈도우 창들이 종료되고 어플리케이션이 종료되기 시작할 때 발생하는 이벤트 입니다. +모든 윈도우들이 종료되고 어플리케이션이 종료되기 시작할 때 발생하는 이벤트 입니다. `event.preventDefault()` 호출을 통해 어플리케이션의 종료를 방지할 수 있습니다. `will-quit` 와 `window-all-closed` 이벤트의 차이점을 확인하려면 `window-all-close` @@ -244,12 +244,12 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입 ### `app.quit()` -모든 윈도우 창 종료를 시도합니다. `before-quit` 이벤트가 먼저 발생합니다. -모든 윈도우 창이 성공적으로 종료되면 `will-quit` 이벤트가 발생하고 기본 동작에 따라 +모든 윈도우 종료를 시도합니다. `before-quit` 이벤트가 먼저 발생합니다. +모든 윈도우가 성공적으로 종료되면 `will-quit` 이벤트가 발생하고 기본 동작에 따라 어플리케이션이 종료됩니다. 이 함수는 모든 `beforeunload`와 `unload` 이벤트 핸들러가 제대로 실행됨을 보장합니다. -`beforeunload` 이벤트 핸들러에서 `false`를 반환했을 때 윈도우 창 종료가 취소 될 수 +`beforeunload` 이벤트 핸들러에서 `false`를 반환했을 때 윈도우 종료가 취소 될 수 있습니다. ### `app.exit(exitCode)` @@ -258,7 +258,7 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입 `exitCode`와 함께 어플리케이션을 즉시 종료합니다. -모든 윈도우 창은 사용자의 동의 여부에 상관없이 즉시 종료되며 `before-quit` 이벤트와 +모든 윈도우는 사용자의 동의 여부에 상관없이 즉시 종료되며 `before-quit` 이벤트와 `will-quit` 이벤트가 발생하지 않습니다. ### `app.getAppPath()` @@ -386,7 +386,7 @@ Windows에서 사용할 수 있는 JumpList의 [Tasks][tasks] 카테고리에 `t `callback`은 주 인스턴스가 생성된 이후 또 다른 인스턴스가 생성됐을 때 `callback(argv, workingDirectory)` 형식으로 호출됩니다. `argv`는 두 번째 인스턴스의 명령줄 인수이며 `workingDirectory`는 현재 작업중인 디렉터리입니다. 보통 대부분의 -어플리케이션은 이러한 콜백이 호출될 때 주 윈도우 창을 포커스하고 최소화되어있으면 창 +어플리케이션은 이러한 콜백이 호출될 때 주 윈도우를 포커스하고 최소화되어있으면 창 복구를 실행합니다. `callback`은 `app`의 `ready` 이벤트가 발생한 후 실행됨을 보장합니다. @@ -403,7 +403,7 @@ OS X에선 사용자가 Finder에서 어플리케이션의 두 번째 인스턴 중복 실행을 방지하는 것이 좋습니다. 다음 예제는 두 번째 인스턴스가 생성되었을 때 중복된 인스턴스를 종료하고 주 어플리케이션 -인스턴스의 윈도우 창을 활성화 시키는 예제입니다: +인스턴스의 윈도우를 활성화 시키는 예제입니다: ```javascript var myWindow = null; @@ -422,7 +422,7 @@ if (shouldQuit) { return; } -// 윈도우 창을 생성하고 각종 리소스를 로드하고 작업합니다. +// 윈도우를 생성하고 각종 리소스를 로드하고 작업합니다. app.on('ready', function() { }); ``` diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index e5d5fbafe43..96d2239d20e 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -1,8 +1,8 @@ # BrowserWindow -`BrowserWindow` 클래스는 브라우저 창(윈도우 창)을 만드는 역할을 담당합니다. +`BrowserWindow` 클래스는 브라우저 창(윈도우)을 만드는 역할을 담당합니다. -다음 예제는 윈도우 창을 생성합니다: +다음 예제는 윈도우를 생성합니다: ```javascript // 메인 프로세스에서 @@ -28,37 +28,45 @@ win.show(); `BrowserWindow`는 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)를 상속받은 클래스 입니다. -`BrowserWindow`는 `options`를 통해 네이티브 속성을 포함한 새로운 윈도우 창을 -생성합니다. +`BrowserWindow`는 `options`를 통해 네이티브 속성을 포함한 새로운 윈도우를 생성합니다. ### `new BrowserWindow([options])` `options` 객체 (optional), 사용할 수 있는 속성들: -* `width` Integer - 윈도우 창의 가로 너비. 기본값은 `800`입니다. -* `height` Integer - 윈도우 창의 세로 높이. 기본값은 `600`입니다. +* `width` Integer - 윈도우의 가로 너비. 기본값은 `800`입니다. +* `height` Integer - 윈도우의 세로 높이. 기본값은 `600`입니다. * `x` Integer - 화면을 기준으로 창 좌측을 오프셋 한 위치. 기본값은 `화면중앙`입니다. * `y` Integer - 화면을 기준으로 창 상단을 오프셋 한 위치. 기본값은 `화면중앙`입니다. * `useContentSize` Boolean - `width`와 `height`를 웹 페이지의 크기로 사용합니다. 이 속성을 사용하면 웹 페이지의 크기에 윈도우 프레임 크기가 추가되므로 실제 창은 조금 더 커질 수 있습니다. 기본값은 `false`입니다. -* `center` Boolean - 윈도우 창을 화면 정 중앙에 위치시킵니다. -* `minWidth` Integer - 윈도우 창의 최소 가로 너비. 기본값은 `0`입니다. -* `minHeight` Integer - 윈도우 창의 최소 세로 높이. 기본값은 `0`입니다. -* `maxWidth` Integer - 윈도우 창의 최대 가로 너비. 기본값은 `제한없음`입니다. -* `maxHeight` Integer - 윈도우 창의 최대 세로 높이. 기본값은 `제한없음`입니다. -* `resizable` Boolean - 윈도우 창의 크기를 재조정 할 수 있는지 여부. 기본값은 `true` +* `center` Boolean - 윈도우를 화면 정 중앙에 위치시킵니다. +* `minWidth` Integer - 윈도우의 최소 가로 너비. 기본값은 `0`입니다. +* `minHeight` Integer - 윈도우의 최소 세로 높이. 기본값은 `0`입니다. +* `maxWidth` Integer - 윈도우의 최대 가로 너비. 기본값은 `제한없음`입니다. +* `maxHeight` Integer - 윈도우의 최대 세로 높이. 기본값은 `제한없음`입니다. +* `resizable` Boolean - 윈도우의 크기를 재조정 할 수 있는지 여부. 기본값은 `true` 입니다. -* `movable` Boolean - 윈도우를 이동시킬 수 있는지 여부. 이 기능은 현재 OSX에만 - 구현되어 있습니다. 기본값은 `true` -* `alwaysOnTop` Boolean - 윈도우 창이 언제나 다른 창들 위에 유지되는지 여부. +* `movable` Boolean - 윈도우를 이동시킬 수 있는지 여부. Linux에선 구현되어있지 + 않습니다. 기본값은 `true` 입니다. +* `minimizable` Boolean - 윈도우를 최소화시킬 수 있는지 여부. Linux에선 구현되어있지 + 않습니다. 기본값은 `true` 입니다. +* `maximizable` Boolean - 윈도우를 최대화시킬 수 있는지 여부. Linux에선 구현되어있지 + 않습니다. 기본값은 `true` 입니다. +* `closable` Boolean - 윈도우를 닫을 수 있는지 여부. Linux에선 구현되어있지 않습니다. + 기본값은 `true` 입니다. +* `alwaysOnTop` Boolean - 윈도우이 언제나 다른 창들 위에 유지되는지 여부. 기본값은 `false`입니다. -* `fullscreen` Boolean - 윈도우 창의 전체화면 활성화 여부. 기본값은 `false` 입니다. - `false`로 지정했을 경우 OS X에선 전체화면 버튼이 숨겨지거나 비활성화됩니다. +* `fullscreen` Boolean - 윈도우의 전체화면 활성화 여부. 이 속성을 명시적으로 + `false`로 지정했을 경우, OS X에선 전체화면 버튼이 숨겨지거나 비활성화되고, + Windows에선 최대화 버튼이 비활성화됩니다. 기본값은 `false` 입니다. +* `fullscreenable` Boolean - OS X의 최대화/줌 버튼이 전체화면 모드 또는 윈도우 + 최대화를 토글할 수 있게 할지 여부입니다. 기본값은 `true` 입니다. * `skipTaskbar` Boolean - 작업표시줄 어플리케이션 아이콘 표시 스킵 여부. 기본값은 `false`입니다. * `kiosk` Boolean - Kiosk(키오스크) 모드. 기본값은 `false`입니다. -* `title` String - 기본 윈도우 창 제목. 기본값은 `"Electron"`입니다. +* `title` String - 기본 윈도우 제목. 기본값은 `"Electron"`입니다. * `icon` [NativeImage](native-image.md) - 윈도우 아이콘, 생략하면 실행 파일의 아이콘이 대신 사용됩니다. * `show` Boolean - 윈도우가 생성되면 보여줄지 여부. 기본값은 `true`입니다. @@ -70,16 +78,18 @@ win.show(); `false`입니다. * `autoHideMenuBar` Boolean - `Alt`를 누르지 않는 한 어플리케이션 메뉴바를 숨길지 여부. 기본값은 `false`입니다. -* `enableLargerThanScreen` Boolean - 윈도우 창 크기가 화면 크기보다 크게 재조정 될 +* `enableLargerThanScreen` Boolean - 윈도우 크기가 화면 크기보다 크게 재조정 될 수 있는지 여부. 기본값은 `false`입니다. -* `backgroundColor` String - 16진수로 표현된 윈도우의 배경 색. `#66CD00` 또는 - `#FFF`가 사용될 수 있습니다. 이 속성은 Linux와 Windows에만 구현되어 있습니다. - 기본값은 `#000`(검정)입니다. +* `backgroundColor` String - `#66CD00` 와 `#FFF` 같이 16진수로 표현된 윈도우의 + 배경 색. 기본값은 Linux와 Windows에선 `#000` (검정)이며, Mac에선 `#FFF` (또는, + 만약 transparent(투명)일 경우 clear(색 없음)로 설정) +* `hasShadow` Boolean - 윈도우가 그림자를 가질지 여부를 지정합니다. 이 속성은 + OS X에서만 구현되어 있습니다. 기본값은 `true`입니다. * `darkTheme` Boolean - 설정에 상관 없이 무조건 어두운 윈도우 테마를 사용합니다. 몇몇 GTK+3 데스크톱 환경에서만 작동합니다. 기본값은 `false`입니다. -* `transparent` Boolean - 윈도우 창을 [투명화](frameless-window.md)합니다. 기본값은 +* `transparent` Boolean - 윈도우를 [투명화](frameless-window.md)합니다. 기본값은 `false`입니다. -* `type` String - 특정 플랫폼에만 적용되는 윈도우 창의 종류를 지정합니다. 기본값은 +* `type` String - 특정 플랫폼에만 적용되는 윈도우의 종류를 지정합니다. 기본값은 일반 윈도우 입니다. 사용할 수 있는 창의 종류는 아래를 참고하세요. * `standardWindow` Boolean - OS X의 표준 윈도우를 텍스쳐 윈도우 대신 사용합니다. 기본 값은 `true`입니다. @@ -155,6 +165,15 @@ win.show(); * `blinkFeatures` String - `CSSVariables,KeyboardEventKey`같은 `,`로 구분된 기능 문자열들의 리스트입니다. 지원하는 전체 기능 문자열들은 [setFeatureEnabledFromString][blink-feature-string] 함수에서 찾을 수 있습니다. +* `defaultFontFamily` Object - font-family의 기본 폰트를 지정합니다. + * `standard` String - 기본값 `Times New Roman`. + * `serif` String - 기본값 `Times New Roman`. + * `sansSerif` String - 기본값 `Arial`. + * `monospace` String - 기본값 `Courier New`. +* `defaultFontSize` Integer - 기본값 `16`. +* `defaultMonospaceFontSize` Integer - 기본값 `13`. +* `minimumFontSize` Integer - 기본값 `0`. +* `defaultEncoding` String - 기본값 `ISO-8859-1`. ## Events @@ -203,7 +222,7 @@ window.onbeforeunload = function(e) { ### Event: 'closed' 윈도우 종료가 완료된 경우 발생하는 이벤트입니다. 이 이벤트가 발생했을 경우 반드시 -윈도우 창의 레퍼런스가 더 이상 사용되지 않도록 제거해야 합니다. +윈도우의 레퍼런스가 더 이상 사용되지 않도록 제거해야 합니다. ### Event: 'unresponsive' @@ -507,11 +526,71 @@ var win = new BrowserWindow({ width: 800, height: 600 }); * `resizable` Boolean -윈도우의 크기가 사용자에 의해 재조정될 수 있는지를 지정합니다. +사용자에 의해 윈도우의 크기가 재조정될 수 있는지를 지정합니다. ### `win.isResizable()` -윈도우의 크기가 사용자에 의해 재조정될 수 있는지 여부를 반환합니다. +사용자에 의해 윈도우의 크기가 재조정될 수 있는지 여부를 반환합니다. + +### `win.setMovable(movable)` _OS X_ _Windows_ + +* `movable` Boolean + +사용자에 의해 윈도우를 이동시킬 수 있는지 여부를 지정합니다. Linux에선 아무 일도 +일어나지 않습니다. + +### `win.isMovable()` _OS X_ _Windows_ + +사용자에 의해 윈도우를 이동시킬 수 있는지 여부를 반환합니다. Linux에선 항상 `true`를 +반환합니다. + +### `win.setMinimizable(minimizable)` _OS X_ _Windows_ + +* `minimizable` Boolean + +사용자에 의해 윈도우를 최소화시킬 수 있는지 여부를 지정합니다. Linux에선 아무 일도 +일어나지 않습니다. + +### `win.isMinimizable()` _OS X_ _Windows_ + +사용자에 의해 윈도우를 최소화시킬 수 있는지 여부를 반환합니다. Linux에선 항상 `true`를 +반환합니다. + +### `win.setMaximizable(maximizable)` _OS X_ _Windows_ + +* `maximizable` Boolean + +사용자에 의해 윈도우를 최대화시킬 수 있는지 여부를 지정합니다. Linux에선 아무 일도 +일어나지 않습니다. + +### `win.isMaximizable()` _OS X_ _Windows_ + +사용자에 의해 윈도우를 최대화시킬 수 있는지 여부를 반환합니다. Linux에선 항상 `true`를 +반환합니다. + +### `win.setFullscreenable(fullscreenable)` _OS X_ + +* `fullscreenable` Boolean + +최대화/줌 버튼이 전체화면 모드 또는 윈도우 최대화를 토글할 수 있게 할지 여부를 +지정합니다. Windows와 Linux에선 아무 일도 일어나지 않습니다. + +### `win.isFullscreenable()` _OS X_ + +최대화/줌 버튼이 전체화면 모드 또는 윈도우 최대화를 토글할 수 있게 할지 여부를 +반환합니다. Windows와 Linux에선 항상 `true`를 반환합니다. + +### `win.setClosable(closable)` _OS X_ _Windows_ + +* `closable` Boolean + +사용자에 의해 윈도우가 수동적으로 닫힐 수 있는지 여부를 지정합니다. Linux에선 아무 일도 +일어나지 않습니다. + +### `win.isClosable()` _OS X_ _Windows_ + +사용자에 의해 윈도우가 수동적으로 닫힐 수 있는지 여부를 반환합니다. Linux에선 항상 +`true`를 반환합니다. ### `win.setAlwaysOnTop(flag)` @@ -689,9 +768,21 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 그리고 현재 작업표시줄 아이콘에 16px 크기의 오버레이를 지정합니다. 보통 이 기능은 어플리케이션의 여러 상태를 사용자에게 소극적으로 알리기 위한 방법으로 사용됩니다. +### `win.setHasShadow(hasShadow)` _OS X_ + +* `hasShadow` (Boolean) + +윈도우가 그림자를 가질지 여부를 지정합니다. Windows와 Linux에선 아무 일도 일어나지 +않습니다. + +### `win.hasShadow()` _OS X_ + +윈도우가 그림자를 가지고 있는지 여부를 반환합니다. Windows와 Linux에선 항상 `true`를 +반환합니다. + ### `win.setThumbarButtons(buttons)` _Windows 7+_ -`buttons` - `button` 객체의 배열: +`buttons` - `button` 객체의 배열 `button` 객체는 다음과 같은 속성을 가지고 있습니다: diff --git a/docs-translations/ko-KR/api/environment-variables.md b/docs-translations/ko-KR/api/environment-variables.md index 11d35069216..465548e003d 100644 --- a/docs-translations/ko-KR/api/environment-variables.md +++ b/docs-translations/ko-KR/api/environment-variables.md @@ -1,6 +1,7 @@ # 환경 변수 -Electron의 몇몇 동작은 명령 줄과 어플리케이션의 코드보다 먼저 초기화되어야 하므로 환경 변수에 의해 작동합니다. +Electron의 몇몇 동작은 명령 줄과 어플리케이션의 코드보다 먼저 초기화되어야 하므로 환경 +변수에 의해 작동합니다. POSIX 쉘의 예시입니다: @@ -24,6 +25,11 @@ Windows 콘솔의 예시입니다: Chrome의 내부 로그를 콘솔에 출력합니다. +## `ELECTRON_LOG_ASAR_READS` + +Electron이 ASAR 파일을 읽을 때, 읽기 오프셋의 로그를 남기고 시스템 `tmpdir`에 파일로 +저장합니다. 결과 파일은 ASAR 모듈의 파일 순서를 최적화 하는데 사용할 수 있습니다. + ## `ELECTRON_ENABLE_STACK_DUMPING` Electron이 크래시되면, 콘솔에 stack trace를 출력합니다. diff --git a/docs-translations/ko-KR/api/frameless-window.md b/docs-translations/ko-KR/api/frameless-window.md index 9dbac12d5fb..94c87ca9a64 100644 --- a/docs-translations/ko-KR/api/frameless-window.md +++ b/docs-translations/ko-KR/api/frameless-window.md @@ -1,7 +1,7 @@ # Frameless Window Frameless Window는 [창 테두리](https://developer.mozilla.org/en-US/docs/Glossary/Chrome)가 -없는 윈도우를 말합니다. 이 기능은 윈도우 창의 일부분인 툴바와 같이 웹 페이지의 일부분이 +없는 윈도우를 말합니다. 이 기능은 윈도우의 일부분인 툴바와 같이 웹 페이지의 일부분이 아닌 부분을 보이지 않도록 합니다. [`BrowserWindow`](browser-window.md) 클래스의 옵션에서 설정할 수 있습니다. diff --git a/docs-translations/ko-KR/api/menu.md b/docs-translations/ko-KR/api/menu.md index 61bf92bf76d..a2d5b8d7a63 100644 --- a/docs-translations/ko-KR/api/menu.md +++ b/docs-translations/ko-KR/api/menu.md @@ -166,7 +166,7 @@ if (process.platform == 'darwin') { }, { label: 'Hide Others', - accelerator: 'Command+Shift+H', + accelerator: 'Command+Alt+H', role: 'hideothers' }, { @@ -235,14 +235,18 @@ Linux에선 각 창의 상단에 표시됩니다. 또한 `template`에는 다른 속성도 추가할 수 있으며 메뉴가 만들어질 때 해당 메뉴 아이템의 프로퍼티로 변환됩니다. -### `Menu.popup([browserWindow, x, y])` +### `Menu.popup([browserWindow, x, y, positioningItem])` -* `browserWindow` BrowserWindow (optional) -* `x` Number (optional) -* `y` Number (만약 `x`를 지정했을 경우 반드시 `y`도 지정해야 합니다) +* `browserWindow` BrowserWindow (optional) - 기본값은 `null`입니다. +* `x` Number (optional) - 기본값은 -1입니다. +* `y` Number (만약 `x`를 지정한 경우 **필수 항목**) - 기본값은 -1입니다. +* `positioningItem` Number (optional) _OS X_ - 메뉴 팝업 시 마우스 커서에 바로 + 위치시킬 메뉴 아이템의 인덱스. 기본값은 -1입니다. 메뉴를 `browserWindow` 내부 팝업으로 표시합니다. 옵션으로 메뉴를 표시할 `(x,y)` 좌표를 지정할 수 있습니다. 따로 좌표를 지정하지 않은 경우 마우스 커서 위치에 표시됩니다. +`positioningItem` 속성은 메뉴 팝업 시 마우스 커서에 바로 위치시킬 메뉴 아이템의 +인덱스입니다. (OS X에서만 지원합니다) ### `Menu.append(menuItem)` diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 59b7d0c153e..06144fc7e9a 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -286,11 +286,11 @@ Returns: * `url` URL * `options` Object (optional), 속성들: - * `httpReferrer` String - HTTP Referrer url. + * `httpReferrer` String - HTTP 레퍼러 url. * `userAgent` String - 요청을 시작한 유저 에이전트. * `extraHeaders` String - "\n"로 구분된 Extra 헤더들. -윈도우에 웹 페이지 `url`을 로드합니다. `url`은 `http://` or `file://`과 같은 +윈도우에 웹 페이지 `url`을 로드합니다. `url`은 `http://`, `file://`과 같은 프로토콜 접두사를 가지고 있어야 합니다. 만약 반드시 http 캐시를 사용하지 않고 로드해야 하는 경우 `pragma` 헤더를 사용할 수 있습니다. diff --git a/docs-translations/ko-KR/api/web-view-tag.md b/docs-translations/ko-KR/api/web-view-tag.md index a6a84a1ceee..bd07c883e06 100644 --- a/docs-translations/ko-KR/api/web-view-tag.md +++ b/docs-translations/ko-KR/api/web-view-tag.md @@ -151,6 +151,16 @@ API를 사용할 수 있습니다. 이를 지정하면 내부에서 로우레벨 "on"으로 지정하면 페이지에서 새로운 창을 열 수 있도록 허용합니다. +### `blinkfeatures` + +```html + +``` + +활성화할 blink 기능을 지정한 `,`로 구분된 문자열의 리스트입니다. 지원하는 기능 문자열의 +전체 목록은 [setFeatureEnabledFromString][blink-feature-string] 함수에서 찾을 수 +있습니다. + ## Methods `webview` 태그는 다음과 같은 메서드를 가지고 있습니다: @@ -165,6 +175,17 @@ webview.addEventListener("dom-ready", function() { }); ``` +### `.loadURL(url[, options])` + +* `url` URL +* `options` Object (optional), 속성들: + * `httpReferrer` String - HTTP 레퍼러 url. + * `userAgent` String - 요청을 시작한 유저 에이전트. + * `extraHeaders` String - "\n"로 구분된 Extra 헤더들. + +Webview에 웹 페이지 `url`을 로드합니다. `url`은 `http://`, `file://`과 같은 +프로토콜 접두사를 가지고 있어야 합니다. + ### `.getURL()` 페이지의 URL을 반환합니다. @@ -701,3 +722,5 @@ WebContents가 파괴될 때 발생하는 이벤트입니다. ### Event: 'devtools-focused' 개발자 도구가 포커스되거나 열렸을 때 발생하는 이벤트입니다. + +[blink-feature-string]: https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/platform/RuntimeEnabledFeatures.cpp&sq=package:chromium&type=cs&l=527 From 5372b6cd9137c18310836be947ee28d8cd0fd434 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 23:47:37 -0800 Subject: [PATCH 039/688] Fullscreenable => FullScreenable --- atom/browser/api/atom_api_window.cc | 12 ++++++------ atom/browser/api/atom_api_window.h | 4 ++-- atom/browser/native_window.h | 4 ++-- atom/browser/native_window_mac.h | 4 ++-- atom/browser/native_window_mac.mm | 8 ++++---- atom/browser/native_window_views.cc | 4 ++-- atom/browser/native_window_views.h | 4 ++-- atom/common/options_switches.cc | 2 +- atom/common/options_switches.h | 2 +- docs/api/browser-window.md | 4 ++-- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index cebd4ec3af1..6b787e407b7 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -432,12 +432,12 @@ bool Window::IsMaximizable() { return window_->IsMaximizable(); } -void Window::SetFullscreenable(bool fullscreenable) { - window_->SetFullscreenable(fullscreenable); +void Window::SetFullScreenable(bool fullscreenable) { + window_->SetFullScreenable(fullscreenable); } -bool Window::IsFullscreenable() { - return window_->IsFullscreenable(); +bool Window::IsFullScreenable() { + return window_->IsFullScreenable(); } void Window::SetClosable(bool closable) { @@ -713,8 +713,8 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isMinimizable", &Window::IsMinimizable) .SetMethod("setMaximizable", &Window::SetMaximizable) .SetMethod("isMaximizable", &Window::IsMaximizable) - .SetMethod("setFullscreenable", &Window::SetFullscreenable) - .SetMethod("isFullscreenable", &Window::IsFullscreenable) + .SetMethod("setFullScreenable", &Window::SetFullScreenable) + .SetMethod("isFullScreenable", &Window::IsFullScreenable) .SetMethod("setClosable", &Window::SetClosable) .SetMethod("isClosable", &Window::IsClosable) .SetMethod("setAlwaysOnTop", &Window::SetAlwaysOnTop) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index ad5ee180fa8..760fbb542b3 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -112,8 +112,8 @@ class Window : public mate::TrackableObject, bool IsMinimizable(); void SetMaximizable(bool maximizable); bool IsMaximizable(); - void SetFullscreenable(bool fullscreenable); - bool IsFullscreenable(); + void SetFullScreenable(bool fullscreenable); + bool IsFullScreenable(); void SetClosable(bool closable); bool IsClosable(); void SetAlwaysOnTop(bool top); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index bb81b11269f..2b715e65358 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -131,8 +131,8 @@ class NativeWindow : public base::SupportsUserData, virtual bool IsMinimizable() = 0; virtual void SetMaximizable(bool maximizable) = 0; virtual bool IsMaximizable() = 0; - virtual void SetFullscreenable(bool fullscreenable) = 0; - virtual bool IsFullscreenable() = 0; + virtual void SetFullScreenable(bool fullscreenable) = 0; + virtual bool IsFullScreenable() = 0; virtual void SetClosable(bool closable) = 0; virtual bool IsClosable() = 0; virtual void SetAlwaysOnTop(bool top) = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 98bfca67b1e..83c2dffe66f 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -54,8 +54,8 @@ class NativeWindowMac : public NativeWindow { bool IsMinimizable() override; void SetMaximizable(bool maximizable) override; bool IsMaximizable() override; - void SetFullscreenable(bool fullscreenable) override; - bool IsFullscreenable() override; + void SetFullScreenable(bool fullscreenable) override; + bool IsFullScreenable() override; void SetClosable(bool closable) override; bool IsClosable() override; void SetAlwaysOnTop(bool top) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9459931d643..9a20e131882 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -376,7 +376,7 @@ NativeWindowMac::NativeWindowMac( options.Get(options::kMaximizable, &maximizable); bool fullscreenable = true; - options.Get(options::kFullscreenable, &fullscreenable); + options.Get(options::kFullScreenable, &fullscreenable); bool closable = true; options.Get(options::kClosable, &closable); @@ -501,7 +501,7 @@ NativeWindowMac::NativeWindowMac( options.Get(options::kFullscreen, &fullscreen); if (fullscreenable) { - SetFullscreenable(true); + SetFullScreenable(true); } else if (base::mac::IsOSElCapitanOrLater()) { // On EL Capitan this flag is required to hide fullscreen button. NSUInteger collectionBehavior = [window_ collectionBehavior]; @@ -710,7 +710,7 @@ bool NativeWindowMac::IsMaximizable() { return [[window_ standardWindowButton:NSWindowZoomButton] isEnabled]; } -void NativeWindowMac::SetFullscreenable(bool fullscreenable) { +void NativeWindowMac::SetFullScreenable(bool fullscreenable) { bool maximizable = IsMaximizable(); NSUInteger collectionBehavior = [window_ collectionBehavior]; if (fullscreenable) { @@ -724,7 +724,7 @@ void NativeWindowMac::SetFullscreenable(bool fullscreenable) { } } -bool NativeWindowMac::IsFullscreenable() { +bool NativeWindowMac::IsFullScreenable() { return [window_ collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary; } diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index d6977dfd2d5..c51bdce0f5c 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -495,10 +495,10 @@ bool NativeWindowViews::IsMaximizable() { #endif } -void NativeWindowViews::SetFullscreenable(bool maximizable) { +void NativeWindowViews::SetFullScreenable(bool maximizable) { } -bool NativeWindowViews::IsFullscreenable() { +bool NativeWindowViews::IsFullScreenable() { return true; } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 7f947b8e983..98339f8aa60 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -74,8 +74,8 @@ class NativeWindowViews : public NativeWindow, bool IsMinimizable() override; void SetMaximizable(bool maximizable) override; bool IsMaximizable() override; - void SetFullscreenable(bool fullscreenable) override; - bool IsFullscreenable() override; + void SetFullScreenable(bool fullscreenable) override; + bool IsFullScreenable() override; void SetClosable(bool closable) override; bool IsClosable() override; void SetAlwaysOnTop(bool top) override; diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 071c0bec772..ac63ea1b727 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -25,7 +25,7 @@ const char kResizable[] = "resizable"; const char kMovable[] = "movable"; const char kMinimizable[] = "minimizable"; const char kMaximizable[] = "maximizable"; -const char kFullscreenable[] = "fullscreenable"; +const char kFullScreenable[] = "fullscreenable"; const char kClosable[] = "closable"; const char kFullscreen[] = "fullscreen"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 861ac3138f9..3c198555a5c 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -26,7 +26,7 @@ extern const char kResizable[]; extern const char kMovable[]; extern const char kMinimizable[]; extern const char kMaximizable[]; -extern const char kFullscreenable[]; +extern const char kFullScreenable[]; extern const char kClosable[]; extern const char kFullscreen[]; extern const char kSkipTaskbar[]; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 0cc59fbb689..6b6fa3c1600 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -575,14 +575,14 @@ nothing. Returns whether the window can be manually maximized by user. On Linux always returns `true`. -### `win.setFullscreenable(fullscreenable)` _OS X_ +### `win.setFullScreenable(fullscreenable)` _OS X_ * `fullscreenable` Boolean Sets whether the maximize/zoom window button toggles fullscreen mode or maximizes the window. On Windows and Linux does nothing. -### `win.isFullscreenable()` _OS X_ +### `win.isFullScreenable()` _OS X_ Returns whether the maximize/zoom window button toggles fullscreen mode or maximizes the window. On Windows and Linux always returns `true`. From ae7e96f181cdb6329e4892e83bc2aa21843b08f0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Jan 2016 23:51:52 -0800 Subject: [PATCH 040/688] Fix fullscreenable on EL Capitan --- atom/browser/native_window_mac.mm | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9a20e131882..fe141869cbe 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -371,13 +371,10 @@ NativeWindowMac::NativeWindowMac( bool minimizable = true; options.Get(options::kMinimizable, &minimizable); - + bool maximizable = true; options.Get(options::kMaximizable, &maximizable); - bool fullscreenable = true; - options.Get(options::kFullScreenable, &fullscreenable); - bool closable = true; options.Get(options::kClosable, &closable); @@ -496,17 +493,15 @@ NativeWindowMac::NativeWindowMac( options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor); [window_ setDisableAutoHideCursor:disableAutoHideCursor]; - // Disable fullscreen button when 'fullscreen' is specified to false. + // Disable fullscreen button when 'fullscreenable' is false or 'fullscreen' + // is specified to false. + bool fullscreenable = true; + options.Get(options::kFullScreenable, &fullscreenable); bool fullscreen = false; - options.Get(options::kFullscreen, &fullscreen); - - if (fullscreenable) { - SetFullScreenable(true); - } else if (base::mac::IsOSElCapitanOrLater()) { - // On EL Capitan this flag is required to hide fullscreen button. - NSUInteger collectionBehavior = [window_ collectionBehavior]; - collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary; - [window_ setCollectionBehavior:collectionBehavior]; + if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) + fullscreenable = false; + if (!fullscreenable) { + SetFullScreenable(false); } // Disable zoom button if window is not resizable @@ -717,6 +712,8 @@ void NativeWindowMac::SetFullScreenable(bool fullscreenable) { collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; } else { collectionBehavior &= (~NSWindowCollectionBehaviorFullScreenPrimary); + // On EL Capitan this flag is required to hide fullscreen button. + collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary; } [window_ setCollectionBehavior:collectionBehavior]; if (!maximizable) { From d704b3f7ba93c1a549795e820fa7ab11617d8333 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 02:23:18 -0800 Subject: [PATCH 041/688] Reorgnize how attributes work --- atom/browser/native_window.cc | 16 +--- atom/browser/native_window_mac.mm | 11 +-- atom/browser/native_window_views.cc | 101 +++++++++++------------- atom/browser/native_window_views.h | 2 +- atom/browser/native_window_views_win.cc | 3 +- 5 files changed, 55 insertions(+), 78 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 4435915db03..7d0ae5a5b76 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -116,23 +116,15 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { SetSizeConstraints(size_constraints); } #if defined(OS_WIN) || defined(USE_X11) - bool resizable; - if (options.Get(options::kResizable, &resizable)) { - SetResizable(resizable); - } - bool minimizable; - if (options.Get(options::kMinimizable, &minimizable)) { - SetMinimizable(minimizable); - } bool closable; if (options.Get(options::kClosable, &closable)) { SetClosable(closable); } - bool maximizable; - if (options.Get(options::kMaximizable, &maximizable)) { - SetMaximizable(maximizable); - } #endif + bool movable; + if (options.Get(options::kMovable, &movable) && movable) { + SetMovable(movable); + } bool top; if (options.Get(options::kAlwaysOnTop, &top) && top) { SetAlwaysOnTop(true); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index fe141869cbe..e989ad90d42 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -394,12 +394,12 @@ NativeWindowMac::NativeWindowMac( useStandardWindow = false; } - NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask; + NSUInteger styleMask = NSTitledWindowMask; if (minimizable) { styleMask |= NSMiniaturizableWindowMask; } - if (!closable) { - styleMask &= ~NSClosableWindowMask; + if (closable) { + styleMask |= NSClosableWindowMask; } if (!useStandardWindow || transparent() || !has_frame()) { styleMask |= NSTexturedBackgroundWindowMask; @@ -472,11 +472,6 @@ NativeWindowMac::NativeWindowMac( set_force_using_draggable_region(true); } - bool movable; - if (options.Get(options::kMovable, &movable)) { - [window_ setMovable:movable]; - } - // On OS X the initial window size doesn't include window frame. bool use_content_size = false; options.Get(options::kUseContentSize, &use_content_size); diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index c51bdce0f5c..216a76ec6b9 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -59,6 +59,17 @@ const int kMenuBarHeight = 20; const int kMenuBarHeight = 25; #endif +#if defined(OS_WIN) +void FlipWindowStyle(HWND handle, bool on, DWORD flag) { + DWORD style = ::GetWindowLong(handle, GWL_STYLE); + if (on) + style |= flag; + else + style &= ~flag; + ::SetWindowLong(handle, GWL_STYLE, style); +} +#endif + bool IsAltKey(const content::NativeWebKeyboardEvent& event) { return event.windowsKeyCode == ui::VKEY_MENU; } @@ -103,9 +114,9 @@ NativeWindowViews::NativeWindowViews( menu_bar_alt_pressed_(false), keyboard_event_handler_(new views::UnhandledKeyboardEventHandler), use_content_size_(false), + movable_(true), resizable_(true), maximizable_(true), - movable_(true), minimizable_(true) { options.Get(options::kTitle, &title_); options.Get(options::kAutoHideMenuBar, &menu_bar_autohide_); @@ -114,7 +125,6 @@ NativeWindowViews::NativeWindowViews( // On Windows we rely on the CanResize() to indicate whether window can be // resized, and it should be set before window is created. options.Get(options::kResizable, &resizable_); - options.Get(options::kMovable, &movable_); options.Get(options::kMinimizable, &minimizable_); options.Get(options::kMaximizable, &maximizable_); #endif @@ -216,25 +226,29 @@ NativeWindowViews::NativeWindowViews( last_window_state_ = ui::SHOW_STATE_FULLSCREEN; else last_window_state_ = ui::SHOW_STATE_NORMAL; - last_normal_size_ = gfx::Size(widget_size_); - DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); - style |= WS_THICKFRAME | WS_CAPTION | WS_MINIMIZEBOX; - - if (transparent()) { - DWORD ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); - ex_style |= WS_EX_COMPOSITED; - ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); - - if (!has_frame()) { - // We should not show a frame for transparent window. - style &= ~(WS_THICKFRAME | WS_CAPTION); - } + if (!has_frame()) { + // Set Window style so that we get a minimize and maximize animation when + // frameless. + DWORD frame_style = WS_CAPTION; + if (resizable_) + frame_style |= WS_THICKFRAME; + if (minimizable_) + frame_style |= WS_MINIMIZEBOX; + if (maximizable_) + frame_style |= WS_MAXIMIZEBOX; + // We should not show a frame for transparent window. + if (transparent()) + frame_style &= ~(WS_THICKFRAME | WS_CAPTION); + ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style); } - if (!transparent() || !has_frame()) { - ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); + if (transparent()) { + // Transparent window on Windows has to have WS_EX_COMPOSITED style. + LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE); + ex_style |= WS_EX_COMPOSITED; + ::SetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE, ex_style); } #endif @@ -405,18 +419,8 @@ void NativeWindowViews::SetContentSizeConstraints( void NativeWindowViews::SetResizable(bool resizable) { #if defined(OS_WIN) - // WS_MAXIMIZEBOX => Maximize button - // WS_MINIMIZEBOX => Minimize button - // WS_THICKFRAME => Resize handle - if (!transparent()) { - DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); - if (resizable) { - style |= WS_THICKFRAME; - } else { - style &= ~(WS_THICKFRAME); - } - ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); - } + if (!transparent()) + FlipWindowStyle(GetAcceleratedWidget(), resizable, WS_THICKFRAME); #elif defined(USE_X11) if (resizable != resizable_) { // On Linux there is no "resizable" property of a window, we have to set @@ -437,7 +441,7 @@ void NativeWindowViews::SetResizable(bool resizable) { } bool NativeWindowViews::IsResizable() { - return resizable_; + return CanResize(); } void NativeWindowViews::SetMovable(bool movable) { @@ -447,51 +451,38 @@ void NativeWindowViews::SetMovable(bool movable) { bool NativeWindowViews::IsMovable() { #if defined(OS_WIN) return movable_; -#elif defined(USE_X11) - return true; +#else + return true; // Not implemented on Linux. #endif } void NativeWindowViews::SetMinimizable(bool minimizable) { #if defined(OS_WIN) - if (!transparent()) { - DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); - if (minimizable) - style |= WS_MINIMIZEBOX; - else - style &= (~WS_MINIMIZEBOX); - ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); - } + FlipWindowStyle(GetAcceleratedWidget(), minimizable, WS_MINIMIZEBOX); #endif - minimizable_ = minimizable; } bool NativeWindowViews::IsMinimizable() { #if defined(OS_WIN) - return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MINIMIZEBOX; -#elif defined(USE_X11) - return true; + return CanMinimize(); +#else + return true; // CanMinimize() Not implemented on Linux. #endif } void NativeWindowViews::SetMaximizable(bool maximizable) { #if defined(OS_WIN) - DWORD style = ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE); - if (maximizable) { - style |= WS_MAXIMIZEBOX; - } else { - style &= (~WS_MAXIMIZEBOX); - } - ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, style); + FlipWindowStyle(GetAcceleratedWidget(), maximizable, WS_MAXIMIZEBOX); #endif + maximizable_ = maximizable; } bool NativeWindowViews::IsMaximizable() { #if defined(OS_WIN) - return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MAXIMIZEBOX; -#elif defined(USE_X11) - return true; + return CanMaximize(); +#else + return true; // CanMaximize() Not implemented on Linux. #endif } @@ -786,7 +777,7 @@ bool NativeWindowViews::CanResize() const { } bool NativeWindowViews::CanMaximize() const { - return resizable_; + return resizable_ && maximizable_; } bool NativeWindowViews::CanMinimize() const { diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 98339f8aa60..61d0f95042f 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -206,9 +206,9 @@ class NativeWindowViews : public NativeWindow, accelerator_util::AcceleratorTable accelerator_table_; bool use_content_size_; + bool movable_; bool resizable_; bool maximizable_; - bool movable_; bool minimizable_; std::string title_; gfx::Size widget_size_; diff --git a/atom/browser/native_window_views_win.cc b/atom/browser/native_window_views_win.cc index 53228d5fdf9..e5ed1975f80 100644 --- a/atom/browser/native_window_views_win.cc +++ b/atom/browser/native_window_views_win.cc @@ -96,9 +96,8 @@ bool NativeWindowViews::PreHandleMSG( return false; case WM_MOVING: { - if (!movable_) { + if (!movable_) ::GetWindowRect(GetAcceleratedWidget(), (LPRECT)l_param); - } return false; } From 239bfe970cfa38ce0c9618977c3ee6b31319d797 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 02:55:12 -0800 Subject: [PATCH 042/688] Make hasShadow work on Windows/Linux --- atom/browser/native_window.cc | 11 ++++------- atom/browser/native_window.h | 4 ++-- atom/browser/native_window_mac.mm | 6 ------ atom/browser/native_window_views.cc | 18 +++++++++++++----- atom/browser/native_window_views.h | 2 ++ 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 7d0ae5a5b76..73370d24c41 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -125,6 +125,10 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { if (options.Get(options::kMovable, &movable) && movable) { SetMovable(movable); } + bool has_shadow; + if (options.Get(options::kHasShadow, &has_shadow)) { + SetHasShadow(has_shadow); + } bool top; if (options.Get(options::kAlwaysOnTop, &top) && top) { SetAlwaysOnTop(true); @@ -555,13 +559,6 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback, callback.Run(bitmap); } -void NativeWindow::SetHasShadow(bool has_shadow) { -} - -bool NativeWindow::HasShadow() { - return true; -} - SkColor NativeWindow::ParseHexColor(const std::string& name) { SkColor result = 0xFF000000; unsigned value = 0; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 2b715e65358..ea5f063a982 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -145,8 +145,8 @@ class NativeWindow : public base::SupportsUserData, virtual void SetKiosk(bool kiosk) = 0; virtual bool IsKiosk() = 0; virtual void SetBackgroundColor(const std::string& color_name) = 0; - virtual void SetHasShadow(bool has_shadow); - virtual bool HasShadow(); + virtual void SetHasShadow(bool has_shadow) = 0; + virtual bool HasShadow() = 0; virtual void SetRepresentedFilename(const std::string& filename); virtual std::string GetRepresentedFilename(); virtual void SetDocumentEdited(bool edited); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index e989ad90d42..a5dd2842b65 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -449,12 +449,6 @@ NativeWindowMac::NativeWindowMac( if (!has_frame()) [window_ setOpaque:NO]; - bool has_shadow = true; - options.Get(options::kHasShadow, &has_shadow); - if (!has_shadow) { - SetHasShadow(false); - } - // We will manage window's lifetime ourselves. [window_ setReleasedWhenClosed:NO]; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 216a76ec6b9..9244a327d1b 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -155,6 +155,11 @@ NativeWindowViews::NativeWindowViews( if (transparent()) params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; + // The given window is most likely not rectangular since it uses + // transparency and has no standard frame, don't show a shadow for it. + if (transparent() && !has_frame()) + params.shadow_type = Widget::InitParams::SHADOW_TYPE_NONE; + #if defined(OS_WIN) params.native_widget = new views::DesktopNativeWidgetAura(window_.get()); @@ -259,11 +264,6 @@ NativeWindowViews::NativeWindowViews( window_->FrameTypeChanged(); } - // The given window is most likely not rectangular since it uses - // transparency and has no standard frame, don't show a shadow for it. - if (transparent() && !has_frame()) - wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE); - gfx::Size size = bounds.size(); if (has_frame() && options.Get(options::kUseContentSize, &use_content_size_) && @@ -597,6 +597,14 @@ void NativeWindowViews::SetBackgroundColor(const std::string& color_name) { #endif } +void NativeWindowViews::SetHasShadow(bool has_shadow) { + wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE); +} + +bool NativeWindowViews::HasShadow() { + return wm::GetShadowType(GetNativeWindow()) != wm::SHADOW_TYPE_NONE; +} + void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) { if (menu_model == nullptr) { // Remove accelerators diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 61d0f95042f..934f2aa00c9 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -88,6 +88,8 @@ class NativeWindowViews : public NativeWindow, void SetKiosk(bool kiosk) override; bool IsKiosk() override; void SetBackgroundColor(const std::string& color_name) override; + void SetHasShadow(bool has_shadow) override; + bool HasShadow() override; void SetMenu(ui::MenuModel* menu_model) override; gfx::NativeWindow GetNativeWindow() override; void SetOverlayIcon(const gfx::Image& overlay, From 010cc3276ab3ce1d975cfca83599a8662b604f13 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 03:12:19 -0800 Subject: [PATCH 043/688] Simplify the setStyleMask calls --- atom/browser/native_window_mac.h | 4 ++ atom/browser/native_window_mac.mm | 88 ++++++++++++------------------- 2 files changed, 39 insertions(+), 53 deletions(-) diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 83c2dffe66f..964126593ae 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -120,6 +120,10 @@ class NativeWindowMac : public NativeWindow { // whehter we can drag. void UpdateDraggableRegionViews(const std::vector& regions); + // Set the attribute of NSWindow while work around a bug of zo0m button. + void SetStyleMask(bool on, NSUInteger flag); + void SetCollectionBehavior(bool on, NSUInteger flag); + base::scoped_nsobject window_; base::scoped_nsobject window_delegate_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index a5dd2842b65..bd47fef914b 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -639,18 +639,10 @@ void NativeWindowMac::SetContentSizeConstraints( } void NativeWindowMac::SetResizable(bool resizable) { - bool maximizable = IsMaximizable(); // Change styleMask for frameless causes the window to change size, so we have // to explicitly disables that. ScopedDisableResize disable_resize; - if (resizable) { - [window_ setStyleMask:[window_ styleMask] | NSResizableWindowMask]; - } else { - [window_ setStyleMask:[window_ styleMask] & (~NSResizableWindowMask)]; - } - if (!maximizable) { - SetMaximizable(false); - } + SetStyleMask(resizable, NSResizableWindowMask); } bool NativeWindowMac::IsResizable() { @@ -666,20 +658,7 @@ bool NativeWindowMac::IsMovable() { } void NativeWindowMac::SetMinimizable(bool minimizable) { - bool maximizable = IsMaximizable(); - if (minimizable) { - [window_ setStyleMask:[window_ styleMask] | NSMiniaturizableWindowMask]; - } else { - [window_ setStyleMask:[window_ styleMask] & (~NSMiniaturizableWindowMask)]; - } - // If fullscreen has not been disabled via `fullscreenable: false` (i.e. when - // collectionBehavior has NSWindowCollectionBehaviorFullScreenPrimary mask), - // zoom button is reset to it's default (enabled) state when window's - // styleMask has been changed. So if the button was disabled, we have to - // disable it again. I think it's a bug in Cocoa. - if (!maximizable) { - SetMaximizable(false); - } + SetStyleMask(minimizable, NSMiniaturizableWindowMask); } bool NativeWindowMac::IsMinimizable() { @@ -695,35 +674,20 @@ bool NativeWindowMac::IsMaximizable() { } void NativeWindowMac::SetFullScreenable(bool fullscreenable) { - bool maximizable = IsMaximizable(); - NSUInteger collectionBehavior = [window_ collectionBehavior]; - if (fullscreenable) { - collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; - } else { - collectionBehavior &= (~NSWindowCollectionBehaviorFullScreenPrimary); - // On EL Capitan this flag is required to hide fullscreen button. - collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary; - } - [window_ setCollectionBehavior:collectionBehavior]; - if (!maximizable) { - SetMaximizable(false); - } + SetCollectionBehavior( + fullscreenable, NSWindowCollectionBehaviorFullScreenPrimary); + // On EL Capitan this flag is required to hide fullscreen button. + SetCollectionBehavior( + !fullscreenable, NSWindowCollectionBehaviorFullScreenAuxiliary); } bool NativeWindowMac::IsFullScreenable() { - return [window_ collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary; + NSUInteger collectionBehavior = [window_ collectionBehavior]; + return collectionBehavior & NSWindowCollectionBehaviorFullScreenPrimary; } void NativeWindowMac::SetClosable(bool closable) { - bool maximizable = IsMaximizable(); - if (closable) { - [window_ setStyleMask:[window_ styleMask] | NSClosableWindowMask]; - } else { - [window_ setStyleMask:[window_ styleMask] & (~NSClosableWindowMask)]; - } - if (!maximizable) { - SetMaximizable(false); - } + SetStyleMask(closable, NSClosableWindowMask); } bool NativeWindowMac::IsClosable() { @@ -890,13 +854,7 @@ void NativeWindowMac::ShowDefinitionForSelection() { } void NativeWindowMac::SetVisibleOnAllWorkspaces(bool visible) { - NSUInteger collectionBehavior = [window_ collectionBehavior]; - if (visible) { - collectionBehavior |= NSWindowCollectionBehaviorCanJoinAllSpaces; - } else { - collectionBehavior &= ~NSWindowCollectionBehaviorCanJoinAllSpaces; - } - [window_ setCollectionBehavior:collectionBehavior]; + SetCollectionBehavior(visible, NSWindowCollectionBehaviorCanJoinAllSpaces); } bool NativeWindowMac::IsVisibleOnAllWorkspaces() { @@ -1053,6 +1011,30 @@ void NativeWindowMac::UpdateDraggableRegionViews( [window_ setMovableByWindowBackground:YES]; } +void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) { + bool zoom_button_enabled = IsMaximizable(); + if (on) + [window_ setStyleMask:[window_ styleMask] | flag]; + else + [window_ setStyleMask:[window_ styleMask] & (~flag)]; + // Change style mask will make the zoom button revert to default, probably + // a bug of Cocoa or OS X. + if (!zoom_button_enabled) + SetMaximizable(false); +} + +void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) { + bool zoom_button_enabled = IsMaximizable(); + if (on) + [window_ setCollectionBehavior:[window_ collectionBehavior] | flag]; + else + [window_ setCollectionBehavior:[window_ collectionBehavior] & (~flag)]; + // Change collectionBehavior will make the zoom button revert to default, + // probably a bug of Cocoa or OS X. + if (!zoom_button_enabled) + SetMaximizable(false); +} + // static NativeWindow* NativeWindow::Create( brightray::InspectableWebContents* inspectable_web_contents, From c41de501cb3b230092ac931cf67e9fe37e05ecdf Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 03:35:30 -0800 Subject: [PATCH 044/688] spec: Test the -able methods --- atom/browser/native_window.cc | 2 +- atom/browser/native_window_mac.mm | 4 +- atom/browser/native_window_views.cc | 8 +-- spec/api-browser-window-spec.js | 107 ++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 8 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 73370d24c41..732fc6301e2 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -122,7 +122,7 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { } #endif bool movable; - if (options.Get(options::kMovable, &movable) && movable) { + if (options.Get(options::kMovable, &movable)) { SetMovable(movable); } bool has_shadow; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index bd47fef914b..d109a8c3a1a 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -489,9 +489,7 @@ NativeWindowMac::NativeWindowMac( bool fullscreen = false; if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) fullscreenable = false; - if (!fullscreenable) { - SetFullScreenable(false); - } + SetFullScreenable(fullscreenable); // Disable zoom button if window is not resizable if (!maximizable) { diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 9244a327d1b..910a0c782b6 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -465,9 +465,9 @@ void NativeWindowViews::SetMinimizable(bool minimizable) { bool NativeWindowViews::IsMinimizable() { #if defined(OS_WIN) - return CanMinimize(); + return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MINIMIZEBOX; #else - return true; // CanMinimize() Not implemented on Linux. + return true; // Not implemented on Linux. #endif } @@ -480,9 +480,9 @@ void NativeWindowViews::SetMaximizable(bool maximizable) { bool NativeWindowViews::IsMaximizable() { #if defined(OS_WIN) - return CanMaximize(); + return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_MAXIMIZEBOX; #else - return true; // CanMaximize() Not implemented on Linux. + return true; // Not implemented on Linux. #endif } diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 92f69d17bca..0cd0422afbb 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -1,3 +1,5 @@ +'use strict'; + const assert = require('assert'); const fs = require('fs'); const path = require('path'); @@ -306,6 +308,7 @@ describe('browser-window module', function() { return assert.equal(after[1], size.height); }); }); + describe('"web-preferences" option', function() { afterEach(function() { return ipcMain.removeAllListeners('answer'); @@ -491,4 +494,108 @@ describe('browser-window module', function() { return assert.equal(size[1], 600); }); }); + + describe('window states', function() { + // Not implemented on Linux. + if (process.platform == 'linux') + return; + + describe('movable state', function() { + it('can be changed with movable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, movable: false}); + assert.equal(w.isMovable(), false); + }); + + it('can be changed with setMovable method', function() { + assert.equal(w.isMovable(), true); + w.setMovable(false); + assert.equal(w.isMovable(), false); + w.setMovable(true); + assert.equal(w.isMovable(), true); + }); + }); + + describe('minimizable state', function() { + it('can be changed with minimizable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, minimizable: false}); + assert.equal(w.isMinimizable(), false); + }); + + it('can be changed with setMinimizable method', function() { + assert.equal(w.isMinimizable(), true); + w.setMinimizable(false); + assert.equal(w.isMinimizable(), false); + w.setMinimizable(true); + assert.equal(w.isMinimizable(), true); + }); + }); + + describe('maximizable state', function() { + it('can be changed with maximizable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, maximizable: false}); + assert.equal(w.isMaximizable(), false); + }); + + it('can be changed with setMaximizable method', function() { + assert.equal(w.isMaximizable(), true); + w.setMaximizable(false); + assert.equal(w.isMaximizable(), false); + w.setMaximizable(true); + assert.equal(w.isMaximizable(), true); + }); + + it('is not affected when changing other states', function() { + w.setMaximizable(false); + assert.equal(w.isMaximizable(), false); + w.setMinimizable(false); + assert.equal(w.isMaximizable(), false); + w.setClosable(false); + assert.equal(w.isMaximizable(), false); + }); + }); + + describe('fullscreenable state', function() { + // Only implemented on OS X. + if (process.platform != 'darwin') + return; + + it('can be changed with fullscreenable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, fullscreenable: false}); + assert.equal(w.isFullScreenable(), false); + }); + + it('can be changed with setFullScreenable method', function() { + assert.equal(w.isFullScreenable(), true); + w.setFullScreenable(false); + assert.equal(w.isFullScreenable(), false); + w.setFullScreenable(true); + assert.equal(w.isFullScreenable(), true); + }); + }); + + describe('closable state', function() { + // Only implemented on OS X. + if (process.platform != 'darwin') + return; + + it('can be changed with closable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, closable: false}); + assert.equal(w.isClosable(), false); + }); + + it('can be changed with setClosable method', function() { + assert.equal(w.isClosable(), true); + w.setClosable(false); + assert.equal(w.isClosable(), false); + w.setClosable(true); + assert.equal(w.isClosable(), true); + }); + }); + + }); }); From c33e8de676532b89200a2f672d04fd7a6cfcb88d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 03:38:19 -0800 Subject: [PATCH 045/688] spec: Improve the test for resizable --- spec/api-browser-window-spec.js | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 0cd0422afbb..b54efdde9a0 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -194,19 +194,6 @@ describe('browser-window module', function() { return assert.equal(w.id, BrowserWindow.fromId(w.id).id); }); }); - describe('BrowserWindow.setResizable(resizable)', function() { - return it('does not change window size for frameless window', function() { - var s; - w.destroy(); - w = new BrowserWindow({ - show: true, - frame: false - }); - s = w.getSize(); - w.setResizable(!w.isResizable()); - return assert.deepEqual(s, w.getSize()); - }); - }); describe('"useContentSize" option', function() { it('make window created with content size when used', function() { var contentSize; @@ -578,10 +565,6 @@ describe('browser-window module', function() { }); describe('closable state', function() { - // Only implemented on OS X. - if (process.platform != 'darwin') - return; - it('can be changed with closable option', function() { w.destroy(); w = new BrowserWindow({show: false, closable: false}); @@ -597,5 +580,20 @@ describe('browser-window module', function() { }); }); + describe('resizable state', function() { + it('can be changed with resizable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, resizable: false}); + assert.equal(w.isResizable(), false); + }); + + it('can be changed with setResizable method', function() { + assert.equal(w.isResizable(), true); + w.setResizable(false); + assert.equal(w.isResizable(), false); + w.setResizable(true); + assert.equal(w.isResizable(), true); + }); + }); }); }); From 8239f69139735a37a230b1716cc9aafc69c356d3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 03:40:28 -0800 Subject: [PATCH 046/688] spec: hasShadow state --- spec/api-browser-window-spec.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index b54efdde9a0..3c98e7a42f9 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -595,5 +595,21 @@ describe('browser-window module', function() { assert.equal(w.isResizable(), true); }); }); + + describe('hasShadow state', function() { + it('can be changed with hasShadow option', function() { + w.destroy(); + w = new BrowserWindow({show: false, hasShadow: false}); + assert.equal(w.hasShadow(), false); + }); + + it('can be changed with setHasShadow method', function() { + assert.equal(w.hasShadow(), true); + w.setHasShadow(false); + assert.equal(w.hasShadow(), false); + w.setHasShadow(true); + assert.equal(w.hasShadow(), true); + }); + }); }); }); From cc560a39008a8eb2b7645d00f4b20fded42edaf0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 23 Jan 2016 20:03:56 +0800 Subject: [PATCH 047/688] spec: Fix failing tests on Windows --- atom/browser/native_window_views.cc | 10 ++++++++-- spec/api-browser-window-spec.js | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 910a0c782b6..44df87da9fb 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -158,7 +158,7 @@ NativeWindowViews::NativeWindowViews( // The given window is most likely not rectangular since it uses // transparency and has no standard frame, don't show a shadow for it. if (transparent() && !has_frame()) - params.shadow_type = Widget::InitParams::SHADOW_TYPE_NONE; + params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; #if defined(OS_WIN) params.native_widget = @@ -441,7 +441,11 @@ void NativeWindowViews::SetResizable(bool resizable) { } bool NativeWindowViews::IsResizable() { +#if defined(OS_WIN) + return ::GetWindowLong(GetAcceleratedWidget(), GWL_STYLE) & WS_THICKFRAME; +#else return CanResize(); +#endif } void NativeWindowViews::SetMovable(bool movable) { @@ -598,7 +602,9 @@ void NativeWindowViews::SetBackgroundColor(const std::string& color_name) { } void NativeWindowViews::SetHasShadow(bool has_shadow) { - wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE); + wm::SetShadowType( + GetNativeWindow(), + has_shadow ? wm::SHADOW_TYPE_RECTANGULAR : wm::SHADOW_TYPE_NONE); } bool NativeWindowViews::HasShadow() { diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 3c98e7a42f9..fc8d3523c8f 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -597,13 +597,19 @@ describe('browser-window module', function() { }); describe('hasShadow state', function() { + // On Window there is no shadow by default and it can not be changed + // dynamically. it('can be changed with hasShadow option', function() { w.destroy(); - w = new BrowserWindow({show: false, hasShadow: false}); - assert.equal(w.hasShadow(), false); + let hasShadow = process.platform == 'darwin' ? false : true; + w = new BrowserWindow({show: false, hasShadow: hasShadow}); + assert.equal(w.hasShadow(), hasShadow); }); it('can be changed with setHasShadow method', function() { + if (process.platform != 'darwin') + return; + assert.equal(w.hasShadow(), true); w.setHasShadow(false); assert.equal(w.hasShadow(), false); From 42493a7ed3c70ba9059e865a56d54f407f5f400e Mon Sep 17 00:00:00 2001 From: Takahito Yamatoya Date: Sun, 24 Jan 2016 19:47:12 +0900 Subject: [PATCH 048/688] Add Japanes translated docs, improve a doc style. --- docs-translations/jp/api/menu.md | 337 +++++++++++++++++++++++++++++++ docs/api/menu.md | 2 +- 2 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 docs-translations/jp/api/menu.md diff --git a/docs-translations/jp/api/menu.md b/docs-translations/jp/api/menu.md new file mode 100644 index 00000000000..e68a69cca83 --- /dev/null +++ b/docs-translations/jp/api/menu.md @@ -0,0 +1,337 @@ +# Menu + +`menu`クラスは、アプリケーションのメニューと[コンテキストメニュー](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/PopupGuide/ContextMenus)として使えるネイティブメニューを作成するのに使われます。このモジュールは、`remote`モジュール経由でレンダラープロセスで使用できるメインプロセスのモジュールです。 + +個々のメニューは複数の[menu items](menu-item.md)で成り立ち、個々のメニューアイテムはサブメニューを持てます。 + +以下は、ユーザーはページを右クリックした時、[remote](remote.md)モジュールを作成するために、(レンダラープロセス)ウェブページで動的にメニューを作成して、表示します。 + +```html + + +``` + +シンプルなテンプレートAPIでレンダラープロセスでアプリケーションメニューを作成する例です。 + +```javascript +var template = [ + { + label: 'Edit', + submenu: [ + { + label: 'Undo', + accelerator: 'CmdOrCtrl+Z', + role: 'undo' + }, + { + label: 'Redo', + accelerator: 'Shift+CmdOrCtrl+Z', + role: 'redo' + }, + { + type: 'separator' + }, + { + label: 'Cut', + accelerator: 'CmdOrCtrl+X', + role: 'cut' + }, + { + label: 'Copy', + accelerator: 'CmdOrCtrl+C', + role: 'copy' + }, + { + label: 'Paste', + accelerator: 'CmdOrCtrl+V', + role: 'paste' + }, + { + label: 'Select All', + accelerator: 'CmdOrCtrl+A', + role: 'selectall' + }, + ] + }, + { + label: 'View', + submenu: [ + { + label: 'Reload', + accelerator: 'CmdOrCtrl+R', + click: function(item, focusedWindow) { + if (focusedWindow) + focusedWindow.reload(); + } + }, + { + label: 'Toggle Full Screen', + accelerator: (function() { + if (process.platform == 'darwin') + return 'Ctrl+Command+F'; + else + return 'F11'; + })(), + click: function(item, focusedWindow) { + if (focusedWindow) + focusedWindow.setFullScreen(!focusedWindow.isFullScreen()); + } + }, + { + label: 'Toggle Developer Tools', + accelerator: (function() { + if (process.platform == 'darwin') + return 'Alt+Command+I'; + else + return 'Ctrl+Shift+I'; + })(), + click: function(item, focusedWindow) { + if (focusedWindow) + focusedWindow.toggleDevTools(); + } + }, + ] + }, + { + label: 'Window', + role: 'window', + submenu: [ + { + label: 'Minimize', + accelerator: 'CmdOrCtrl+M', + role: 'minimize' + }, + { + label: 'Close', + accelerator: 'CmdOrCtrl+W', + role: 'close' + }, + ] + }, + { + label: 'Help', + role: 'help', + submenu: [ + { + label: 'Learn More', + click: function() { require('electron').shell.openExternal('http://electron.atom.io') } + }, + ] + }, +]; + +if (process.platform == 'darwin') { + var name = require('electron').app.getName(); + template.unshift({ + label: name, + submenu: [ + { + label: 'About ' + name, + role: 'about' + }, + { + type: 'separator' + }, + { + label: 'Services', + role: 'services', + submenu: [] + }, + { + type: 'separator' + }, + { + label: 'Hide ' + name, + accelerator: 'Command+H', + role: 'hide' + }, + { + label: 'Hide Others', + accelerator: 'Command+Alt+H', + role: 'hideothers' + }, + { + label: 'Show All', + role: 'unhide' + }, + { + type: 'separator' + }, + { + label: 'Quit', + accelerator: 'Command+Q', + click: function() { app.quit(); } + }, + ] + }); + // Window menu. + template[3].submenu.push( + { + type: 'separator' + }, + { + label: 'Bring All to Front', + role: 'front' + } + ); +} + +var menu = Menu.buildFromTemplate(template); +Menu.setApplicationMenu(menu); +``` + +## クラス: Menu + +### `new Menu()` + +新しいメニューを作成します。 + +## メソッド + +`menu`クラスーは次のメソッドを持ちます。 + +### `Menu.setApplicationMenu(menu)` + +* `menu` Menu + +OS Xで、アプリケーションメニューとして`menu`を設定します。WindowsとLinuxでは、`menu`はそれぞれのウィンドウの上のメニューとして設定されます。 + +### `Menu.sendActionToFirstResponder(action)` _OS X_ + +* `action` String + +アプリケーションの最初のレスポンダーに`action`が送信されます。規定のCocoaメニュー動作をエミュレートするために使われ、通常は`MenuItem`の`role`プロパティーを使います。 + +### `Menu.buildFromTemplate(template)` + +* `template` Array + +一般的に、`template`は、[MenuItem](menu-item.md)を組み立てるための `options`配列です。使用方法は下のように参照します。 + +ほかのフィールドに`template`の項目を設定でき、メニューアイテムを構成するプロパティです。 + +### `Menu.popup([browserWindow, x, y, positioningItem])` + +* `browserWindow` BrowserWindow (オプション) - 既定では`null`です。 +* `x` Number (オプション) - 既定では -1です。 +* `y` Number (**必須** `x` が使われている場合) - 既定では -1です。 +* `positioningItem` Number (オプション) _OS X_ - 既定では -1です。 + +メニューアイテムのインデックスを指定した座標にマウスカーソルを配置します。 + +`browserWindow`でコンテキストメニューとしてメニューをポップアップします。メニューを表示する場所をオプションで`x, y`座標を指定でき、指定しなければ現在のマウスカーソル位置に表示します。 + +### `Menu.append(menuItem)` + +* `menuItem` MenuItem + +メニューに`menuItem`を追加します。 + +### `Menu.insert(pos, menuItem)` + +* `pos` Integer +* `menuItem` MenuItem + +メニューの`pos`位置に`menuItem`を追加します。 + +### `Menu.items()` + +メニューのアイテムを収容した配列を取得します。 + +## OS X アプリケーションメニューの注意事項 + +OS Xは、WindowsとLinuxのアプリケーションのメニューとは完全に異なるスタイルを持ち、よりネイティブのようにアプリメニューを作成するのに幾つかの注意事項があります。 + +### 標準的なメニュー + +OS Xでは、`Services`と`Windows`メニューのように定義された標準的な多くのメニューがあります。標準的なメニューを作成するために、メニューの`role`に次のどれかを設定する必要があり、Electronはそれを受けて標準的なメニューを作成します。 + +* `window` +* `help` +* `services` + +### 標準的なメニューアイテムの動作 + +`About xxx`と`Hide xxx`、`Hide Others`のようないくつかのメニューアイテム用にOS Xは標準的な動作を提供します。メニューアイテムの動作に標準的な動作を設定するために、メニューアイテムの`role`属性を設定すべきです。 + +### メインのメニュー名 + +OS Xでは、設定したラベルに関係なく、アプリケーションの最初のアイテムのラベルはいつもアプリの名前です。変更するために、アプリにバンドルされている`Info.plist`ファイルを修正してアプリの名前を変更する必要があります。詳細は、 [About Information Property List Files][AboutInformationPropertyListFiles] を見てください。 + +## メニューアイテムの位置 + +`position`を使用することができ、`Menu.buildFromTemplate`でメニューを構築するときに`id`がアイテムを配置する方法をコントロールします。 + +`MenuItem`の`position`属性は、`[placement]=[id]`をもち、 `placement`は`before`や `after`、 `endof`の一つが設定され、`id`はメニューの設定されているアイテムで一意のIDです。 + +* `before` - IDから参照したアイテムの前にアイテムを挿入します。参照するアイテムが存在しないのなら、メニューの最後にアイテムが挿入されます。 +* `after` - IDから参照したアイテムの後にアイテムを挿入します。参照するアイテムが存在しないのなら、メニューの最後にアイテムが挿入されます。 +* `endof` -IDから参照したアイテムを含む論理グループの最後にアイテムを挿入します(グループはアイテムを分けるために作成されます)。参照するアイテムが存在しないのなら、付与されたIDで新しい分離グループが作成され、そのグループのあとにアイテムが挿入されます。 + +アイテムが配置されたとき、新しいアイテムが配置されるまで、すべての配置されていないアイテムがその後に挿入されます。同じ場所にメニューアイテムのグループを配置したいのなら、最初にアイテムで場所を指定する必要があります。 + +### 具体例 + +テンプレート: + +```javascript +[ + {label: '4', id: '4'}, + {label: '5', id: '5'}, + {label: '1', id: '1', position: 'before=4'}, + {label: '2', id: '2'}, + {label: '3', id: '3'} +] +``` + +メニュー: + +``` +- 1 +- 2 +- 3 +- 4 +- 5 +``` + +テンプレート: + +```javascript +[ + {label: 'a', position: 'endof=letters'}, + {label: '1', position: 'endof=numbers'}, + {label: 'b', position: 'endof=letters'}, + {label: '2', position: 'endof=numbers'}, + {label: 'c', position: 'endof=letters'}, + {label: '3', position: 'endof=numbers'} +] +``` + +メニュー: + +``` +- --- +- a +- b +- c +- --- +- 1 +- 2 +- 3 +``` + +[AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html diff --git a/docs/api/menu.md b/docs/api/menu.md index 0e66fc216d5..1de3b4f101e 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -302,7 +302,7 @@ You can make use of `position` and `id` to control how the item will be placed when building a menu with `Menu.buildFromTemplate`. The `position` attribute of `MenuItem` has the form `[placement]=[id]`, where -placement is one of `before`, `after`, or `endof` and `id` is the unique ID of +`placement` is one of `before`, `after`, or `endof` and `id` is the unique ID of an existing item in the menu: * `before` - Inserts this item before the id referenced item. If the From a83aee90e55fe1ec9057edb4f856eca54ba2b1e3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Jan 2016 15:02:43 +0800 Subject: [PATCH 049/688] No need to use scoped_nsobject for id --- atom/browser/native_window_mac.h | 4 +++- atom/browser/native_window_mac.mm | 22 ++++++++++++---------- docs/api/browser-window.md | 8 ++++++++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 4d86ec33774..93d03e4c157 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -126,7 +126,9 @@ class NativeWindowMac : public NativeWindow { base::scoped_nsobject window_; base::scoped_nsobject window_delegate_; - base::scoped_nsobject event_monitor_; + + // Event monitor for scroll wheel event. + id wheel_event_monitor_; // The view that will fill the whole frameless window. base::scoped_nsobject content_view_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index f69292e0607..7967a177173 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -499,32 +499,34 @@ NativeWindowMac::NativeWindowMac( NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - BOOL __block down = NO; - event_monitor_.reset([[NSEvent + // Use an NSEvent monitor to listen for the wheel event. + BOOL __block began = NO; + wheel_event_monitor_ = [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask - handler:^NSEvent * _Nullable(NSEvent * event) { + handler:^(NSEvent* event) { if ([[event window] windowNumber] != [window_ windowNumber]) return event; if (!web_contents) return event; - if (!down && (([event phase] == NSEventPhaseMayBegin) || ([event phase] == NSEventPhaseBegan))) { + if (!began && (([event phase] == NSEventPhaseMayBegin) || + ([event phase] == NSEventPhaseBegan))) { this->NotifyWindowScrollTouchBegin(); - down = YES; - } - if (down && (([event phase] == NSEventPhaseEnded) || ([event phase] == NSEventPhaseCancelled))) { + began = YES; + } else if (began && (([event phase] == NSEventPhaseEnded) || + ([event phase] == NSEventPhaseCancelled))) { this->NotifyWindowScrollTouchEnd(); - down = NO; + began = NO; } return event; - }] retain]); + }]; InstallView(); } NativeWindowMac::~NativeWindowMac() { - [NSEvent removeMonitor: event_monitor_.get()]; + [NSEvent removeMonitor:wheel_event_monitor_]; Observe(nullptr); } diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 6b8474662d7..edda572e9ac 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -307,6 +307,14 @@ someWindow.on('app-command', function(e, cmd) { }); ``` +### Event: 'scroll-touch-begin' _OS X_ + +Emitted when scroll wheel event phase has begun. + +### Event: 'scroll-touch-end' _OS X_ + +Emitted when scroll wheel event phase has ended. + ## Methods The `BrowserWindow` object has the following methods: From d8c8214f3384101f7e7b324606d13ef661d232e6 Mon Sep 17 00:00:00 2001 From: Takahito Yamatoya Date: Mon, 25 Jan 2016 18:10:34 +0900 Subject: [PATCH 050/688] Add Japanes translated docs. --- .../jp/api/chrome-command-line-switches.md | 133 ++++++++++++++++++ docs-translations/jp/api/frameless-window.md | 73 ++++++++++ 2 files changed, 206 insertions(+) create mode 100644 docs-translations/jp/api/chrome-command-line-switches.md create mode 100644 docs-translations/jp/api/frameless-window.md diff --git a/docs-translations/jp/api/chrome-command-line-switches.md b/docs-translations/jp/api/chrome-command-line-switches.md new file mode 100644 index 00000000000..b3359eb322c --- /dev/null +++ b/docs-translations/jp/api/chrome-command-line-switches.md @@ -0,0 +1,133 @@ +#サポートしているChromeコマンドラインスイッチ + +ElectronでサポートしているChromeブラウザーで使用できるコマンドラインスイッチをこのページで一覧にしています。[app][app]モジュールの[ready][ready]イベントが出力される前にアプリのメインスクリプトに追加するために[app.commandLine.appendSwitch][append-switch]を使えます。 + +```javascript +const app = require('electron').app; +app.commandLine.appendSwitch('remote-debugging-port', '8315'); +app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1'); + +app.on('ready', function() { + // Your code here +}); +``` + +## --client-certificate=`path` + +クライアントの証明書ファイルの`path`を設定します。 + +## --ignore-connections-limit=`domains` + +接続数の制限を無視する`,`で分割した`domains`リスト + +## --disable-http-cache + +HTTPリクエストのディスクキャッシュの無効化。 + +## --remote-debugging-port=`port` + +`port`で指定したHTTP越しのリモートデバッグの有効化。 + +## --js-flags=`flags` + +JSエンジンに渡されるフラグの指定。メインプロセスで`flags`を有効化したいのなら、Electron開始時に渡される必要があります。 + +```bash +$ electron --js-flags="--harmony_proxies --harmony_collections" your-app +``` + +## --proxy-server=`address:port` + +システム設定を上書きし、指定したプロキシサーバーを使用します。HTTPS、WebSocketリクエストを含むHTTPプロトコルのリクエストのみに影響します。全てのプロキシサーバーがHTTPSとWebSocketリクエストに対応しているわけではないことに注意してください。 + +## --proxy-bypass-list=`hosts` + +ホスト一覧をセミコロンで分割したプロキシサーバーをバイパスしてするためにElectronに指示します。このフラグは、`--proxy-server`と同時に使われるときのみに影響します。 + +例: + +```javascript +app.commandLine.appendSwitch('proxy-bypass-list', ';*.google.com;*foo.com;1.2.3.4:5678') +``` + +ロカールアドレス(`localhost`や`127.0.0.1`など)、`google.com`サブドメイン、`foo.com` サフィックスを含むホスト、`1.2.3.4:5678`を除いてすべてのホストでプロキシサーバーが使われます。 + +## --proxy-pac-url=`url` + +`url`で指定したPACスクリプトが使われます。 + +## --no-proxy-server + +プロキシサーバーを使わず、常に直接接続します。遠輝ほかのプロキシサーバーフラグを上書きします。 + +## --host-rules=`rules` + +ホスト名がどのようにマップされているかを制御するコンマで分割された`rules`一覧 + +例: + +* `MAP * 127.0.0.1` 全てのホスト名を127.0.0.1にマッピングするよう強制します。 +* `MAP *.google.com proxy` すべてのgoogle.comサブドメインを "proxy"で解決するよう強制します。 +* `MAP test.com [::1]:77` "test.com"をIPv6ループバックで解決するよう強制します。結果ポートのをソケットアドレス77番にするよう強制します。 +* `MAP * baz, EXCLUDE www.google.com` 全てを"baz"に再マッピングし、 "www.google.com"は除外します。 + +これらのマッピングは、ネットリクエスト(直接接続で、TCP接続とホスト解決とHTTPプロキシ接続での`CONNECT`、`SOCKS`プロキシ接続でのエンドポイントホスト)でエンドポイントホストに適用されます。 + +## --host-resolver-rules=`rules` + +`--host-rules`のようですが、`rules` はホスト解決のみに適用されます。 + +## --ignore-certificate-errors + +証明書関連エラーを無視します。 + +## --ppapi-flash-path=`path` + +pepper flash pluginの`path`を設定します。 + +## --ppapi-flash-version=`version` + +pepper flash pluginの`version`を設定します。 + +## --log-net-log=`path` + +ネットログイベントを保存し、`path`に書き込みを有効化します。 + +## --ssl-version-fallback-min=`version` + +TLSフォールバックを許可する最小のSSL/TLSバージョン ("tls1"や"tls1.1" 、 "tls1.2")を設定します。 + +## --cipher-suite-blacklist=`cipher_suites` + +無効にするために、SSL暗号スイートのカンマ区切りのリストを指定します。 + +## --disable-renderer-backgrounding + +不可視のページのレンダラープロセスの優先度を下げることからChromiumを防ぎます。 + +このフラグは、グローバルですべてのレンダラープロセスに有効で、一つのウィンドウだけで無効化したい場合、[playing silent audio][play-silent-audio]をハックして対応します。 + +## --enable-logging + +コンソールにChromiumのログを出力します。 + +このスイッチは`app.commandLine.appendSwitch` で使えず、アプリがロードされるよりもパースしますが、同じ効果を受けるために`ELECTRON_ENABLE_LOGGING`を環境変数に設定します。 + +## --v=`log_level` + +既定の最大アクティブなV-loggingレベルが付与されています。0が既定です。通常、正の値はV-loggingレベルに使用されます。 + +`--enable-logging` が渡された時だけ、このスイッチは動作します。 + +## --vmodule=`pattern` + +`--v`で付与された値を上書きするために、モジュール毎の最大V-loggingレベルを付与します。例えば、 `my_module=2,foo*=3` は、`my_module.*` と `foo*.*`のソースファイル全てのロギングレベルを変更します。 + +前方または後方スラッシュを含む任意のパターンは、全体のパス名だけでなく、モジュールに対してもテストとされます。例えば、`*/foo/bar/*=2`は`foo/bar`ディレクトリ下のソースファイルですべてのコードのロギングレベルを変更します。 + +このスイッチは、`--enable-logging`が渡された時のみ動作します。 + +[app]: app.md +[append-switch]: app.md#appcommandlineappendswitchswitch-value +[ready]: app.md#event-ready +[play-silent-audio]: https://github.com/atom/atom/pull/9485/files diff --git a/docs-translations/jp/api/frameless-window.md b/docs-translations/jp/api/frameless-window.md new file mode 100644 index 00000000000..0b1e055602f --- /dev/null +++ b/docs-translations/jp/api/frameless-window.md @@ -0,0 +1,73 @@ +# Frameless Window + +フレームの無いウィンドウは、ウェブページの一部ではなく、ツールバーのようなウィンドウのパーツで、[chrome](https://developer.mozilla.org/en-US/docs/Glossary/Chrome)ではないウィンドウです。 オプションとして[`BrowserWindow`](browser-window.md)クラスがあります。 + +## フレームの無いウィンドウを作成する + +フレームの無いウィンドウを作成するために、[BrowserWindow](browser-window.md)の `options`で、`frame` を `false`に設定する必要があります。 + +```javascript +const BrowserWindow = require('electron').BrowserWindow; +var win = new BrowserWindow({ width: 800, height: 600, frame: false }); +``` + +### OS Xでの別の方法 + +Mac OS X 10.10 Yosemite以降では、Chrome無しのウィンドウを指定する方法があります。`frame`を`false`に設定しタイトルバーとウィンドウコントロールの両方を無効にする代わりに、タイトルバーを隠しコンテンツをフルウィンドウサイズに広げたいけど、標準的なウィンドウ操作用にウィンドウコントロール("トラフィックライト")を維持したいかもしれません。新しい`titleBarStyle`オプションを指定することで、そうできます。 + +```javascript +var win = new BrowserWindow({ 'titleBarStyle': 'hidden' }); +``` + +## 透明なウィンドウ + + `transparent`オプションを`true`に設定すると、フレームの無い透明なウィンドウを作成できます。 + +```javascript +var win = new BrowserWindow({ transparent: true, frame: false }); +``` + +### 制限 + +* 透明領域をクリックすることはできません。この問題を解決するためにウィンドウの輪郭を設定するAPIを導入しようとしています。詳細は、[our issue](https://github.com/atom/electron/issues/1335) を参照してください。 +* 透明なウィンドウはサイズ変更できません。いくつかのプラットフォーム上では、`resizable`の`true`設定は、いくつかのプラットフォーム上で、動作を停止する透明ウィンドウを作成するかもしれません。 +* `blur`フィルターはウェブページのみに適用され、ウィンドウの下のコンテンツ(例えば、ユーザーのシステム上でほかのアプリケーションを開く)に、ぼやける効果を適用する方法はありません。 +* Windows オペレーティングシステム上では、DMMが無効のとき透明なウィンドウは動作しません。 +* Linuxユーザーは、GPUを無効化するためにコマンドラインで`--enable-transparent-visuals --disable-gpu`を設定でき、透明ウィンドウを作成するためにARGBを許可でき、これは、 [いくつかのNVidiaドライバー上でアルファチャンネルが動作しない](https://code.google.com/p/chromium/issues/detail?id=369209) という上流のバグ原因になります。 +* Macでは、透明なウィンドウでネイティブのウィンドウシャドーを表示できません。 + +## ドラッグ可能領域 + +既定では、フレーム無しウィンドウはドラッグできません。(OSの標準的なタイトルバーのような)ドラッグできる領域をElectronに指定するには、CSSで`-webkit-app-region: drag`を指定する必要があり、アプリはドラッグできる領域からドラッグできない領域を除外するために、`-webkit-app-region: no-drag`を使えます。現在のところ長方形領域のみサポートしています。 + +ウィンドウ全体をドラッグできるようにするには、`body`のスタイルに`-webkit-app-region: drag`を追加します。 + +```html + + +``` + +ウィンドウ全体度ドラッグできるようにするには、ボタンをドラッグできないように指定する必要があり、そうしなければユーザーがそれをクリックする可能性があります。 + +```css +button { + -webkit-app-region: no-drag; +} +``` + +カスタムタイトルバーをドラッグできるように設定すると、タイトルバーのすべてのボタンをドラッグできないようにする必要があります。 + +## テキスト選択 + +フレームの無いウィンドウでは、ドラッグを可能にする動作とテキスト選択がぶつかるかもしれません。例えば、タイトルバーをドラッグしたとき、うっかりタイトルバーのテキストを選択してしまうかもしれません。これを防ぐために、次の例のようにドラッグできる領域内のテキスト選択を無効にする必要があります。 + +```css +.titlebar { + -webkit-user-select: none; + -webkit-app-region: drag; +} +``` + +## コンテキストメニュー + +いくつかのプラットフォームでは、ドラッグ可能な領域は、クライアントフレーム無しとして扱われるので、その上で右クリックすると、システムメニューがポップアップします。コンテキストメニューをすべてのプラットフォームで正しく動作するようにするためには、ドラッグ可能領域でカスタムコンテキストメニューを使用しないでください。 From b461969114d9294b89cb85befbc35c79b97dcbbc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Jan 2016 18:41:34 +0800 Subject: [PATCH 051/688] docs: Add "require('electron').xxx is undefined." to FAQ --- docs/faq/electron-faq.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index e8f5b191d7a..3e141535af0 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -79,5 +79,18 @@ delete window.module; ``` +## `require('electron').xxx` is undefined. + +When using Electron's built-in module you might encounter an error like this: + +``` +> require('electron').webFrame.setZoomFactor(1.0); +Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined +``` + +This is because you have the npm `electron` module installed either locally or +globally, which overrides Electron's built-in module. You can to either remove +the module, or rename it. + [memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx From 2af7c37d13cfeabbcf548f063e83321cb39b850f Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Tue, 26 Jan 2016 05:30:52 +0900 Subject: [PATCH 052/688] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 6 ++ docs-translations/ko-KR/api/browser-window.md | 18 +++-- docs-translations/ko-KR/api/web-contents.md | 70 +++++++++++++++++++ docs-translations/ko-KR/faq/electron-faq.md | 13 ++++ 4 files changed, 102 insertions(+), 5 deletions(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 5044a6de3e7..cfcd4ee3aab 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -519,6 +519,12 @@ dock 아이콘을 표시합니다. 어플리케이션의 [dock menu][dock-menu]를 설정합니다. +### `app.dock.setIcon(image)` _OS X_ + +* `image` [NativeImage](native-image.md) + +dock 아이콘의 `image`를 설정합니다. + [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 96d2239d20e..f79b201d0a1 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -80,9 +80,9 @@ win.show(); 여부. 기본값은 `false`입니다. * `enableLargerThanScreen` Boolean - 윈도우 크기가 화면 크기보다 크게 재조정 될 수 있는지 여부. 기본값은 `false`입니다. -* `backgroundColor` String - `#66CD00` 와 `#FFF` 같이 16진수로 표현된 윈도우의 - 배경 색. 기본값은 Linux와 Windows에선 `#000` (검정)이며, Mac에선 `#FFF` (또는, - 만약 transparent(투명)일 경우 clear(색 없음)로 설정) +* `backgroundColor` String - `#66CD00` 와 `#FFF`, `#80FFFFFF` (알파 지원됨) 같이 + 16진수로 표현된 윈도우의 배경 색. 기본값은 Linux와 Windows에선 `#000` (검정)이며, + Mac에선 `#FFF` (또는, transparent(투명)일 경우 clear(색 없음)로 설정) * `hasShadow` Boolean - 윈도우가 그림자를 가질지 여부를 지정합니다. 이 속성은 OS X에서만 구현되어 있습니다. 기본값은 `true`입니다. * `darkTheme` Boolean - 설정에 상관 없이 무조건 어두운 윈도우 테마를 사용합니다. @@ -302,6 +302,14 @@ someWindow.on('app-command', function(e, cmd) { }); ``` +### Event: 'scroll-touch-begin' _OS X_ + +스크롤 휠 이벤트가 동작하기 시작했을 때 발생하는 이벤트입니다. + +### Event: 'scroll-touch-end' _OS X_ + +스크롤 휠 이벤트가 동작을 멈췄을 때 발생하는 이벤트입니다. + ## Methods `BrowserWindow` 객체는 다음과 같은 메서드를 가지고 있습니다: @@ -568,14 +576,14 @@ var win = new BrowserWindow({ width: 800, height: 600 }); 사용자에 의해 윈도우를 최대화시킬 수 있는지 여부를 반환합니다. Linux에선 항상 `true`를 반환합니다. -### `win.setFullscreenable(fullscreenable)` _OS X_ +### `win.setFullScreenable(fullscreenable)` _OS X_ * `fullscreenable` Boolean 최대화/줌 버튼이 전체화면 모드 또는 윈도우 최대화를 토글할 수 있게 할지 여부를 지정합니다. Windows와 Linux에선 아무 일도 일어나지 않습니다. -### `win.isFullscreenable()` _OS X_ +### `win.isFullScreenable()` _OS X_ 최대화/줌 버튼이 전체화면 모드 또는 윈도우 최대화를 토글할 수 있게 할지 여부를 반환합니다. Windows와 Linux에선 항상 `true`를 반환합니다. diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 06144fc7e9a..4d688a40944 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -823,3 +823,73 @@ win.webContents.on('did-finish-load', function() { **참고:** 사용자가 절대로 이 객체를 저장해서는 안 됩니다. 개발자 도구가 닫혔을 때, `null`이 반환될 수 있습니다. + +### `webContents.debugger` + +디버거 API는 [원격 디버깅 프로토콜][rdp]에 대한 대체 수송자 역할을 합니다. + +```javascript +try { + win.webContents.debugger.attach("1.1"); +} catch(err) { + console.log("Debugger attach failed : ", err); +}; + +win.webContents.debugger.on('detach', function(event, reason) { + console.log("Debugger detached due to : ", reason); +}); + +win.webContents.debugger.on('message', function(event, method, params) { + if (method == "Network.requestWillBeSent") { + if (params.request.url == "https://www.github.com") + win.webContents.debugger.detach(); + } +}) + +win.webContents.debugger.sendCommand("Network.enable"); +``` + +#### `webContents.debugger.attach([protocolVersion])` + +* `protocolVersion` String (optional) - 요쳥할 디버깅 프로토콜의 버전. + +`webContents`에 디버거를 부착합니다. + +#### `webContents.debugger.isAttached()` + +디버거가 `webContents`에 부착되어 있는지 여부를 반환합니다. + +#### `webContents.debugger.detach()` + +`webContents`로부터 디버거를 분리시킵니다. + +#### `webContents.debugger.sendCommand(method[, commandParams, callback])` + +* `method` String - 메서드 이름, 반드시 원격 디버깅 프로토콜에 의해 정의된 메서드중 + 하나가 됩니다. +* `commandParams` Object (optional) - 요청 매개변수를 표현한 JSON 객체. +* `callback` Function (optional) - 응답 + * `error` Object - 커맨드의 실패를 표시하는 에러 메시지. + * `result` Object - 원격 디버깅 프로토콜에서 커맨드 설명의 'returns' 속성에 의해 + 정의된 응답 + +지정한 커맨드를 디버깅 대상에게 전송합니다. + +#### Event: 'detach' + +* `event` Event +* `reason` String - 디버거 분리 사유. + +디버깅 세션이 종료될 때 발생하는 이벤트입니다. `webContents`가 닫히거나 개발자 도구가 +부착된 `webContents`에 대해 호출될 때 발생합니다. + +#### Event: 'message' + +* `event` Event +* `method` String - 메서드 이름. +* `params` Object - 원격 디버깅 프로토콜의 'parameters' 속성에서 정의된 이벤트 + 매개변수 + +디버깅 타겟이 관련 이벤트를 발생시킬 때 마다 발생하는 이벤트입니다. + +[rdp]: https://developer.chrome.com/devtools/docs/debugger-protocol diff --git a/docs-translations/ko-KR/faq/electron-faq.md b/docs-translations/ko-KR/faq/electron-faq.md index 54ecf64e435..035938715c7 100644 --- a/docs-translations/ko-KR/faq/electron-faq.md +++ b/docs-translations/ko-KR/faq/electron-faq.md @@ -77,5 +77,18 @@ delete window.module; ``` +## `require('electron').xxx`가 undefined를 반환합니다. + +Electron의 빌트인 모듈을 사용할 때, 다음과 같은 오류가 발생할 수 있습니다: + +``` +> require('electron').webFrame.setZoomFactor(1.0); +Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined +``` + +이러한 문제가 발생하는 이유는 npm의 `electron` 모듈이 로컬 또는 전역 중 한 곳에 +설치되어, Electron의 빌트인 모듈을 덮어씌우는 바람에 빌트인 모듈을 사용할 수 없기 +때문입니다. 설치된 모듈을 지우거나 이름을 변경하여 문제를 해결할 수 있습니다. + [memory-management]: https://developer.mozilla.org/ko/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx From 4c43be2148e0c5efc1042e894356acd970621d43 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 26 Jan 2016 17:00:12 +0800 Subject: [PATCH 053/688] docs: Add more on the "electron.xxx" undefined question --- docs/faq/electron-faq.md | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index 3e141535af0..643bde7409b 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -88,9 +88,35 @@ When using Electron's built-in module you might encounter an error like this: Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined ``` -This is because you have the npm `electron` module installed either locally or -globally, which overrides Electron's built-in module. You can to either remove -the module, or rename it. +This is because you have the [npm `electron` module][electron-module] installed +either locally or globally, which overrides Electron's built-in module. + +To verify whether you are using the correct built-in module, you can print the +path of the `electron` module: + +```javascript +console.log(require.resolve('electron')); +``` + +and then check if it is in the following form: + +``` +"/path/to/Electron.app/Contents/Resources/atom.asar/renderer/api/lib/exports/electron.js" +``` + +If it is something like `node_modules/electron/index.js`, then you have to +either remove the npm `electron` module, or rename it. + +```bash +npm uninstall electron +npm uninstall -g electron +``` + +However if your are using the built-in module but still getting this error, it +is very likely you are using the module in wrong process. For example +`electron.app` can only be used in the main process, while `electron.webFrame` +is only available in renderer processes. [memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx +[electron-module]: https://www.npmjs.com/package/electron From ab8e6650bd47e90b0f3aa0aa711f4d0f62447f6e Mon Sep 17 00:00:00 2001 From: Takahito Yamatoya Date: Tue, 26 Jan 2016 18:17:42 +0900 Subject: [PATCH 054/688] :memo:Add Japanes translated docs. [ci skip] --- docs-translations/jp/api/content-tracing.md | 129 +++++++++++++++++ docs-translations/jp/api/protocol.md | 150 ++++++++++++++++++++ docs-translations/jp/api/remote.md | 124 ++++++++++++++++ 3 files changed, 403 insertions(+) create mode 100644 docs-translations/jp/api/content-tracing.md create mode 100644 docs-translations/jp/api/protocol.md create mode 100644 docs-translations/jp/api/remote.md diff --git a/docs-translations/jp/api/content-tracing.md b/docs-translations/jp/api/content-tracing.md new file mode 100644 index 00000000000..f7142a5001b --- /dev/null +++ b/docs-translations/jp/api/content-tracing.md @@ -0,0 +1,129 @@ +# contentTracing + +`content-tracing`モジュールは、Chromiumコンテンツモジュールによって生成されるトーレスデータを収集するのに使われます。このモジュールはウェブインターフェイスを含んでいないので、Chromeブラウザーで `chrome://tracing/`を開いて、結果を表示するために生成されたファイルを読み込む必要があります。 + +```javascript +const contentTracing = require('electron').contentTracing; + +const options = { + categoryFilter: '*', + traceOptions: 'record-until-full,enable-sampling' +} + +contentTracing.startRecording(options, function() { + console.log('Tracing started'); + + setTimeout(function() { + contentTracing.stopRecording('', function(path) { + console.log('Tracing data recorded to ' + path); + }); + }, 5000); +}); +``` + +## メソッド + +`content-tracing`モジュールは次のメソッドを持っています。 + +### `contentTracing.getCategories(callback)` + +* `callback` Function + +カテゴリグループ一式を取得します。新しいコードパスに到達しているとしてカテゴリグループを変更できます。 + +一度、全ての子プロセスが`getCategories`リクエストを認識すると、カテゴリグループの配列で`callback`が呼び出されます。 + +### `contentTracing.startRecording(options, callback)` + +* `options` Object + * `categoryFilter` String + * `traceOptions` String +* `callback` Function + +全てのプロセスで記録を開始します。 + +EnableRecordingリクエストを受信するとすぐに、子プロセス上でただちに非同期にローカルに記録を始めます。全ての子プロセスが`startRecording`リクエストを認識すると、`callback`が呼び出されます。 + +`categoryFilter`はどのカテゴリグループをトレースすべきかをフィルタリングします。フィルターは、マッチしたカテゴリーを含むカテゴリグループを除外する`-`プレフィックスをオプションうぃ持っています。同じリストでの、対象カテゴリパターンと、除外カテゴリーパターンの両方を持つことはサポートしていません。 + +例: + +* `test_MyTest*`, +* `test_MyTest*,test_OtherStuff`, +* `"-excluded_category1,-excluded_category2` + +`traceOptions` は、どの種類のトレースを有効にするかを制御し、コンマ区切りのリストです。 + +取りうるオプション: + +* `record-until-full` +* `record-continuously` +* `trace-to-console` +* `enable-sampling` +* `enable-systrace` + +最初の3つのオプションは、トレースの記録モードで、そのため相互排他的です。`traceOptions`文字列に1つ以上のトレース記録モードが現れると、最後のモードが優先されます。トレース記録モードが指定されていない場合、記録モードは、`record-until-full`です。 + +適用される`traceOptions`からオプションをパースする前に、トレースオプションは最初に既定のオプションにリセットされます(`record_mode`は、`record-until-full`を設定し、 `enable_sampling`と `enable_systrace` は `false`に設定します)。 + +### `contentTracing.stopRecording(resultFilePath, callback)` + +* `resultFilePath` String +* `callback` Function + +全てのプロセスで記録を止めます。 + +子プロセスは基本的にトレースデータをキャッシュし、まれにフラッシュし、メインプロセスにトレースデータを送り返します。IPC越しにトレースデータを送信するのは高コストな操作なので、トレースのランタイムオーバーヘッドを最小限にするのに役立ちます。トレースが終了すると、保留されているトレースデータのフラッシュをするためにすべての子プロセスに非道に問い合わせすべきです。 + + +一度、すべての子プロセスが`stopRecording` リクエストを認識すると、トレースデータを含んだファイルで`callback`が呼び出されます。 + +トレースデータは`resultFilePath`が空でなければ、そこに書き込まれ、空の場合は一時ファイルに書き込まれます。実際のファイルパスは`null`でなければ `callback` に通します。 + +### `contentTracing.startMonitoring(options, callback)` + +* `options` Object + * `categoryFilter` String + * `traceOptions` String +* `callback` Function + +全てのプロセス上で監視を開始します。 + +`startMonitoring`リクエスト受信するとすぐに、子プロセス上でローカルに非同期にただちに監視を始めます。 + +全ての子プロセスが`startMonitoring`リクエストを認識すると、`callback`がコールされます。 + +### `contentTracing.stopMonitoring(callback)` + +* `callback` Function + +全てのプロセス上で監視を止めます。 + +全ての子プロセスが`stopMonitoring`リクエスト認識すると、`callback`がコールされます。 + +### `contentTracing.captureMonitoringSnapshot(resultFilePath, callback)` + +* `resultFilePath` String +* `callback` Function + +現在の監視トレースデータを取得します。子プロセスは基本的にトレースデータをキャッシュし、まれにフラッシュし、メインプロセスにトレースデータを送り返します。IPC越しにトレースデータを送信するのは高コストな操作なので、トレースによる不必要なランタイムオーバーヘッドを避けるます。トレースが終了するために、保留されているトレースデータのフラッシュをするためにすべての子プロセスに非道に問い合わせすべきです。 + +全ての子プロセスが`captureMonitoringSnapshot`リクエストを認識すると、トレースデータを含んだファイルで`callback`が呼び出されます。 + +### `contentTracing.getTraceBufferUsage(callback)` + +* `callback` Function + +プロセスのトレースバッファのプロセス間で最大使用量をフルの状態の何%かで取得します。TraceBufferUsage値が設定されていると、 `callback`がコールされます。 + +### `contentTracing.setWatchEvent(categoryName, eventName, callback)` + +* `categoryName` String +* `eventName` String +* `callback` Function + +プロセス上でイベント発生すると、その度に`callback`がコールされます。 + +### `contentTracing.cancelWatchEvent()` + +イベントウオッチをキャンセルします。トレースが有効になっていると、監視イベントのコールバックとの競合状態になる可能性があります。 diff --git a/docs-translations/jp/api/protocol.md b/docs-translations/jp/api/protocol.md new file mode 100644 index 00000000000..841c64512a7 --- /dev/null +++ b/docs-translations/jp/api/protocol.md @@ -0,0 +1,150 @@ +# protocol + +`protocol`モジュールはカスタムプロトコルを登録したり、または既存のプロトコルをインターセプタ―することができます。 + +`file://`プロトコルの同様の効果をもつプロトコルを実装した例です。 + +```javascript +const electron = require('electron'); +const app = electron.app; +const path = require('path'); + +app.on('ready', function() { + var protocol = electron.protocol; + protocol.registerFileProtocol('atom', function(request, callback) { + var url = request.url.substr(7); + callback({path: path.normalize(__dirname + '/' + url)}); + }, function (error) { + if (error) + console.error('Failed to register protocol') + }); +}); +``` + +**Note:** このモジュールは、`app`モジュールで`ready`イベントが出力された後のみ使うことができます。 + +## メソッド + +`protocol`モジュールは、次のメソッドを持ちます。 + +### `protocol.registerStandardSchemes(schemes)` + +* `schemes` Array - 標準的なスキーマーを登録するためのカスタムスキーマー + +標準的な`scheme`は、RFC 3986で策定している[generic URI syntax](https://tools.ietf.org/html/rfc3986#section-3)に準拠しています。これには`file:` と `filesystem:`を含んでいます。 + +### `protocol.registerServiceWorkerSchemes(schemes)` + +* `schemes` Array - サービスワーカーをハンドルするために登録されたカスタムスキーマー + +### `protocol.registerFileProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (optional) + +レスポンスとしてファイルを送信する`scheme`のプロトコルを登録します。`scheme`で`request`が生成された時、`handler`は`handler(request, callback)`で呼び出されます。`scheme` 登録が成功したり、`completion(error)`が失敗したときに、`completion` は`completion(null)`で呼び出されます。 + +`request`をハンドルするために、`callback`はファイルパスまたは`path`プロパティを持つオブジェクトで呼び出すべきです。例えば、`callback(filePath)` または`callback({path: filePath})`です。 + +何もなし、数字、`error`プロパティを持つオブジェクトで、`callback`が呼び出された時、 `request`は指定した`error`番号で失敗します。使用できる提供されているエラー番号は、[net error list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h)を参照してください。 + +既定では、`scheme`は、`file:`のような一般的なURIの構文に続くプロトコルと違う解析がされ、`http:`のように扱われます。なので、恐らく標準的なスキーマーのように扱われるスキーマーを持つために、`protocol.registerStandardSchemes` を呼び出したくなります。 + +### `protocol.registerBufferProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (optional) + +レスポンスとして`Buffer`を送信する`scheme`プロトコルを登録します。`callback`は、`Buffer`オブジェクトまたは`data`と `mimeType`、`chart`プロパティを持つオブジェクトを呼び出す必要があります。 + +例: + +```javascript +protocol.registerBufferProtocol('atom', function(request, callback) { + callback({mimeType: 'text/html', data: new Buffer('
Response
')}); +}, function (error) { + if (error) + console.error('Failed to register protocol') +}); +``` + +### `protocol.registerStringProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (optional) + +レスポンスとして`String`を送信する`scheme`プロトコルを登録します。`callback`は、`String`または`data`と `mimeType`、`chart`プロパティを持つオブジェクトを呼び出す必要があります。 + +### `protocol.registerHttpProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (optional) + +レスポンスとしてHTTPリクエストを送信する`scheme`プロトコルを登録します。`callback`は、`url`と`method`、`referrer`、`uploadData`、`session`プロパティを持つオブジェクトを呼び出す必要があります。 + +既定では、HTTPリクエストは現在のセッションを再利用します。別のセッションでリクエストをしたい場合、`session` に `null`を設定する必要があります。 + +POSTリクエストは`uploadData`オブジェクトを提供する必要があります。 +* `uploadData` object + * `contentType` String - コンテンツのMIMEタイプ + * `data` String - 送信されるコンテンツ + +### `protocol.unregisterProtocol(scheme[, completion])` + +* `scheme` String +* `completion` Function (optional) + +`scheme`のカスタムプロトコルを解除します。 + +### `protocol.isProtocolHandled(scheme, callback)` + +* `scheme` String +* `callback` Function + +`scheme`のハンドラーがあるかないかを示すブーリアン値で`callback`がコールされます。 + +### `protocol.interceptFileProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (optional) + +`scheme`プロトコルをインターセプタ―し、レスポンスとしてファイルを送信するプロトコルの新しいハンドラーとして`handler`を使います。 + +### `protocol.interceptStringProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (optional) + +`scheme`プロトコルをインターセプタ―し、レスポンスとして`String`を送信するプロトコルの新しいハンドラーとして`handler`を使います。 + +### `protocol.interceptBufferProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (optional) + +`scheme`プロトコルをインターセプタ―し、レスポンスとして`Buffer`を送信するプロトコルの新しいハンドラーとして`handler`を使います。 + +### `protocol.interceptHttpProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (optional) + +`scheme`プロトコルをインターセプタ―し、レスポンスとして新しいHTTPリクエストを送信するプロトコルの新しいハンドラーとして`handler`を使います。 + +Intercepts `scheme` protocol and uses `handler` as the protocol's new handler +which sends a new HTTP request as a response. + +### `protocol.uninterceptProtocol(scheme[, completion])` + +* `scheme` String +* `completion` Function + +インターセプタ―したインストールされた`scheme`を削除し、オリジナルハンドラーをリストアします。 diff --git a/docs-translations/jp/api/remote.md b/docs-translations/jp/api/remote.md new file mode 100644 index 00000000000..0d4ec0d389e --- /dev/null +++ b/docs-translations/jp/api/remote.md @@ -0,0 +1,124 @@ +# remote + + `remote`モジュールは、レンダラープロセス(ウェブページ)とメインプロセス間でインタープロセスコミュニケーション(IPC)をする簡単な方法を提供します。 + +Electronでは、GUI関連モジュール(`dialog`や`menu`など)はメインプロセスのみに提供されており、レンダラープロセスには提供されていません。レンダラープロセスからそれらを使うために、`ipc`モジュールはメインプロセスにインタープロセスメッセージを送信するのに必要です。`remote`モジュールで、Javaの[RMI][rmi]と同じように、はっきりとインタープロセスメッセージを送信しなくてもメインプロセスオブジェクトのメソッドを呼び出せます。 + +レンダラープロセスからブラウザーウィンドウを作成する例: + +```javascript +const remote = require('electron').remote; +const BrowserWindow = remote.BrowserWindow; + +var win = new BrowserWindow({ width: 800, height: 600 }); +win.loadURL('https://github.com'); +``` + +**Note:** 逆には(メインプロセスからレンダラープロセスにアクセスする)、[webContents.executeJavascript](web-contents.md#webcontentsexecutejavascriptcode-usergesture)が使えます。 + +## Remote オブジェクト + +`remote`モジュールから返されるそれぞれのオブジェクト(関数含む)はメインプロセスでオブジェクトを示します(リモートオブジェクトまたはリモート関数と呼ばれます)。リモートプロジェクトのメソッドを実行したり、リモート関数をコールしたり、リモートコンストラクター(関数)で新しいオブジェクトを生成したりしたとき、実際に非同期にインタープロセスメッセージが送信されます。 + +上の例では、`BrowserWindow` と `win` はリモートオブジェクトで、`new BrowserWindow`はレンダラープロセスで `BrowserWindow`を作成しません。代わりに、メインプロセスで`BrowserWindow` オブジェクトが作成され、レンダラープロセスで対応するリモートオブジェクトを返し、すなわち`win`オブジェクトです。 + +リモート経由でのみアクセスできる [enumerable properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties)に注意してください。 + +## Remote オブジェクトのライフタイム + +Electronは、レンダラープロセスのリモートオブジェクトが生きている限り(言い換えれば、ガベージコレクションされません)、対応するメインプロセスのオブジェクトは解放されないことを確認してください。リモートオブジェクトがガベージコレクションされたとき、対応するメインプロセスのオブジェクトが間接参照されます。 + +レンダラープロセスでリモートオブジェクトがリークした場合(マップに格納されているが解放されない)、メインプロセスで対応するオブジェクトもリークするので、リモートオブジェクトがリークしないように細心の注意を払うべきです。 + +文字列や数字のようなプライマリ値は、コピーして送信します。 + +## メインプロセスにコールバックを通す + +メインプロセスのコードは、レンダラーからコールバックを受け取ることができます。例えば、`remote`モジュールです。この機能をとても慎重に使うべきです。 + +最初に、デッドロックを避けるために、メインプロセスに渡されたコールバックは非同期に呼び出されます。メインプロセスは、渡されたコールバックの戻り値を取得することを期待すべきではありません。 + +例えば、メインプロセスでコールされた`Array.map`で、レンダラープロセスから関数を使用することはできません。: + +```javascript +// main process mapNumbers.js +exports.withRendererCallback = function(mapper) { + return [1,2,3].map(mapper); +} + +exports.withLocalCallback = function() { + return exports.mapNumbers(function(x) { + return x + 1; + }); +} +``` + +```javascript +// renderer process +var mapNumbers = require("remote").require("./mapNumbers"); + +var withRendererCb = mapNumbers.withRendererCallback(function(x) { + return x + 1; +}) + +var withLocalCb = mapNumbers.withLocalCallback() + +console.log(withRendererCb, withLocalCb) // [true, true, true], [2, 3, 4] +``` + +見ることができるように、レンダラーコールバックの同期戻り値は予想されなかったとして、メインプロセスで生きている同一のコールバックの戻り値と一致しません。 + +第二に、メインプロセスに渡されるコールバックはメインプロセスがガベージコレクトするまで存続します。 + +例えば、次のコードは一目で無害なコードのように思えます。リモートオブジェクト上で`close`イベントのコールバックをインストールしています。 + +```javascript +remote.getCurrentWindow().on('close', function() { + // blabla... +}); +``` + +りかし、明確にアンインストールするまでメインプロセスによってコールバックは参照されることを覚えておいてください。アンインストールしない場合、ウィンドウをリロードするたびに、コールバックは再度インストールされ、それぞれの再起動時にコールバックあリークします。 + +さらに悪いことに、前にインストールされたコールバックのコンテキストは解放されるので、`close`イベントを出力されると、メインプロセスで例外が発生します。 + +この問題を避けるために、メインプロセスに渡されたレンダラーコールバックへの参照をクリーンアップを確認します。これにはイベントハンドラーのクリンアップも含まれ、存在しているレンダラープロセスから来るコールバックを確実にメインプロセスが守るように確認します。 + +## メインプロセスで組み込みモジュールにアクセスする + +メインプロセスの組み込みモジュールは、`remote`モジュールでゲッターとして追加されるので、`electron`モジュールのように直接それらを使用できます。 + +```javascript +const app = remote.app; +``` + +## メソッド + +`remote`モジュールは次のメソッドを持ちます。 + +### `remote.require(module)` + +* `module` String + +メインプロセスで、`require(module)`で返されるオブジェクトを返します。 + +### `remote.getCurrentWindow()` + +このウェブページに属する[`BrowserWindow`](browser-window.md) オブジェクトを返します。 + +### `remote.getCurrentWebContents()` + +このウェブページの[`WebContents`](web-contents.md) オブジェクトを返します。 + +### `remote.getGlobal(name)` + +* `name` String + +メインプロセスで、`name`のグローバル変数(例えば、`global[name]`)を返します。 + + +### `remote.process` + +メインプロセスで`process`オブジェクトを返します。これは`remote.getGlobal('process')`と同様ですが、キャッシュされます。 + +[rmi]: http://en.wikipedia.org/wiki/Java_remote_method_invocation From 205b2455f2da6dc2dbc728ca2fcfd10bd7af7173 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 26 Jan 2016 20:23:32 +0800 Subject: [PATCH 055/688] Update node --- vendor/node | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/node b/vendor/node index 3b044608ee5..a130651f868 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit 3b044608ee51ca001dabe944cade6e64f46b0724 +Subproject commit a130651f868f5ad23cb366abacea02f9ed50b769 From d0587a9c52ed6863ebc8d1f2c4d9c8a176eb82f5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 26 Jan 2016 20:26:42 +0800 Subject: [PATCH 056/688] spec: process.stdout.write --- spec/node-spec.js | 19 +++++++++++++------ spec/static/main.js | 3 +++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/spec/node-spec.js b/spec/node-spec.js index c7a74efd6c7..6f84f59921f 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -190,17 +190,24 @@ describe('node feature', function() { return assert.equal(Buffer.byteLength(p.innerText), 13); }); }); + describe('process.stdout', function() { it('should not throw exception', function() { - return process.stdout; + process.stdout; }); - return xit('should have isTTY defined', function() { - return assert.equal(typeof process.stdout.isTTY, 'boolean'); + + it('should not throw exception when calling write()', function() { + process.stdout.write('test'); + }); + + xit('should have isTTY defined', function() { + assert.equal(typeof process.stdout.isTTY, 'boolean'); }); }); - return describe('vm.createContext', function() { - return it('should not crash', function() { - return require('vm').runInNewContext(''); + + describe('vm.createContext', function() { + it('should not crash', function() { + require('vm').runInNewContext(''); }); }); }); diff --git a/spec/static/main.js b/spec/static/main.js index c49b2318de6..4419a2219b0 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -28,6 +28,9 @@ app.commandLine.appendSwitch('disable-renderer-backgrounding'); // sure we can reproduce it in renderer process. process.stdout; +// Access console to reproduce #3482. +console; + ipcMain.on('message', function(event, arg) { event.sender.send('message', arg); }); From 864449db89b509154f99c2f0854e95f45ffbc373 Mon Sep 17 00:00:00 2001 From: Paul P Date: Tue, 26 Jan 2016 14:44:46 +0000 Subject: [PATCH 057/688] prevent assignment to constant variable (url) --- atom/browser/api/lib/auto-updater/auto-updater-win.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/atom/browser/api/lib/auto-updater/auto-updater-win.js b/atom/browser/api/lib/auto-updater/auto-updater-win.js index e7d6daca927..4c3edd3dcd2 100644 --- a/atom/browser/api/lib/auto-updater/auto-updater-win.js +++ b/atom/browser/api/lib/auto-updater/auto-updater-win.js @@ -45,8 +45,7 @@ class AutoUpdater extends EventEmitter { // Following information is not available on Windows, so fake them. date = new Date; - url = _this.updateURL; - return _this.emit('update-downloaded', {}, releaseNotes, version, date, url, function() { + return _this.emit('update-downloaded', {}, releaseNotes, version, date, _this.updateURL, function() { return _this.quitAndInstall(); }); }); From cbf11f38ca35832500064bf40964b8b9158f0e07 Mon Sep 17 00:00:00 2001 From: Paul P Date: Tue, 26 Jan 2016 14:55:31 +0000 Subject: [PATCH 058/688] remove unused variable --- atom/browser/api/lib/auto-updater/auto-updater-win.js | 1 - 1 file changed, 1 deletion(-) diff --git a/atom/browser/api/lib/auto-updater/auto-updater-win.js b/atom/browser/api/lib/auto-updater/auto-updater-win.js index 4c3edd3dcd2..f8a07902f21 100644 --- a/atom/browser/api/lib/auto-updater/auto-updater-win.js +++ b/atom/browser/api/lib/auto-updater/auto-updater-win.js @@ -2,7 +2,6 @@ const app = require('electron').app; const EventEmitter = require('events').EventEmitter; -const url = require('url'); const squirrelUpdate = require('./squirrel-update-win'); class AutoUpdater extends EventEmitter { From b01d677086efefbcac8bea46eb1a7e51d0488c48 Mon Sep 17 00:00:00 2001 From: Wen Luo Date: Wed, 27 Jan 2016 11:41:03 +0800 Subject: [PATCH 059/688] Update application-distribution.md Remove duplicated words. --- docs-translations/zh-CN/tutorial/application-distribution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/zh-CN/tutorial/application-distribution.md b/docs-translations/zh-CN/tutorial/application-distribution.md index c1fddce15ea..22a5078c1fa 100644 --- a/docs-translations/zh-CN/tutorial/application-distribution.md +++ b/docs-translations/zh-CN/tutorial/application-distribution.md @@ -103,7 +103,7 @@ MyApp.app/Contents ### grunt打包脚本 -手动的检查 Electron 代码并重编译是很复杂晦涩的,因此有一个 Grunt任务可以自动自动的处理 +手动检查 Electron 代码并重编译是很复杂晦涩的,因此有一个Grunt任务可以自动的处理 这些内容 [grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell). 这个任务会自动的处理编辑 `.gyp` 文件,从源代码进行编译,然后重编译你的应用程序的本地 Node 模块以匹配这个新的可执行文件的名称。 From 4ab68461238631c2c81dfd17c7f4037a9ccafe68 Mon Sep 17 00:00:00 2001 From: Takahito Yamatoya Date: Wed, 27 Jan 2016 15:17:24 +0900 Subject: [PATCH 060/688] :memo:Add Japanes translated docs. [ci skip] --- docs-translations/jp/api/session.md | 434 ++++++++++++++++++++++++++++ 1 file changed, 434 insertions(+) create mode 100644 docs-translations/jp/api/session.md diff --git a/docs-translations/jp/api/session.md b/docs-translations/jp/api/session.md new file mode 100644 index 00000000000..9385ac3e891 --- /dev/null +++ b/docs-translations/jp/api/session.md @@ -0,0 +1,434 @@ +# session + +`session`モジュールは、新しい`Session`オブジェクトを作成するのに使われます。 + +[`BrowserWindow`](browser-window.md)のプロパティである [`webContents`](web-contents.md)プロパティの`session`を使うことで既存ページの `session`にアクセスできます。 + +```javascript +const BrowserWindow = require('electron').BrowserWindow; + +var win = new BrowserWindow({ width: 800, height: 600 }); +win.loadURL("http://github.com"); + +var ses = win.webContents.session; +``` + +## メソッド + + `session`メソッドは次のメソッドを持ちます: + +### session.fromPartition(partition) + +* `partition` String + +`partition`文字列から新しい`Session`インスタンスを返します。 + +`partition`が`persist:`から始まっている場合、同じ`partition`のアプリ内のすべてのページに永続セッションを提供するのにページが使います。`persist:`プレフィックスが無い場合、ページはインメモリセッションを使います。`partition`が空の場合、アプリの既定のセッションを返します。 + +## プロパティ + +`session`モジュールは次のプロパティを持ちます: + +### session.defaultSession + +アプリの既定のセッションオブジェクトを返します。 + +## クラス: Session + +`session`モジュールで、`Session`オブジェクトを作成できます: + +```javascript +const session = require('electron').session; + +var ses = session.fromPartition('persist:name'); +``` + +### インスタンスイベント + +`Session`のインスタンス上で次のイベントが提供されます: + +#### イベント: 'will-download' + +* `event` Event +* `item` [DownloadItem](download-item.md) +* `webContents` [WebContents](web-contents.md) + +Electronが`webContents`で`item`をダウンロードしようとすると出力されます。 + +`event.preventDefault()` をコールするとダウンロードをキャンセルできます。 + +```javascript +session.defaultSession.on('will-download', function(event, item, webContents) { + event.preventDefault(); + require('request')(item.getURL(), function(data) { + require('fs').writeFileSync('/somewhere', data); + }); +}); +``` + +### インスタンスのメソッド + +`Session`のインスタンス上で次のメソッドが提供されています: + +#### `ses.cookies` + +`cookies`は、cookiesに問い合わせしたり、修正をできるようにします。例: + +```javascript +// Query all cookies. +session.defaultSession.cookies.get({}, function(error, cookies) { + console.log(cookies); +}); + +// Query all cookies associated with a specific url. +session.defaultSession.cookies.get({ url : "http://www.github.com" }, function(error, cookies) { + console.log(cookies); +}); + +// Set a cookie with the given cookie data; +// may overwrite equivalent cookies if they exist. +var cookie = { url : "http://www.github.com", name : "dummy_name", value : "dummy" }; +session.defaultSession.cookies.set(cookie, function(error) { + if (error) + console.error(error); +}); +``` + +#### `ses.cookies.get(filter, callback)` + +* `filter` Object + * `url` String (オプション) - `url`に関連付けられているcookiesを取得します。空の場合すべてのurlのcookiesを取得します + * `name` String (オプション) - `name`でcookiesをフィルタリングします + * `domain` String (オプション) - `domains`のドメインまたはサブドメインに一致するcookiesを取得します + * `path` String (オプション) - `path`に一致するパスのcookiesを取得します + * `secure` Boolean (オプション) - Secure プロパティでcookiesをフィルターします + * `session` Boolean (オプション) - Filters out `session`または永続cookiesを除外します +* `callback` Function + +`details`に一致するすべてのcookiesを取得するためにリクエストを送信し、完了時に`callback(error, cookies)`で`callback`がコールされます。 + +`cookies` は`cookie`オブジェクトの配列です。 + +* `cookie` Object + * `name` String - cookieの名前 + * `value` String - cookieの値 + * `domain` String - cookieのドメイン + * `hostOnly` String - cookieがホストのみのcookieかどうか + * `path` String - cookieのパス + * `secure` Boolean - cookieがセキュアとマークされているかどうか + * `httpOnly` Boolean - HTTPのみとしてcookieがマークされているかどうか + * `session` Boolean - cookieがセッションcookieまたは有効期限付きの永続cookieかどうか + * `expirationDate` Double (オプション) - + +cookieの有効期限をUNIX時間で何秒かを示します。セッションcookiesは提供されません。 + +#### `ses.cookies.set(details, callback)` + +* `details` Object + * `url` String - `url`に関連付けられているcookiesを取得します。 + * `name` String - cookieの名前。省略した場合、既定では空です。 + * `value` String - cookieの名前。省略した場合、既定では空です。 + * `domain` String - cookieのドメイン。省略した場合、既定では空です。 + * `path` String - cookieのパス。 省略した場合、既定では空です。 + * `secure` Boolean - cookieをセキュアとしてマークする必要があるかどうか。既定ではfalseです。 + * `session` Boolean - cookieをHTTPのみとしてマークする必要があるかどうか。既定ではfalseです。 + * `expirationDate` Double - cookieの有効期限をUNIX時間で何秒か。省略した場合、cookieはセッションcookieになります。 +* `callback` Function + +`details`でcookieを設定し、完了すると`callback(error)`で`callback`がコールされます。 + +#### `ses.cookies.remove(url, name, callback)` + +* `url` String - cookieに関連付けられているURL +* `name` String - 削除するcookieの名前 +* `callback` Function + +`url` と `name`と一致するcookiesを削除し、完了すると`callback`が、`callback()`でコールされます。 + +#### `ses.getCacheSize(callback)` + +* `callback` Function + * `size` Integer - 使用しているキャッシュサイズバイト数 + +現在のセッションのキャッシュサイズを返します。 + +#### `ses.clearCache(callback)` + +* `callback` Function - 操作が完了したら、コールされます。 + +セッションのHTTPキャッシュをクリアします。 + +#### `ses.clearStorageData([options, ]callback)` + +* `options` Object (オプション) + * `origin` String - `window.location.origin`の説明で、`scheme://host:port`に従う + * `storages` Array - クリアするストレージの種類で、次を含められます: + `appcache`、 `cookies`、 `filesystem`、 `indexdb`、 `local storage`、 + `shadercache`、 `websql`、 `serviceworkers` + * `quotas` Array - クリアするクォーターの種類で、次を含められます: + `temporary`, `persistent`, `syncable`. +* `callback` Function - 操作をするとコールされます。 + +ウェブストレージのデータをクリアします。 + +#### `ses.flushStorageData()` + +書き込まれていないDOMStorageデータをディスクに書き込みます。 + +#### `ses.setProxy(config, callback)` + +* `config` Object + * `pacScript` String - PACファイルに関連付けらえたURL + * `proxyRules` String - 使用するプロキシを指定するルール +* `callback` Function - 操作をするとコールされます。 + +プロキシ設定を設定します。 + +`pacScript` と `proxyRules`が一緒に渡されたら、`proxyRules`オプションは無視され、`pacScript`設定が適用されます。 + + `proxyRules`はつふぃのルールに従います。 + +``` +proxyRules = schemeProxies[";"] +schemeProxies = ["="] +urlScheme = "http" | "https" | "ftp" | "socks" +proxyURIList = [","] +proxyURL = ["://"][":"] +``` + +具体例: +* `http=foopy:80;ftp=foopy2` - `http://`URLは`foopy:80`HTTPプロキシを使用し、`ftp://`URLは`foopy2:80` HTTPプロキシを使用します。 +* `foopy:80` - 全てのURLで`foopy:80`を使用します。 +* `foopy:80,bar,direct://` - 全てのURLで`foopy:80`HTTPプロキシを使用し、`foopy:80`が提供されていなければ`bar`を使用し、さらに使えない場合はプロキシを使いません。 +* `socks4://foopy` - 全てのURLでSOCKS `foopy:1080`プロキシを使います。 +* `http=foopy,socks5://bar.com` - http URLで`foopy`HTTPプロキシを使い、`foopy`が提供されていなければ、SOCKS5 proxy `bar.com`を使います。 +* `http=foopy,direct://` -  http URLで`foopy`HTTPプロキシを使い、`foopy`が提供されていなければ、プロキシを使いません。 +* `http=foopy;socks=foopy2` - http URLで`foopy`HTTPプロキシを使い、それ以外のすべてのURLで`socks4://foopy2`を使います。 + +### `ses.resolveProxy(url, callback)` + +* `url` URL +* `callback` Function + +`url`をプロキシ情報で解決します。リクエストが実行された時、`callback(proxy)`で `callback`がコールされます。 + +#### `ses.setDownloadPath(path)` + +* `path` String - ダウンロード場所 + +ダウンロードの保存ディレクトリを設定します。既定では、ダウンロードディレクトリは、個別のアプリフォルダー下の`Downloads`です。 + +#### `ses.enableNetworkEmulation(options)` + +* `options` Object + * `offline` Boolean - ネットワーク停止を再現するかどうか + * `latency` Double - RTT ms秒 + * `downloadThroughput` Double - Bpsでのダウンロード割合 + * `uploadThroughput` Double - Bpsでのアップロード割合 + +再現ネットワークは、`session`用の設定を付与します。 + +```javascript +// To emulate a GPRS connection with 50kbps throughput and 500 ms latency. +window.webContents.session.enableNetworkEmulation({ + latency: 500, + downloadThroughput: 6400, + uploadThroughput: 6400 +}); + +// To emulate a network outage. +window.webContents.session.enableNetworkEmulation({offline: true}); +``` + +#### `ses.disableNetworkEmulation()` + +`session`ですでに有効になっているネットワークエミュレーションを無効化します。オリジナルのネットワーク設定にリセットします。 + +#### `ses.setCertificateVerifyProc(proc)` + +* `proc` Function + +`session`の証明書検証ロジックを設定し、サーバー証明書確認がリクエストされた時、`proc(hostname, certificate, callback)`で`proc`がコールされます。`callback(true)`がコールされると証明書を受け入れ、`callback(false)`がコールされると拒否します。 + +Calling `setCertificateVerifyProc(null)`をコールして、既定の証明書検証ロジックに戻します。 + +```javascript +myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, callback) { + if (hostname == 'github.com') + callback(true); + else + callback(false); +}); +``` + +#### `ses.webRequest` + +`webRequest`APIセットをインターセプトし、そのライフタイムの様々な段階でリクエストの内容を変更できます。 + +APIのイベントが発生したとき、それぞれのAPIはオプションで`filter`と `listener`を受け入れ、`listener(details)` で`listener`がコールされ、`details`はリクエストを説明するオブジェクトです。`listener`に`null`が渡されるとイベントの購読をやめます。 + +`filter`は`urls`プロパティを持つオブジェクトで、URLパターンにマッチしないリクエストを除外するのに使われるURLパターンの配列です。`filter`を省略した場合、全てのリクエストにマッチします。 + +いくつかのイベントで`callback`で`listener`に渡され、`listener`が動作するとき、`response`オブジェクトでコールされる必要があります。 + +```javascript +// Modify the user agent for all requests to the following urls. +var filter = { + urls: ["https://*.github.com/*", "*://electron.github.io"] +}; + +session.defaultSession.webRequest.onBeforeSendHeaders(filter, function(details, callback) { + details.requestHeaders['User-Agent'] = "MyAgent"; + callback({cancel: false, requestHeaders: details.requestHeaders}); +}); +``` + +#### `ses.webRequest.onBeforeRequest([filter, ]listener)` + +* `filter` Object +* `listener` Function + +リクエストが発生しようとしている時、`listener(details, callback)`で`listener` がコールされます。 + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + +`callback`は`response`オブジェクトでコールされる必要があります: + +* `response` Object + * `cancel` Boolean (オプション) + * `redirectURL` String (オプション) - オリジナルリクエストが送信もしくは完了するのを中断し、代わりに付与したURLにリダイレクトします。 + +#### `ses.webRequest.onBeforeSendHeaders([filter, ]listener)` + +* `filter` Object +* `listener` Function + +リクエストヘッダーが提供されれば、HTTPリクエストが送信される前に、`listener(details, callback)`で`listener`がコールされます。TCP接続がサーバーに対して行われた後に発生することがありますが、HTTPデータは送信前です。 + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `requestHeaders` Object + +The `callback` has to be called with an `response` object: + +* `response` Object + * `cancel` Boolean (オプション) + * `requestHeaders` Object (オプション) - 付与されると、リクエストはそれらのヘッダーで作成されます。 + +#### `ses.webRequest.onSendHeaders([filter, ]listener)` + +* `filter` Object +* `listener` Function + +サーバーにリクエストを送信しようする直前に`listener(details)`で、`listener` がコールされます。前回の`onBeforeSendHeaders`レスポンスの変更箇所は、このリスナーが起動した時点で表示されます。 + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `requestHeaders` Object + +#### `ses.webRequest.onHeadersReceived([filter,] listener)` + +* `filter` Object +* `listener` Function + +リクエストのHTTPレスポンスヘッダーを受信したとき、`listener`は`listener(details, callback)`でコールされます。 + +* `details` Object + * `id` String + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `statusLine` String + * `statusCode` Integer + * `responseHeaders` Object + +`callback`は`response`オブジェクトでコールされる必要があります: + +* `response` Object + * `cancel` Boolean + * `responseHeaders` Object (オプション) - 付与されていると、これらのヘッダーでサーバーはレスポンスしたと仮定します。 + +#### `ses.webRequest.onResponseStarted([filter, ]listener)` + +* `filter` Object +* `listener` Function + +レスポンスボディの最初のバイトを受信したとき、`listener` は`listener(details)` でコールされます。HTTPリクエストでは、ステータス行とレスポンスヘッダーを意味します。 + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `responseHeaders` Object + * `fromCache` Boolean -ディスクキャッシュから取得したレスポンスかどうかを示します + * `statusCode` Integer + * `statusLine` String + +#### `ses.webRequest.onBeforeRedirect([filter, ]listener)` + +* `filter` Object +* `listener` Function + +サーバーがリダイレクトを開始しはじめたとき、`listener(details)`で`listener` がコールされます。 + +* `details` Object + * `id` String + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `redirectURL` String + * `statusCode` Integer + * `ip` String (オプション) - 実際にリクエストが送信されるサーバーIPアドレス + * `fromCache` Boolean + * `responseHeaders` Object + +#### `ses.webRequest.onCompleted([filter, ]listener)` + +* `filter` Object +* `listener` Function + +リクエスト完了時、`listener`が`listener(details)`でコールされます。 + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `responseHeaders` Object + * `fromCache` Boolean + * `statusCode` Integer + * `statusLine` String + +#### `ses.webRequest.onErrorOccurred([filter, ]listener)` + +* `filter` Object +* `listener` Function + +エラー発生時、 `listener(details)` で`listener`がコールされます。 + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `fromCache` Boolean + * `error` String - エラーの説明 From 8011578e8c624ee700f7bccebf97f3f3aa6c8dcc Mon Sep 17 00:00:00 2001 From: Veck Hsiao Date: Wed, 27 Jan 2016 14:48:06 +0800 Subject: [PATCH 061/688] Add Traditional Chinese Translation Page supported-platforms.md --- .../zh-TW/tutorial/supported-platforms.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 docs-translations/zh-TW/tutorial/supported-platforms.md diff --git a/docs-translations/zh-TW/tutorial/supported-platforms.md b/docs-translations/zh-TW/tutorial/supported-platforms.md new file mode 100644 index 00000000000..225bc9b2b55 --- /dev/null +++ b/docs-translations/zh-TW/tutorial/supported-platforms.md @@ -0,0 +1,26 @@ +# 支援的平台 + +Electron 已支援以下平台: + +### OS X + +OS X 系統只有 64 位元的執行檔,且 OS X 的最低版本要求為 OS X 10.8。 + +### Windows + +Windows 7 和更新的版本都有支援,早期的作業系統都不支援(且無法運作)。 + + + +`x86` 和 `amd64` (x64) 的執行檔都有提供,請注意,`ARM` 版本的 Electron 還沒有支援。 + +### Linux + +已經建置好的 `ia32`(`i686`) 和 `x64`(`amd64`) Electron 執行檔都是在 Ubuntu 12.04 的環境下編譯,`arm` 執行檔是在 hard-float ABI 和 +Debian Wheezy 的 NEON 的 ARM v7 下編譯的。 + +已建置好的執行檔是否能夠成功在 Linux 發行版執行,要看該發行版在建置的平台上是否含有 Electron 會連結的函式庫,所以只有 Ubuntu 12.04 是已確定可以運行的,而以下平台也都有驗證過可以運行已建置好的 Electron 執行檔: + +* Ubuntu 12.04 and later +* Fedora 21 +* Debian 8 From 3ca941a94970cec65ce05e7978c0a3f328394806 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 27 Jan 2016 21:03:23 +0800 Subject: [PATCH 062/688] Update brightray for #4223 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 3edbdfdf520..7b721379562 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 3edbdfdf52015309df78fb586143c833e3c01b25 +Subproject commit 7b7213795623ce16523460fb2c3642728515c94b From dc0151099c787b81a4e99ff04c40fa347e2464e6 Mon Sep 17 00:00:00 2001 From: Robo Date: Tue, 26 Jan 2016 13:58:21 +0530 Subject: [PATCH 063/688] session: provide uploadData with webrequest api when available --- atom/browser/net/atom_network_delegate.cc | 4 ++ .../native_mate_converters/net_converter.cc | 70 +++++++++++-------- .../native_mate_converters/net_converter.h | 11 +++ docs/api/session.md | 3 + spec/api-web-request-spec.js | 29 ++++++++ 5 files changed, 88 insertions(+), 29 deletions(-) diff --git a/atom/browser/net/atom_network_delegate.cc b/atom/browser/net/atom_network_delegate.cc index 4f9bc835ed2..f993138ccc5 100644 --- a/atom/browser/net/atom_network_delegate.cc +++ b/atom/browser/net/atom_network_delegate.cc @@ -75,6 +75,10 @@ void ToDictionary(base::DictionaryValue* details, net::URLRequest* request) { details->SetString("resourceType", info ? ResourceTypeToString(info->GetResourceType()) : "other"); + scoped_ptr list(new base::ListValue); + GetUploadData(list.get(), request); + if (!list->empty()) + details->Set("uploadData", list.Pass()); } void ToDictionary(base::DictionaryValue* details, diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 7a1b48d9311..94081b88a3d 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -10,6 +10,7 @@ #include "atom/common/node_includes.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/value_converter.h" +#include "base/values.h" #include "native_mate/dictionary.h" #include "net/base/upload_bytes_element_reader.h" #include "net/base/upload_data_stream.h" @@ -24,35 +25,15 @@ namespace mate { // static v8::Local Converter::ToV8( v8::Isolate* isolate, const net::URLRequest* val) { - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - dict.Set("method", val->method()); - dict.Set("url", val->url().spec()); - dict.Set("referrer", val->referrer()); - const net::UploadDataStream* upload_data = val->get_upload(); - if (upload_data) { - const ScopedVector* readers = - upload_data->GetElementReaders(); - std::vector upload_data_list; - upload_data_list.reserve(readers->size()); - for (const auto& reader : *readers) { - auto upload_data_dict = mate::Dictionary::CreateEmpty(isolate); - if (reader->AsBytesReader()) { - const net::UploadBytesElementReader* bytes_reader = - reader->AsBytesReader(); - auto bytes = - node::Buffer::Copy(isolate, bytes_reader->bytes(), - bytes_reader->length()).ToLocalChecked(); - upload_data_dict.Set("bytes", bytes); - } else if (reader->AsFileReader()) { - const net::UploadFileElementReader* file_reader = - reader->AsFileReader(); - upload_data_dict.Set("file", file_reader->path().AsUTF8Unsafe()); - } - upload_data_list.push_back(upload_data_dict); - } - dict.Set("uploadData", upload_data_list); - } - return mate::ConvertToV8(isolate, dict); + scoped_ptr dict(new base::DictionaryValue); + dict->SetString("method", val->method()); + dict->SetStringWithoutPathExpansion("url", val->url().spec()); + dict->SetString("referrer", val->referrer()); + scoped_ptr list(new base::ListValue); + atom::GetUploadData(list.get(), val); + if (!list->empty()) + dict->Set("uploadData", list.Pass()); + return mate::ConvertToV8(isolate, *(dict.get())); } // static @@ -83,3 +64,34 @@ v8::Local Converter>::ToV8( } } // namespace mate + +namespace atom { + +void GetUploadData(base::ListValue* upload_data_list, + const net::URLRequest* request) { + const net::UploadDataStream* upload_data = request->get_upload(); + if (!upload_data) + return; + const ScopedVector* readers = + upload_data->GetElementReaders(); + for (const auto& reader : *readers) { + scoped_ptr upload_data_dict( + new base::DictionaryValue); + if (reader->AsBytesReader()) { + const net::UploadBytesElementReader* bytes_reader = + reader->AsBytesReader(); + scoped_ptr bytes( + base::BinaryValue::CreateWithCopiedBuffer(bytes_reader->bytes(), + bytes_reader->length())); + upload_data_dict->Set("bytes", bytes.Pass()); + } else if (reader->AsFileReader()) { + const net::UploadFileElementReader* file_reader = + reader->AsFileReader(); + auto file_path = file_reader->path().AsUTF8Unsafe(); + upload_data_dict->SetStringWithoutPathExpansion("file", file_path); + } + upload_data_list->Append(upload_data_dict.Pass()); + } +} + +} // namespace atom diff --git a/atom/common/native_mate_converters/net_converter.h b/atom/common/native_mate_converters/net_converter.h index b11c55929b9..b7fd9481a20 100644 --- a/atom/common/native_mate_converters/net_converter.h +++ b/atom/common/native_mate_converters/net_converter.h @@ -8,6 +8,10 @@ #include "base/memory/ref_counted.h" #include "native_mate/converter.h" +namespace base { +class ListValue; +} + namespace net { class AuthChallengeInfo; class URLRequest; @@ -36,4 +40,11 @@ struct Converter> { } // namespace mate +namespace atom { + +void GetUploadData(base::ListValue* upload_data_list, + const net::URLRequest* request); + +} // namespace atom + #endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ diff --git a/docs/api/session.md b/docs/api/session.md index ffed58797c4..1bef70e5105 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -332,6 +332,9 @@ is about to occur. * `method` String * `resourceType` String * `timestamp` Double + * `uploadData` Array (optional) + * `bytes` Buffer - Content being sent. + * `file` String - Path of file being uploaded. The `callback` has to be called with an `response` object: diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index 6731d995a61..91b84c77e1b 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -1,5 +1,6 @@ const assert = require('assert'); const http = require('http'); +const qs = require('querystring'); const remote = require('electron').remote; const session = remote.session; @@ -83,6 +84,7 @@ describe('webRequest module', function() { assert.equal(details.url, defaultURL); assert.equal(details.method, 'GET'); assert.equal(details.resourceType, 'xhr'); + assert(!details.uploadData); return callback({}); }); return $.ajax({ @@ -96,6 +98,33 @@ describe('webRequest module', function() { } }); }); + it('receives post data in details object', function(done) { + var postData = { + name: 'post test', + type: 'string' + }; + ses.webRequest.onBeforeRequest(function(details, callback) { + var data; + assert.equal(details.url, defaultURL); + assert.equal(details.method, 'POST'); + assert.equal(details.uploadData.length, 1); + data = qs.parse(details.uploadData[0].bytes.toString()); + assert.deepEqual(data, postData); + return callback({ + cancel: true + }); + }); + return $.ajax({ + url: defaultURL, + type: 'POST', + data: postData, + success: function() { + }, + error: function() { + done(); + } + }); + }); return it('can redirect the request', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { if (details.url === defaultURL) { From a6bcc5d110053a1d287203656f31dedc0c1008f6 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 27 Jan 2016 14:14:10 +0530 Subject: [PATCH 064/688] common: export hideInternalModules --- atom/common/api/lib/exports/electron.js | 6 +++++- script/test.py | 3 --- spec/api-app-spec.js | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/atom/common/api/lib/exports/electron.js b/atom/common/api/lib/exports/electron.js index 5b93d286da6..6811e73a10b 100644 --- a/atom/common/api/lib/exports/electron.js +++ b/atom/common/api/lib/exports/electron.js @@ -1,5 +1,5 @@ // Do not expose the internal modules to `require`. -exports.hideInternalModules = function() { +const hideInternalModules = function() { var globalPaths = require('module').globalPaths; if (globalPaths.length === 3) { @@ -11,6 +11,10 @@ exports.hideInternalModules = function() { // Attaches properties to |exports|. exports.defineProperties = function(exports) { return Object.defineProperties(exports, { + hideInternalModules: { + enumerable: true, + value: hideInternalModules + }, // Common modules, please sort with alphabet order. clipboard: { diff --git a/script/test.py b/script/test.py index 7f75d3113d6..28aeac9dc1f 100755 --- a/script/test.py +++ b/script/test.py @@ -16,9 +16,6 @@ PRODUCT_NAME = atom_gyp()['product_name%'] def main(): os.chdir(SOURCE_ROOT) - # Disable old APIs - os.environ['ELECTRON_HIDE_INTERNAL_MODULES'] = 'true' - config = 'D' if len(sys.argv) == 2 and sys.argv[1] == '-R': config = 'R' diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index dafaf44a2d1..0019ec59d5f 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -10,6 +10,21 @@ remote = require('electron').remote; ref = remote.require('electron'), app = ref.app, BrowserWindow = ref.BrowserWindow; +describe('electron module', function() { + it ('can prevent exposing internal modules to require', function(done) { + const electron = require('electron'); + const clipboard = require('clipboard'); + assert.equal(typeof clipboard, 'object'); + electron.hideInternalModules(); + try { + require('clipboard'); + } catch(err) { + assert.equal(err.message, 'Cannot find module \'clipboard\''); + done(); + } + }); +}); + describe('app module', function() { describe('app.getVersion()', function() { return it('returns the version field of package.json', function() { From c4df96df6718b6fa56152bc97031d7e8add5ca0b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 27 Jan 2016 23:19:22 +0800 Subject: [PATCH 065/688] Update brightray to fix compilation error --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 7b721379562..ea6011bc960 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 7b7213795623ce16523460fb2c3642728515c94b +Subproject commit ea6011bc9607f321258bf93e510f56f031973230 From 172fc917687daf85140a0c2c51d62c974dfb2007 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 28 Jan 2016 03:26:35 +0900 Subject: [PATCH 066/688] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/faq/electron-faq.md | 33 +++++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/docs-translations/ko-KR/faq/electron-faq.md b/docs-translations/ko-KR/faq/electron-faq.md index 035938715c7..0978dc00539 100644 --- a/docs-translations/ko-KR/faq/electron-faq.md +++ b/docs-translations/ko-KR/faq/electron-faq.md @@ -86,9 +86,36 @@ Electron의 빌트인 모듈을 사용할 때, 다음과 같은 오류가 발생 Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined ``` -이러한 문제가 발생하는 이유는 npm의 `electron` 모듈이 로컬 또는 전역 중 한 곳에 -설치되어, Electron의 빌트인 모듈을 덮어씌우는 바람에 빌트인 모듈을 사용할 수 없기 -때문입니다. 설치된 모듈을 지우거나 이름을 변경하여 문제를 해결할 수 있습니다. +이러한 문제가 발생하는 이유는 [npm의 `electron` 모듈][electron-module]이 로컬 또는 +전역 중 한 곳에 설치되어, Electron의 빌트인 모듈을 덮어씌우는 바람에 빌트인 모듈을 +사용할 수 없기 때문입니다. + +올바른 빌트인 모듈을 사용하고 있는지 확인하고 싶다면, `electron` 모듈의 경로를 +출력하는 방법이 있습니다: + +```javascript +console.log(require.resolve('electron')); +``` + +그리고 다음과 같은 경로를 가지는지 점검하면 됩니다: + +``` +"/path/to/Electron.app/Contents/Resources/atom.asar/renderer/api/lib/exports/electron.js" +``` + +하지만 `node_modules/electron/index.js`와 같은 경로로 되어있을 경우, `electron` +모듈을 지우거나 이름을 바꿔야만 합니다. + +```bash +npm uninstall electron +npm uninstall -g electron +``` + +그런데 여전히 빌트인 모듈이 계속해서 문제를 발생시키는 경우, 아마 모듈을 잘못 사용하고 +있을 가능성이 큽니다. 예를 들면 `electron.app`은 메인 프로세스에서만 사용할 수 있는 +모듈이며, 반면 `electron.webFrame` 모듈은 랜더러 프로세스에서만 사용할 수 있는 +모듈입니다. [memory-management]: https://developer.mozilla.org/ko/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx +[electron-module]: https://www.npmjs.com/package/electron From e6fbb0adfaa44d192112c9fb39597253133d94ed Mon Sep 17 00:00:00 2001 From: fbukevin Date: Thu, 28 Jan 2016 14:20:35 +0800 Subject: [PATCH 067/688] translate zh-TW tutorial application-distribution.md --- .../tutorial/application-distribution.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 docs-translations/zh-TW/tutorial/application-distribution.md diff --git a/docs-translations/zh-TW/tutorial/application-distribution.md b/docs-translations/zh-TW/tutorial/application-distribution.md new file mode 100644 index 00000000000..60d32f88be0 --- /dev/null +++ b/docs-translations/zh-TW/tutorial/application-distribution.md @@ -0,0 +1,108 @@ +# 應用程式部署 + +要部屬你的 Electron 應用程式,你需要把你的應用程式資料夾命名為 `app`,並放置於 Electron 的資源目錄下 (在 OS X 中位在 `Electron.app/Contents/Resources/` 而 Linux 和 Windows 的是在 `resources/`),例如: + +OS X: + +```text +electron/Electron.app/Contents/Resources/app/ +├── package.json +├── main.js +└── index.html +``` + +Windows 和 Linux: + +```text +electron/resources/app +├── package.json +├── main.js +└── index.html +``` + +然後執行 `Electron.app` (或者在 Linux 中是 `electron`, Windows 中是 `electron.exe`),然後 Electron 將會啟動你的應用程式,目錄 `electron` 會接著被部署給最後使用者。 + +## 打包你的應用程式成一個檔案 + +除了透過複製所有原始檔案來發布你的應用程式,你也可以使用 [asar](https://github.com/atom/asar) 來打包你的應用程式為一個壓縮檔,來避免暴露你的原始碼給使用者。 + +要使用 `asar` 壓縮檔來取代 `app` 資料夾,你需要重新命名該壓縮檔為 `app.asar`,然後如下所示把它放到 Electron 的資源目錄中,接著 Electron 就會試著讀取壓縮檔並從它開始執行。 + +OS X: + +```text +electron/Electron.app/Contents/Resources/ +└── app.asar +``` + +Windows 和 Linux: + +```text +electron/resources/ +└── app.asar +``` + +更多詳細的介紹請參閱 [應用程式打包](application-packaging.md). + +## 重新塑造你的下載執行檔品牌形象 + +當你完成 Electron 的應用程式打包後,在發布給使用者前,你會想想要重新塑造你的 Electron。 + +### Windows + +你可以重新命名 `electron.exe` 為任何你喜歡的名稱,然後透過像是 [rcedit](https://github.com/atom/rcedit) 或 +[ResEdit](http://www.resedit.net) 的工具來編輯它的圖示(icon)和其他資訊。 + +### OS X + +你可以重新命名 `Electron.app` 為任何你喜歡的名稱,另外你也需要重新命名下列檔案中的 `CFBundleDisplayName`、`CFBundleIdentifier` 和 `CFBundleName` 欄位: + +* `Electron.app/Contents/Info.plist` +* `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist` + +你也可以重新命名 helper 應用程式來避免在活動監視器中秀出 `Electron Helper` +,但請確認你有重新命名 helper 應用程式的可執行檔名稱。 + +重新命名後的應用程式檔案結構可能長得相這樣: + +``` +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` 可執行檔為任何你想要的名字。 + +## 透過重新建置 Electron 原始碼重塑品牌形象 + +你也可以透過改變產品名稱和重新建置原始碼來重塑 Electron 的品牌形象,要這麼做的話,你需要修改 `atom.gyp` 檔案並在重新建置前清理已建置的所有檔案。 + +### grunt-build-atom-shell + +手動取得 Electron 的原始碼和重新建置可能事件複雜的事,因此有一個建立好的 Grunt 任務(task)可以自動化的處理這些事情: +[grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell). + +這個任務將會自動的處理編輯 `.gyp` 檔,建置原始碼,然後重新建置你的應用程式原生 Node 模組來符合新的可執行檔名稱。 + +## 打包工具 + +除了手動打包你的應用程式,你也可以選擇使用第三方打包工具來幫助你: + +* [electron-packager](https://github.com/maxogden/electron-packager) +* [electron-builder](https://github.com/loopline-systems/electron-builder) From 1da13625d1fdf042a77dbecfee722bd638289352 Mon Sep 17 00:00:00 2001 From: fbukevin Date: Thu, 28 Jan 2016 16:46:28 +0800 Subject: [PATCH 068/688] WIP: docs-translations/zh-TW/tutorial/application-packaging.md --- .../zh-TW/tutorial/application-packaging.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 docs-translations/zh-TW/tutorial/application-packaging.md diff --git a/docs-translations/zh-TW/tutorial/application-packaging.md b/docs-translations/zh-TW/tutorial/application-packaging.md new file mode 100644 index 00000000000..301e7663156 --- /dev/null +++ b/docs-translations/zh-TW/tutorial/application-packaging.md @@ -0,0 +1,167 @@ +# 應用程式打包 + +為了減少圍繞著 Windows 上長路徑名稱問題的 [issues](https://github.com/joyent/node/issues/6960) ,稍微地加速 `require` 和隱藏你的原始碼避免不小心被看到,你可以選擇把你的應用程式打包成一個 [asar][asar] 壓縮檔,只需要改變一點點你的原始碼就好。 +## 產生 `asar` 壓縮檔 + +一個 [asar][asar] 壓縮檔是一個簡單的類 tar 格式的檔案,它會把幾個檔案串接成一個檔案, Electron 可以不需要解壓縮整個檔案就從中讀取任意檔案。 + +把你的應用程式打包成 `asar` 壓縮檔的步驟: + +### 1. 安裝 asar 工具包 + +```bash +$ npm install -g asar +``` + +### 2. 用 `asar pack` 打包 + +```bash +$ asar pack your-app app.asar +``` + +## 使用 `asar` 壓縮檔 + +在 Electron 中有兩組 API:Node.js 提供的 Node APIs 和 Chromium 提供的 Web +APIs,兩組 API 都支援從 `asar` 壓縮檔中讀取檔案。 + +### Node API + +因為 Electron 中有一些特別的補釘,像是 `fs.readFile` 和 `require` 這樣的 Node API 會將 `asar` 壓縮檔視為許多虛擬目錄,將裡頭的檔案視為在檔案系統上的一般檔案。 + +例如,假設我們有一個 `example.asar` 壓縮檔在 `/path/to` 中: + +```bash +$ asar list /path/to/example.asar +/app.js +/file.txt +/dir/module.js +/static/index.html +/static/main.css +/static/jquery.min.js +``` + +讀取一個在 `asar` 壓縮檔中的檔案: + +```javascript +const fs = require('fs'); +fs.readFileSync('/path/to/example.asar/file.txt'); +``` + +列出所有在壓縮檔根目錄下的檔案: + +```javascript +const fs = require('fs'); +fs.readdirSync('/path/to/example.asar'); +``` + +使用一個壓縮檔中的模組: + +```javascript +require('/path/to/example.asar/dir/module.js'); +``` + +你也可以利用 `BrowserWindow` 在 `asar` 壓縮檔中呈現一個網頁: + +```javascript +const BrowserWindow = require('electron').BrowserWindow; +var win = new BrowserWindow({width: 800, height: 600}); +win.loadURL('file:///path/to/example.asar/static/index.html'); +``` + +### Web API + +在一個網頁中,壓縮檔中的檔案都可以透過 `file:` 這個協定被存取,如同 Node API,`asar` 壓縮檔都被視為目錄。 + +例如,要透過 `$.get` 取得一個檔案: + +```html + +``` + +### 把一個 `asar` 壓縮檔視為一般檔案 + +在一些像是驗證 `asar` 壓縮檔檢查碼(checksum)的例子中,我們需要以檔案的方式讀取 `asar` 壓縮檔中的內容,為了達到這個目的,你可以使用內建的 +`original-fs` 模組,它提供了沒有 `asar` 支援的原生 `fs` API: + +```javascript +var originalFs = require('original-fs'); +originalFs.readFileSync('/path/to/example.asar'); +``` + +你也可以設定 `process.noAsar` 為 `true` 來關掉在 `fs` 模組中的 `asar` 支援: + +```javascript +process.noAsar = true; +fs.readFileSync('/path/to/example.asar'); +``` + +## Node API 上的限制 + +儘管我們盡可能的努力嘗試著使 Node API 中的 `asar` 壓縮檔像目錄一樣運作,還是有一些基於 Node API 低階本質的限制存在。 + +### 壓縮檔都是唯讀的 + +所有壓縮檔都無法被修改,因此所有可以修改檔案的 Node API 都無法與 `asar ` 壓縮檔一起運作。 + +### 使用中的目錄無法被設為壓縮檔中的目錄 + +儘管 `asar` 壓縮檔被視為目錄,卻並沒有真正的目錄在檔案系統中,所以你永遠無法將使用中的目錄設定成 `asar` 壓縮檔中的目錄,把他們以 `cwd` 選項的方式傳遞,對某些 API 也會造成錯誤。 + +### Extra Unpacking on Some APIs + +Most `fs` APIs can read a file or get a file's information from `asar` archives +without unpacking, but for some APIs that rely on passing the real file path to +underlying system calls, Electron will extract the needed file into a +temporary file and pass the path of the temporary file to the APIs to make them +work. This adds a little overhead for those APIs. + +APIs that requires extra unpacking are: + +* `child_process.execFile` +* `child_process.execFileSync` +* `fs.open` +* `fs.openSync` +* `process.dlopen` - Used by `require` on native modules + +### Fake Stat Information of `fs.stat` + +The `Stats` object returned by `fs.stat` and its friends on files in `asar` +archives is generated by guessing, because those files do not exist on the +filesystem. So you should not trust the `Stats` object except for getting file +size and checking file type. + +### Executing Binaries Inside `asar` Archive + +There are Node APIs that can execute binaries like `child_process.exec`, +`child_process.spawn` and `child_process.execFile`, but only `execFile` is +supported to execute binaries inside `asar` archive. + +This is because `exec` and `spawn` accept `command` instead of `file` as input, +and `command`s are executed under shell. There is no reliable way to determine +whether a command uses a file in asar archive, and even if we do, we can not be +sure whether we can replace the path in command without side effects. + +## Adding Unpacked Files in `asar` Archive + +As stated above, some Node APIs will unpack the file to filesystem when +calling, apart from the performance issues, it could also lead to false alerts +of virus scanners. + +To work around this, you can unpack some files creating archives by using the +`--unpack` option, an example of excluding shared libraries of native modules +is: + +```bash +$ asar pack app app.asar --unpack *.node +``` + +After running the command, apart from the `app.asar`, there is also an +`app.asar.unpacked` folder generated which contains the unpacked files, you +should copy it together with `app.asar` when shipping it to users. + +[asar]: https://github.com/atom/asar From 3c9e08faf10613bb1d2dcfe589655ebf24eeada7 Mon Sep 17 00:00:00 2001 From: Veck Hsiao Date: Thu, 28 Jan 2016 18:15:44 +0800 Subject: [PATCH 069/688] finished translate application-packaging.md --- .../zh-TW/tutorial/application-packaging.md | 45 ++++++------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/docs-translations/zh-TW/tutorial/application-packaging.md b/docs-translations/zh-TW/tutorial/application-packaging.md index 301e7663156..438d513e2bb 100644 --- a/docs-translations/zh-TW/tutorial/application-packaging.md +++ b/docs-translations/zh-TW/tutorial/application-packaging.md @@ -112,56 +112,39 @@ fs.readFileSync('/path/to/example.asar'); 儘管 `asar` 壓縮檔被視為目錄,卻並沒有真正的目錄在檔案系統中,所以你永遠無法將使用中的目錄設定成 `asar` 壓縮檔中的目錄,把他們以 `cwd` 選項的方式傳遞,對某些 API 也會造成錯誤。 -### Extra Unpacking on Some APIs +### 更多透過 API 拆封的方法 -Most `fs` APIs can read a file or get a file's information from `asar` archives -without unpacking, but for some APIs that rely on passing the real file path to -underlying system calls, Electron will extract the needed file into a -temporary file and pass the path of the temporary file to the APIs to make them -work. This adds a little overhead for those APIs. +大部分 `fs` API 可以讀取一個檔案,或是不用拆封就從 `asar` 壓縮檔中取得一個檔案的資訊,但對一些需要傳遞真實檔案路徑給現行系統呼叫的 API ,Electron 將會解開需要的檔案到一個暫時的檔案,然後傳遞該暫時檔案的路徑給那些 API 以便使他們可以運作,這會增加這些 API 一點負擔。 -APIs that requires extra unpacking are: + +需要額外拆封的 API : * `child_process.execFile` * `child_process.execFileSync` * `fs.open` * `fs.openSync` -* `process.dlopen` - Used by `require` on native modules +* `process.dlopen` - 在原生模組中被 `require` 使用 -### Fake Stat Information of `fs.stat` +### `fs.stat` 的不真實的狀態資訊 -The `Stats` object returned by `fs.stat` and its friends on files in `asar` -archives is generated by guessing, because those files do not exist on the -filesystem. So you should not trust the `Stats` object except for getting file -size and checking file type. +`fs.stat` 回傳的 `Stats` 物件和它在 `asar` 壓縮檔中的檔案朋友都是以猜測的方式產生的,因為那些檔案不存在檔案系統,所以你不應該信任 `Stats` 物件,除了取得檔案大小和確認檔案型態之外。 -### Executing Binaries Inside `asar` Archive +### 執行 `asar` 壓縮檔中的二進位檔 -There are Node APIs that can execute binaries like `child_process.exec`, -`child_process.spawn` and `child_process.execFile`, but only `execFile` is -supported to execute binaries inside `asar` archive. +有像是 `child_process.exec`、`child_process.spawn` 和 `child_process.execFile` 的 Node APIs 可以執行二進位檔,但只有 `execFile` 是 `asar` 壓縮檔中可以執行二進位檔的。 -This is because `exec` and `spawn` accept `command` instead of `file` as input, -and `command`s are executed under shell. There is no reliable way to determine -whether a command uses a file in asar archive, and even if we do, we can not be -sure whether we can replace the path in command without side effects. +這是因為 `exec` 和 `spawn` 接受的輸入是 `command` 而不是 `file`,而 `command` 們都是在 shell 底下執行,我們找不到可靠的方法來決定是否一個命令使用一個在 `asar` 壓縮檔中的檔案,而儘管我們找得到,我們也無法確定是否我們可以在沒有外部影響(side effect)的情況下替換掉命令中的路徑。 -## Adding Unpacked Files in `asar` Archive +## 加入拆封檔案到 `asar` 壓縮檔中 -As stated above, some Node APIs will unpack the file to filesystem when -calling, apart from the performance issues, it could also lead to false alerts -of virus scanners. +如前述,一些 Node API 再被呼叫時會拆封檔案到檔案系統,除了效能議題外,它也會導致掃毒軟體發出 false alerts。 -To work around this, you can unpack some files creating archives by using the -`--unpack` option, an example of excluding shared libraries of native modules -is: +要繞過這個問題,你可以透過使用 `--unpack` 選向來拆封一些建立壓縮檔的檔案,以下是一個不包含共享原生模組的函式庫的例子: ```bash $ asar pack app app.asar --unpack *.node ``` -After running the command, apart from the `app.asar`, there is also an -`app.asar.unpacked` folder generated which contains the unpacked files, you -should copy it together with `app.asar` when shipping it to users. +執行這個命令以後,除了 `app.asar` 以外,還有一個帶有拆封檔案的 `app.asar.unpacked` 資料夾被產生出來,當你要發布給使用者時,你應該把它和 `app.asar` 一起複。 [asar]: https://github.com/atom/asar From 223b440bc870e3218c9a4eddc2fe1b7365c13a66 Mon Sep 17 00:00:00 2001 From: fbukevin Date: Thu, 28 Jan 2016 18:20:39 +0800 Subject: [PATCH 070/688] prepare for retaining "Guides" pages --- .../zh-TW/tutorial/debugging-main-process.md | 76 ++++++++++ .../zh-TW/tutorial/devtools-extension.md | 62 ++++++++ .../mac-app-store-submission-guide.md | 120 ++++++++++++++++ .../tutorial/using-native-node-modules.md | 67 +++++++++ .../tutorial/using-pepper-flash-plugin.md | 50 +++++++ .../tutorial/using-selenium-and-webdriver.md | 132 ++++++++++++++++++ 6 files changed, 507 insertions(+) create mode 100644 docs-translations/zh-TW/tutorial/debugging-main-process.md create mode 100644 docs-translations/zh-TW/tutorial/devtools-extension.md create mode 100644 docs-translations/zh-TW/tutorial/mac-app-store-submission-guide.md create mode 100644 docs-translations/zh-TW/tutorial/using-native-node-modules.md create mode 100644 docs-translations/zh-TW/tutorial/using-pepper-flash-plugin.md create mode 100644 docs-translations/zh-TW/tutorial/using-selenium-and-webdriver.md diff --git a/docs-translations/zh-TW/tutorial/debugging-main-process.md b/docs-translations/zh-TW/tutorial/debugging-main-process.md new file mode 100644 index 00000000000..6fbb858bc28 --- /dev/null +++ b/docs-translations/zh-TW/tutorial/debugging-main-process.md @@ -0,0 +1,76 @@ +# Debugging the Main Process + +The browser window DevTools can only debug the renderer process scripts (i.e. +the web pages). In order to provide a way to debug the scripts from the main +process, Electron has provided the `--debug` and `--debug-brk` switches. + +## Command Line Switches + +Use the following command line switches to debug Electron's main process: + +### `--debug=[port]` + +When this switch is used Electron will listen for V8 debugger protocol +messages on `port`. The default `port` is `5858`. + +### `--debug-brk=[port]` + +Like `--debug` but pauses the script on the first line. + +## Use node-inspector for Debugging + +__Note:__ Electron doesn't currently work very well +with node-inspector, and the main process will crash if you inspect the +`process` object under node-inspector's console. + +### 1. Make sure you have [node-gyp required tools][node-gyp-required-tools] installed + +### 2. Install [node-inspector][node-inspector] + +```bash +$ npm install node-inspector +``` + +### 3. Install a patched version of `node-pre-gyp` + +```bash +$ npm install git+https://git@github.com/enlight/node-pre-gyp.git#detect-electron-runtime-in-find +``` + +### 4. Recompile the `node-inspector` `v8` modules for electron (change the target to your electron version number) + +```bash +$ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-debug/ --dist-url=https://atom.io/download/atom-shell reinstall +$ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-profiler/ --dist-url=https://atom.io/download/atom-shell reinstall +``` + +See also [How to install native modules](how-to-install-native-modules). + +### 5. Enable debug mode for Electron + +You can either start Electron with a debug flag like: + +```bash +$ electron --debug=5858 your/app +``` + +or, to pause your script on the first line: + +```bash +$ electron --debug-brk=5858 your/app +``` + +### 6. Start the [node-inspector][node-inspector] server using electron + +```bash +$ ELECTRON_RUN_AS_NODE=true path/to/electron.exe node_modules/node-inspector/bin/inspector.js +``` + +### 7. Load the debugger UI + +Open http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 in the Chrome browser. You may have to click pause if starting with debug-brk to see the entry line. + +[node-inspector]: https://github.com/node-inspector/node-inspector +[node-gyp-required-tools]: https://github.com/nodejs/node-gyp#installation +[how-to-install-native-modules]: using-native-node-modules.md#how-to-install-native-modules + diff --git a/docs-translations/zh-TW/tutorial/devtools-extension.md b/docs-translations/zh-TW/tutorial/devtools-extension.md new file mode 100644 index 00000000000..7c7ea7d64a2 --- /dev/null +++ b/docs-translations/zh-TW/tutorial/devtools-extension.md @@ -0,0 +1,62 @@ +# DevTools Extension + +To make debugging easier, Electron has basic support for the +[Chrome DevTools Extension][devtools-extension]. + +For most DevTools extensions you can simply download the source code and use +the `BrowserWindow.addDevToolsExtension` API to load them. The loaded extensions +will be remembered so you don't need to call the API every time when creating +a window. + +** NOTE: React DevTools does not work, follow the issue here https://github.com/atom/electron/issues/915 ** + +For example, to use the [React DevTools Extension](https://github.com/facebook/react-devtools) +, first you need to download its source code: + +```bash +$ cd /some-directory +$ git clone --recursive https://github.com/facebook/react-devtools.git +``` + +Follow the instructions in [`react-devtools/shells/chrome/Readme.md`](https://github.com/facebook/react-devtools/blob/master/shells/chrome/Readme.md) to build the extension. + +Then you can load the extension in Electron by opening DevTools in any window, +and running the following code in the DevTools console: + +```javascript +const BrowserWindow = require('electron').remote.BrowserWindow; +BrowserWindow.addDevToolsExtension('/some-directory/react-devtools/shells/chrome'); +``` + +To unload the extension, you can call the `BrowserWindow.removeDevToolsExtension` +API with its name and it will not load the next time you open the DevTools: + +```javascript +BrowserWindow.removeDevToolsExtension('React Developer Tools'); +``` + +## Format of DevTools Extension + +Ideally all DevTools extensions written for the Chrome browser can be loaded by +Electron, but they have to be in a plain directory. For those packaged with +`crx` extensions, there is no way for Electron to load them unless you find a +way to extract them into a directory. + +## Background Pages + +Currently Electron doesn't support the background pages feature in Chrome +extensions, so some DevTools extensions that rely on this feature may +not work in Electron. + +## `chrome.*` APIs + +Some Chrome extensions may use `chrome.*` APIs for features and while there has +been some effort to implement those APIs in Electron, not all have been +implemented. + +Given that not all `chrome.*` APIs are implemented if the DevTools extension is +using APIs other than `chrome.devtools.*`, the extension is very likely not to +work. You can report failing extensions in the issue tracker so that we can add +support for those APIs. + +[devtools-extension]: https://developer.chrome.com/extensions/devtools diff --git a/docs-translations/zh-TW/tutorial/mac-app-store-submission-guide.md b/docs-translations/zh-TW/tutorial/mac-app-store-submission-guide.md new file mode 100644 index 00000000000..036676fe853 --- /dev/null +++ b/docs-translations/zh-TW/tutorial/mac-app-store-submission-guide.md @@ -0,0 +1,120 @@ +# Mac App Store Submission Guide + +Since v0.34.0, Electron allows submitting packaged apps to the Mac App Store +(MAS). This guide provides information on: how to submit your app and the +limitations of the MAS build. + +__Note:__ Submitting an app to Mac App Store requires enrolling [Apple Developer +Program][developer-program], which costs money. + +## How to Submit Your App + +The following steps introduce a simple way to submit your app to Mac App Store. +However, these steps do not ensure your app will be approved by Apple; you +still need to read Apple's [Submitting Your App][submitting-your-app] guide on +how to meet the Mac App Store requirements. + +### Get Certificate + +To submit your app to the Mac App Store, you first must get a certificate from +Apple. You can follow these [existing guides][nwjs-guide] on web. + +### Sign Your App + +After getting the certificate from Apple, you can package your app by following +[Application Distribution](application-distribution.md), and then proceed to +signing your app. This step is basically the same with other programs, but the +key is to sign every dependency of Electron one by one. + +First, you need to prepare two entitlements files. + +`child.plist`: + +```xml + + + + + com.apple.security.app-sandbox + + com.apple.security.inherit + + + +``` + +`parent.plist`: + +```xml + + + + + com.apple.security.app-sandbox + + + +``` + +And then sign your app with the following script: + +```bash +#!/bin/bash + +# Name of your app. +APP="YourApp" +# The path of you app to sign. +APP_PATH="/path/to/YouApp.app" +# The path to the location you want to put the signed package. +RESULT_PATH="~/Desktop/$APP.pkg" +# The name of certificates you requested. +APP_KEY="3rd Party Mac Developer Application: Company Name (APPIDENTITY)" +INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)" + +FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" + +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Libraries/libnode.dylib" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Electron Framework" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper.app/" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper EH.app/" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper NP.app/" +codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" +productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" +``` + +If you are new to app sandboxing under OS X, you should also read through +Apple's [Enabling App Sandbox][enable-app-sandbox] to have a basic idea, then +add keys for the permissions needed by your app to the entitlements files. + +### Upload Your App and Submit for Review + +After signing your app, you can use Application Loader to upload it to iTunes +Connect for processing, making sure you have [created a record][create-record] +before uploading. Then you can [submit your app for review][submit-for-review]. + +## Limitations of MAS Build + +In order to satisfy all requirements for app sandboxing, the following modules +have been disabled in the MAS build: + +* `crash-reporter` +* `auto-updater` + +and the following behaviors have been changed: + +* Video capture may not work for some machines. +* Certain accessibility features may not work. +* Apps will not be aware of DNS changes. + +Also, due to the usage of app sandboxing, the resources which can be accessed by + the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for + more information. + +[developer-program]: https://developer.apple.com/support/compare-memberships/ +[submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html +[nwjs-guide]: https://github.com/nwjs/nw.js/wiki/Mac-App-Store-%28MAS%29-Submission-Guideline#first-steps +[enable-app-sandbox]: https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html +[create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html +[submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html +[app-sandboxing]: https://developer.apple.com/app-sandboxing/ diff --git a/docs-translations/zh-TW/tutorial/using-native-node-modules.md b/docs-translations/zh-TW/tutorial/using-native-node-modules.md new file mode 100644 index 00000000000..2defedd7418 --- /dev/null +++ b/docs-translations/zh-TW/tutorial/using-native-node-modules.md @@ -0,0 +1,67 @@ +# Using Native Node Modules + +The native Node modules are supported by Electron, but since Electron is +using a different V8 version from official Node, you have to manually specify +the location of Electron's headers when building native modules. + +## Native Node Module Compatibility + +Native modules might break when Node starts using a new version of V8. +To make sure the module you're interested in will work with Electron, you should +check if it supports the internal Node version used by Electron. +You can check what version of Node is used in Electron by looking it up in +the [releases](https://github.com/atom/electron/releases) page or by using +`process.version` (see [Quick Start](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md) +for example). + +Consider using [NAN](https://github.com/nodejs/nan/) for your own modules, since +it makes it easier to support multiple versions of Node. It's also helpful for +porting old modules to newer versions of Node so they can work with Electron. + +## How to Install Native Modules + +Three ways to install native modules: + +### The Easy Way + +The most straightforward way to rebuild native modules is via the +[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) package, +which handles the manual steps of downloading headers and building native modules: + +```sh +npm install --save-dev electron-rebuild + +# Every time you run "npm install", run this +./node_modules/.bin/electron-rebuild + +# On Windows if you have trouble, try: +.\node_modules\.bin\electron-rebuild.cmd +``` + +### The npm Way + +You can also use `npm` to install modules. The steps are exactly the same with +Node modules, except that you need to setup some environment variables: + +```bash +export npm_config_disturl=https://atom.io/download/atom-shell +export npm_config_target=0.33.1 +export npm_config_arch=x64 +export npm_config_runtime=electron +HOME=~/.electron-gyp npm install module-name +``` + +### The node-gyp Way + +To build Node modules with headers of Electron, you need to tell `node-gyp` +where to download headers and which version to use: + +```bash +$ cd /path-to-module/ +$ HOME=~/.electron-gyp node-gyp rebuild --target=0.29.1 --arch=x64 --dist-url=https://atom.io/download/atom-shell +``` + +The `HOME=~/.electron-gyp` changes where to find development headers. The +`--target=0.29.1` is version of Electron. The `--dist-url=...` specifies +where to download the headers. The `--arch=x64` says the module is built for +64bit system. diff --git a/docs-translations/zh-TW/tutorial/using-pepper-flash-plugin.md b/docs-translations/zh-TW/tutorial/using-pepper-flash-plugin.md new file mode 100644 index 00000000000..a9918b220ac --- /dev/null +++ b/docs-translations/zh-TW/tutorial/using-pepper-flash-plugin.md @@ -0,0 +1,50 @@ +# Using Pepper Flash Plugin + +Electron now supports the Pepper Flash plugin. To use the Pepper Flash plugin in +Electron, you should manually specify the location of the Pepper Flash plugin +and then enable it in your application. + +## Prepare a Copy of Flash Plugin + +On OS X and Linux, the details of the Pepper Flash plugin can be found by +navigating to `chrome://plugins` in the Chrome browser. Its location and version +are useful for Electron's Pepper Flash support. You can also copy it to another +location. + +## Add Electron Switch + +You can directly add `--ppapi-flash-path` and `ppapi-flash-version` to the +Electron command line or by using the `app.commandLine.appendSwitch` method +before the app ready event. Also, add the `plugins` switch of `browser-window`. +For example: + +```javascript +// Specify flash path. +// On Windows, it might be /path/to/pepflashplayer.dll +// On OS X, /path/to/PepperFlashPlayer.plugin +// On Linux, /path/to/libpepflashplayer.so +app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); + +// Specify flash version, for example, v17.0.0.169 +app.commandLine.appendSwitch('ppapi-flash-version', '17.0.0.169'); + +app.on('ready', function() { + mainWindow = new BrowserWindow({ + 'width': 800, + 'height': 600, + 'web-preferences': { + 'plugins': true + } + }); + mainWindow.loadURL('file://' + __dirname + '/index.html'); + // Something else +}); +``` + +## Enable Flash Plugin in a `` Tag + +Add `plugins` attribute to `` tag. + +```html + +``` diff --git a/docs-translations/zh-TW/tutorial/using-selenium-and-webdriver.md b/docs-translations/zh-TW/tutorial/using-selenium-and-webdriver.md new file mode 100644 index 00000000000..035dabdfe79 --- /dev/null +++ b/docs-translations/zh-TW/tutorial/using-selenium-and-webdriver.md @@ -0,0 +1,132 @@ +# Using Selenium and WebDriver + +From [ChromeDriver - WebDriver for Chrome][chrome-driver]: + +> WebDriver is an open source tool for automated testing of web apps across many +> browsers. It provides capabilities for navigating to web pages, user input, +> JavaScript execution, and more. ChromeDriver is a standalone server which +> implements WebDriver's wire protocol for Chromium. It is being developed by +> members of the Chromium and WebDriver teams. + +In order to use `chromedriver` with Electron you have to tell it where to +find Electron and make it think Electron is the Chrome browser. + +## Setting up with WebDriverJs + +[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) provides +a Node package for testing with web driver, we will use it as an example. + +### 1. Start ChromeDriver + +First you need to download the `chromedriver` binary, and run it: + +```bash +$ ./chromedriver +Starting ChromeDriver (v2.10.291558) on port 9515 +Only local connections are allowed. +``` + +Remember the port number `9515`, which will be used later + +### 2. Install WebDriverJS + +```bash +$ npm install selenium-webdriver +``` + +### 3. Connect to ChromeDriver + +The usage of `selenium-webdriver` with Electron is basically the same with +upstream, except that you have to manually specify how to connect chrome driver +and where to find Electron's binary: + +```javascript +const webdriver = require('selenium-webdriver'); + +var driver = new webdriver.Builder() + // The "9515" is the port opened by chrome driver. + .usingServer('http://localhost:9515') + .withCapabilities({ + chromeOptions: { + // Here is the path to your Electron binary. + binary: '/Path-to-Your-App.app/Contents/MacOS/Atom', + } + }) + .forBrowser('electron') + .build(); + +driver.get('http://www.google.com'); +driver.findElement(webdriver.By.name('q')).sendKeys('webdriver'); +driver.findElement(webdriver.By.name('btnG')).click(); +driver.wait(function() { + return driver.getTitle().then(function(title) { + return title === 'webdriver - Google Search'; + }); +}, 1000); + +driver.quit(); +``` + +## Setting up with WebdriverIO + +[WebdriverIO](http://webdriver.io/) provides a Node package for testing with web +driver. + +### 1. Start ChromeDriver + +First you need to download the `chromedriver` binary, and run it: + +```bash +$ chromedriver --url-base=wd/hub --port=9515 +Starting ChromeDriver (v2.10.291558) on port 9515 +Only local connections are allowed. +``` + +Remember the port number `9515`, which will be used later + +### 2. Install WebdriverIO + +```bash +$ npm install webdriverio +``` + +### 3. Connect to chrome driver + +```javascript +const webdriverio = require('webdriverio'); +var options = { + host: "localhost", // Use localhost as chrome driver server + port: 9515, // "9515" is the port opened by chrome driver. + desiredCapabilities: { + browserName: 'chrome', + chromeOptions: { + binary: '/Path-to-Your-App/electron', // Path to your Electron binary. + args: [/* cli arguments */] // Optional, perhaps 'app=' + /path/to/your/app/ + } + } +}; + +var client = webdriverio.remote(options); + +client + .init() + .url('http://google.com') + .setValue('#q', 'webdriverio') + .click('#btnG') + .getTitle().then(function(title) { + console.log('Title was: ' + title); + }) + .end(); +``` + +## Workflow + +To test your application without rebuilding Electron, simply +[place](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md) +your app source into Electron's resource directory. + +Alternatively, pass an argument to run with your electron binary that points to +your app's folder. This eliminates the need to copy-paste your app into +Electron's resource directory. + +[chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/ From f820b0db83eeed131c454b5b04399e9b80d7a1cd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 28 Jan 2016 18:59:07 +0800 Subject: [PATCH 071/688] docs: Revise the webRequest and protocol docs --- docs/api/protocol.md | 48 +++++++++++++++++++++++++++++++++++--------- docs/api/session.md | 11 ++++++++-- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/docs/api/protocol.md b/docs/api/protocol.md index cac811265a3..1c778b71a7c 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -54,6 +54,19 @@ going to be created with `scheme`. `completion` will be called with `completion(null)` when `scheme` is successfully registered or `completion(error)` when failed. +* `request` Object + * `url` String + * `referrer` String + * `method` String + * `uploadData` Array (optional) +* `callback` Function + +The `uploadData` is an array of `data` objects: + +* `data` Object + * `bytes` Buffer - Content being sent. + * `file` String - Path of file being uploaded. + To handle the `request`, the `callback` should be called with either the file's path or an object that has a `path` property, e.g. `callback(filePath)` or `callback({path: filePath})`. @@ -61,7 +74,7 @@ path or an object that has a `path` property, e.g. `callback(filePath)` or When `callback` is called with nothing, a number, or an object that has an `error` property, the `request` will fail with the `error` number you specified. For the available error numbers you can use, please see the -[net error list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h). +[net error list][net-error]. By default the `scheme` is treated like `http:`, which is parsed differently than protocols that follow the "generic URI syntax" like `file:`, so you @@ -74,9 +87,11 @@ treated as a standard scheme. * `handler` Function * `completion` Function (optional) -Registers a protocol of `scheme` that will send a `Buffer` as a response. The -`callback` should be called with either a `Buffer` object or an object that -has the `data`, `mimeType`, and `chart` properties. +Registers a protocol of `scheme` that will send a `Buffer` as a response. + +The usage is the same with `registerFileProtocol`, except that the `callback` +should be called with either a `Buffer` object or an object that has the `data`, +`mimeType`, and `charset` properties. Example: @@ -95,9 +110,11 @@ protocol.registerBufferProtocol('atom', function(request, callback) { * `handler` Function * `completion` Function (optional) -Registers a protocol of `scheme` that will send a `String` as a response. The -`callback` should be called with either a `String` or an object that has the -`data`, `mimeType`, and `chart` properties. +Registers a protocol of `scheme` that will send a `String` as a response. + +The usage is the same with `registerFileProtocol`, except that the `callback` +should be called with either a `String` or an object that has the `data`, +`mimeType`, and `charset` properties. ### `protocol.registerHttpProtocol(scheme, handler[, completion])` @@ -106,16 +123,25 @@ Registers a protocol of `scheme` that will send a `String` as a response. The * `completion` Function (optional) Registers a protocol of `scheme` that will send an HTTP request as a response. -The `callback` should be called with an object that has the `url`, `method`, + +The usage is the same with `registerFileProtocol`, except that the `callback` +should be called with a `redirectRequest` object that has the `url`, `method`, `referrer`, `uploadData` and `session` properties. +* `redirectRequest` Object + * `url` String + * `method` String + * `session` Object (optional) + * `uploadData` Object + By default the HTTP request will reuse the current session. If you want the request to have a different session you should set `session` to `null`. -POST request should provide an `uploadData` object. +For POST requests the `uploadData` object must be provided. + * `uploadData` object * `contentType` String - MIME type of the content. - * `data` String - Content to be sent. + * `data` String - Content to be sent. ### `protocol.unregisterProtocol(scheme[, completion])` @@ -174,3 +200,5 @@ which sends a new HTTP request as a response. * `completion` Function Remove the interceptor installed for `scheme` and restore its original handler. + +[net-error]: https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h diff --git a/docs/api/session.md b/docs/api/session.md index 1bef70e5105..da5bac23592 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -333,8 +333,13 @@ is about to occur. * `resourceType` String * `timestamp` Double * `uploadData` Array (optional) - * `bytes` Buffer - Content being sent. - * `file` String - Path of file being uploaded. +* `callback` Function + +The `uploadData` is an array of `data` objects: + +* `data` Object + * `bytes` Buffer - Content being sent. + * `file` String - Path of file being uploaded. The `callback` has to be called with an `response` object: @@ -359,6 +364,7 @@ TCP connection is made to the server, but before any http data is sent. * `resourceType` String * `timestamp` Double * `requestHeaders` Object +* `callback` Function The `callback` has to be called with an `response` object: @@ -401,6 +407,7 @@ response headers of a request have been received. * `statusLine` String * `statusCode` Integer * `responseHeaders` Object +* `callback` Function The `callback` has to be called with an `response` object: From d195cc3796528b3c24886ec3ca4970f8c240c1a2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 28 Jan 2016 18:59:58 +0800 Subject: [PATCH 072/688] docs: uploadData is optional --- docs/api/protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/protocol.md b/docs/api/protocol.md index 1c778b71a7c..e57a34ef89b 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -132,7 +132,7 @@ should be called with a `redirectRequest` object that has the `url`, `method`, * `url` String * `method` String * `session` Object (optional) - * `uploadData` Object + * `uploadData` Object (optional) By default the HTTP request will reuse the current session. If you want the request to have a different session you should set `session` to `null`. From 05aeceeb52eede7d11a1dcfd0761cc8b2e1b6a56 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 13 Jan 2016 12:26:57 -0800 Subject: [PATCH 073/688] Always fall back to OpenFolderViaShell when trying to reveal a file We should always fallback to OpenFolderViaShell when revealing a file fails, since this API seems to be highly subject to Random Bad Things happening to you. --- atom/common/platform_util_win.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 735e974d1f8..4de5224668b 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -238,7 +238,7 @@ void ShowItemInFolder(const base::FilePath& full_path) { (GetProcAddress(shell32_base, "SHOpenFolderAndSelectItems")); } if (!open_folder_and_select_itemsPtr) { - ShellExecute(NULL, L"open", dir.value().c_str(), NULL, NULL, SW_SHOW); + ui::win::OpenFolderViaShell(dir); return; } @@ -251,15 +251,19 @@ void ShowItemInFolder(const base::FilePath& full_path) { hr = desktop->ParseDisplayName(NULL, NULL, const_cast(dir.value().c_str()), NULL, &dir_item, NULL); - if (FAILED(hr)) + if (FAILED(hr)) { + ui::win::OpenFolderViaShell(dir); return; + } base::win::ScopedCoMem file_item; hr = desktop->ParseDisplayName(NULL, NULL, const_cast(full_path.value().c_str()), NULL, &file_item, NULL); - if (FAILED(hr)) + if (FAILED(hr)) { + ui::win::OpenFolderViaShell(dir); return; + } const ITEMIDLIST* highlight[] = { file_item }; @@ -271,7 +275,7 @@ void ShowItemInFolder(const base::FilePath& full_path) { // found" even though the file is there. In these cases, ShellExecute() // seems to work as a fallback (although it won't select the file). if (hr == ERROR_FILE_NOT_FOUND) { - ShellExecute(NULL, L"open", dir.value().c_str(), NULL, NULL, SW_SHOW); + ui::win::OpenFolderViaShell(dir); } else { LPTSTR message = NULL; DWORD message_length = FormatMessage( @@ -284,6 +288,8 @@ void ShowItemInFolder(const base::FilePath& full_path) { << " " << reinterpret_cast(&message); if (message) LocalFree(message); + + ui::win::OpenFolderViaShell(dir); } } } From 4305e98fcbf6387696e36d35dc3e67318bb48ae5 Mon Sep 17 00:00:00 2001 From: fbukevin Date: Thu, 28 Jan 2016 21:16:59 +0800 Subject: [PATCH 074/688] translate zh-TW tutorial mac-app-store-submission-guide.md --- .../mac-app-store-submission-guide.md | 62 +++++++------------ 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/docs-translations/zh-TW/tutorial/mac-app-store-submission-guide.md b/docs-translations/zh-TW/tutorial/mac-app-store-submission-guide.md index 036676fe853..6deaa8295ef 100644 --- a/docs-translations/zh-TW/tutorial/mac-app-store-submission-guide.md +++ b/docs-translations/zh-TW/tutorial/mac-app-store-submission-guide.md @@ -1,32 +1,23 @@ -# Mac App Store Submission Guide +# Mac App Store 提交指引 -Since v0.34.0, Electron allows submitting packaged apps to the Mac App Store -(MAS). This guide provides information on: how to submit your app and the -limitations of the MAS build. +自從版本 v0.34.0 開始,Electron 允許提交打包好的應用程式到 Mac App Store(MAS),這個指引提供了以下資訊:如何提交你的應用程式和 MAS 的建置限制。 -__Note:__ Submitting an app to Mac App Store requires enrolling [Apple Developer -Program][developer-program], which costs money. +__Note:__ 提交一個應用程式到 Mac App Store 需要註冊要付費的 [Apple Developer +Program][developer-program]. -## How to Submit Your App +## 如何提交你的應用程式 -The following steps introduce a simple way to submit your app to Mac App Store. -However, these steps do not ensure your app will be approved by Apple; you -still need to read Apple's [Submitting Your App][submitting-your-app] guide on -how to meet the Mac App Store requirements. +以下步驟介紹了一個簡單的方法提交你的應用程式到 Mac App Store,然而這些步驟不保證你的應用程式會被 Apple 批准,你仍然需要閱讀 Apple 的 [Submitting Your App][submitting-your-app] 指引來達到 Mac App Store 的要求。 -### Get Certificate +### 取得認證 -To submit your app to the Mac App Store, you first must get a certificate from -Apple. You can follow these [existing guides][nwjs-guide] on web. +要提交你的應用程式到 Mac App Store,你首先必須取得 Apple 的認證,你可以遵循這些網路上的 [existing guides][nwjs-guide]。 -### Sign Your App +### 簽署你的應用程式 -After getting the certificate from Apple, you can package your app by following -[Application Distribution](application-distribution.md), and then proceed to -signing your app. This step is basically the same with other programs, but the -key is to sign every dependency of Electron one by one. +取得了 Apple 的認證以後,你可以遵照 [Application Distribution](application-distribution.md) 來打包你的應用程式,然後進行你應用程式的簽署,這個步驟基本上與其他程式相同,但重點在於你要一一為每個 Electron 的相依套件做簽署。 -First, you need to prepare two entitlements files. +首先,你需要準備兩個管理權限用的檔案。 `child.plist`: @@ -56,7 +47,7 @@ First, you need to prepare two entitlements files. ``` -And then sign your app with the following script: +接著遵照下面的腳本簽署你的應用程式: ```bash #!/bin/bash @@ -83,33 +74,26 @@ codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" ``` -If you are new to app sandboxing under OS X, you should also read through -Apple's [Enabling App Sandbox][enable-app-sandbox] to have a basic idea, then -add keys for the permissions needed by your app to the entitlements files. +如果你是第一次使用 OS X 下的應用程式沙盒(app sandboxing),你應該也要閱讀 Apple 的 [Enabling App Sandbox][enable-app-sandbox] 以舉被基本概念,然後把你的應用程式會用到的 key 的權限都加入管理權現的檔案中。 -### Upload Your App and Submit for Review +### 上傳你的應用程式和提交檢視 -After signing your app, you can use Application Loader to upload it to iTunes -Connect for processing, making sure you have [created a record][create-record] -before uploading. Then you can [submit your app for review][submit-for-review]. +當你簽署好你的應用程式後,你可以使用應用程式載入器(Application Loader)把他上傳到 iTunes,處理中請保持連線順暢,在上傳以前請確保你已經 [建立一個紀錄][create-record],機著你就可以提交你的應用程式去檢視了。 -## Limitations of MAS Build +## MAS 建置的限制 -In order to satisfy all requirements for app sandboxing, the following modules -have been disabled in the MAS build: +為了滿足應用程式沙盒的所有的要求,以下模組需要在 MAS 建置過程中被停用: * `crash-reporter` * `auto-updater` -and the following behaviors have been changed: +然後以下的動作已經被變更: -* Video capture may not work for some machines. -* Certain accessibility features may not work. -* Apps will not be aware of DNS changes. +* 在某些機器上影像捕捉可能不能運作 +* 特定的存取特性可能無法運作 +* 應用程式將不管 DNS 的改變 -Also, due to the usage of app sandboxing, the resources which can be accessed by - the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for - more information. +此外,由於使用了應用程式沙盒,那些可以被應用程式存取的資源會被嚴格限制,你可以閱讀 [App Sandboxing][app-sandboxing] 以取得更多資訊。 [developer-program]: https://developer.apple.com/support/compare-memberships/ [submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html @@ -117,4 +101,4 @@ Also, due to the usage of app sandboxing, the resources which can be accessed by [enable-app-sandbox]: https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html [create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html [submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html -[app-sandboxing]: https://developer.apple.com/app-sandboxing/ +[app-sandboxing]: https://developer.apple.com/app-sandboxing/ \ No newline at end of file From 7d54bb54cdf27c2ba0cfc4f1268c6bba2681cd5e Mon Sep 17 00:00:00 2001 From: fbukevin Date: Thu, 28 Jan 2016 22:17:48 +0800 Subject: [PATCH 075/688] translate zh-TW tutorial using-native-node-modules.md --- .../tutorial/using-native-node-modules.md | 49 ++++++------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/docs-translations/zh-TW/tutorial/using-native-node-modules.md b/docs-translations/zh-TW/tutorial/using-native-node-modules.md index 2defedd7418..82febb6d5ab 100644 --- a/docs-translations/zh-TW/tutorial/using-native-node-modules.md +++ b/docs-translations/zh-TW/tutorial/using-native-node-modules.md @@ -1,47 +1,34 @@ -# Using Native Node Modules +# 使用原生 node 模組 -The native Node modules are supported by Electron, but since Electron is -using a different V8 version from official Node, you have to manually specify -the location of Electron's headers when building native modules. +原生的 Node 模組 Electron 都有支援,但自從 Electron 使用了與 Node 官方不同的 V8 版本後,當你要建置原生模組的時候,你需要手動指定 Electron 標頭的位置。 -## Native Node Module Compatibility +## 原生 Node 模組的相容性 -Native modules might break when Node starts using a new version of V8. -To make sure the module you're interested in will work with Electron, you should -check if it supports the internal Node version used by Electron. -You can check what version of Node is used in Electron by looking it up in -the [releases](https://github.com/atom/electron/releases) page or by using -`process.version` (see [Quick Start](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md) -for example). +原生模組可能在 Node 開始使用一個新版本的 V8 時毀損,為了確保你想要用的模組能正確與 Electron 一起運行,你應該檢查是否支援 Electron 內部 Node 版本,你可以查看 [releases](https://github.com/atom/electron/releases) 或是使用 `process.version` (範例請見 [Quick Start](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md)) 來檢查哪個 Node 版本是現在的 Electron 使用的。 -Consider using [NAN](https://github.com/nodejs/nan/) for your own modules, since -it makes it easier to support multiple versions of Node. It's also helpful for -porting old modules to newer versions of Node so they can work with Electron. +你可以考慮給你自己的模組使用 [NAN](https://github.com/nodejs/nan/),因為它可以較輕易的支援多種版本的 Node,它對於移植舊的模組到新版本的 Node 以便與 Electron 一起運作也是很有用的。 -## How to Install Native Modules +## 如何安裝原生模組 -Three ways to install native modules: +三種安裝原生模組的方式: -### The Easy Way +### 簡單的方法 -The most straightforward way to rebuild native modules is via the -[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) package, -which handles the manual steps of downloading headers and building native modules: +最直接重新建置原生模組的方法是透過 [`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) 套件,這個套件處理了手動下載標頭和建制原生模組的步驟: ```sh npm install --save-dev electron-rebuild -# Every time you run "npm install", run this +# 每次你執行 "npm install", 執行這句 ./node_modules/.bin/electron-rebuild -# On Windows if you have trouble, try: +# 在 Windows 上如果你有狀況,試試看: .\node_modules\.bin\electron-rebuild.cmd ``` -### The npm Way +### 使用 npm -You can also use `npm` to install modules. The steps are exactly the same with -Node modules, except that you need to setup some environment variables: +你也可以使用 `npm` 安裝模組,步驟與 Node 模組的安裝相同,除了你需要設定一些環境變數: ```bash export npm_config_disturl=https://atom.io/download/atom-shell @@ -51,17 +38,13 @@ export npm_config_runtime=electron HOME=~/.electron-gyp npm install module-name ``` -### The node-gyp Way +### 使用 node-gyp -To build Node modules with headers of Electron, you need to tell `node-gyp` -where to download headers and which version to use: +要把 Node 模組與 Eletron 的標頭一起建置,你需要告訴 `node-gyp` 下載標頭到哪裡,以及要使用哪個版本: ```bash $ cd /path-to-module/ $ HOME=~/.electron-gyp node-gyp rebuild --target=0.29.1 --arch=x64 --dist-url=https://atom.io/download/atom-shell ``` -The `HOME=~/.electron-gyp` changes where to find development headers. The -`--target=0.29.1` is version of Electron. The `--dist-url=...` specifies -where to download the headers. The `--arch=x64` says the module is built for -64bit system. +`HOME=~/.electron-gyp` 改變了尋找開發標頭的地方,`--target=0.29.1` 是 Eletron 的版本, `--dist-url=...` 指定了下載標頭到哪, `--arch=x64` 指出模組要建置在 64 位元系統。 From 516b01e398c27ec714e74a5ce10d5a37f01e774d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 28 Jan 2016 22:38:53 +0800 Subject: [PATCH 076/688] win: Call _close before close file handle Fix #4258. --- atom/common/asar/archive.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index d6abf1cee82..7527932b977 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -130,14 +130,16 @@ Archive::Archive(const base::FilePath& path) Archive::~Archive() { #if defined(OS_WIN) - file_.Close(); - _close(fd_); + if (fd_ != -1) + _close(fd_); #endif } bool Archive::Init() { - if (!file_.IsValid()) + if (!file_.IsValid()) { + LOG(ERROR) << base::File::ErrorToString(file_.error_details()); return false; + } std::vector buf; int len; From 3b9fb6f9e6594e72ff967a90bce38da7b492807c Mon Sep 17 00:00:00 2001 From: fbukevin Date: Thu, 28 Jan 2016 22:40:13 +0800 Subject: [PATCH 077/688] translate zh-TW tutorial debugging-main-process.md --- .../zh-TW/tutorial/debugging-main-process.md | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/docs-translations/zh-TW/tutorial/debugging-main-process.md b/docs-translations/zh-TW/tutorial/debugging-main-process.md index 6fbb858bc28..f1a7e840951 100644 --- a/docs-translations/zh-TW/tutorial/debugging-main-process.md +++ b/docs-translations/zh-TW/tutorial/debugging-main-process.md @@ -1,74 +1,69 @@ -# Debugging the Main Process +# 主行程 Debug -The browser window DevTools can only debug the renderer process scripts (i.e. -the web pages). In order to provide a way to debug the scripts from the main -process, Electron has provided the `--debug` and `--debug-brk` switches. +瀏覽器視窗開發工具 DevTools 只可以用來幫渲染器的行程腳本(renderer process script,網頁畫面)除錯(debug),為了提供一個方法在主行程中除錯,Electron 有提供 `--debug` 和 `--debug-brk` 開關。 -## Command Line Switches +## 命令列開關 -Use the following command line switches to debug Electron's main process: +使用以下命令列切換來為 Electron 的主行程除錯: ### `--debug=[port]` -When this switch is used Electron will listen for V8 debugger protocol -messages on `port`. The default `port` is `5858`. +當這個開關被使用,Electron 將會透過 `port` 來監聽 V8 的除錯協定訊息,預設的 `port` 是 `5858`。 ### `--debug-brk=[port]` -Like `--debug` but pauses the script on the first line. +同 `--debug` 但暫停在腳本的第一行。 -## Use node-inspector for Debugging +## 使用 node-inspector 來除錯 -__Note:__ Electron doesn't currently work very well -with node-inspector, and the main process will crash if you inspect the -`process` object under node-inspector's console. +__Note:__ Electron 近期沒有跟 node-inspector 處的很好,而且如果你透過 node-inspector's console 查看 `process` 物件,主行程將會爆掉。 -### 1. Make sure you have [node-gyp required tools][node-gyp-required-tools] installed +### 1. 確保你有安裝 [node-gyp required tools][node-gyp-required-tools] -### 2. Install [node-inspector][node-inspector] +### 2. 安裝 [node-inspector][node-inspector] ```bash $ npm install node-inspector ``` -### 3. Install a patched version of `node-pre-gyp` +### 3. 安裝一個修補過版本的 `node-pre-gyp` ```bash $ npm install git+https://git@github.com/enlight/node-pre-gyp.git#detect-electron-runtime-in-find ``` -### 4. Recompile the `node-inspector` `v8` modules for electron (change the target to your electron version number) +### 4. 除心編譯 `node-inspector` `v8` 模組給 Electron (變更 target 為你的 Electron 編號) ```bash $ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-debug/ --dist-url=https://atom.io/download/atom-shell reinstall $ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-profiler/ --dist-url=https://atom.io/download/atom-shell reinstall ``` -See also [How to install native modules](how-to-install-native-modules). +參閱 [如何安裝原生模組](how-to-install-native-modules). -### 5. Enable debug mode for Electron +### 5. 給 Electron 啟用除錯模式 -You can either start Electron with a debug flag like: +你可以啟動 Electron 並帶有一個除錯 flag ,例如: ```bash $ electron --debug=5858 your/app ``` -or, to pause your script on the first line: +或者,讓你的腳本暫停在第一行: ```bash $ electron --debug-brk=5858 your/app ``` -### 6. Start the [node-inspector][node-inspector] server using electron +### 6. 使用啟動 [node-inspector][node-inspector] 伺服器 ```bash $ ELECTRON_RUN_AS_NODE=true path/to/electron.exe node_modules/node-inspector/bin/inspector.js ``` -### 7. Load the debugger UI +### 7. 載入除錯介面 -Open http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 in the Chrome browser. You may have to click pause if starting with debug-brk to see the entry line. +在你的 Chrome 瀏覽器打開 http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858,你可能需要點擊暫停假如你是透過使用 debug-brk 啟動並停在進入行(entry line)的話。 [node-inspector]: https://github.com/node-inspector/node-inspector [node-gyp-required-tools]: https://github.com/nodejs/node-gyp#installation From 93f268cbd18928743136d5e6ffbeb4e5dbd3bafc Mon Sep 17 00:00:00 2001 From: fbukevin Date: Thu, 28 Jan 2016 22:52:57 +0800 Subject: [PATCH 078/688] translate zh-TW tutorial using-selenium-and-webdriver.md --- .../tutorial/using-selenium-and-webdriver.md | 51 ++++++++----------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/docs-translations/zh-TW/tutorial/using-selenium-and-webdriver.md b/docs-translations/zh-TW/tutorial/using-selenium-and-webdriver.md index 035dabdfe79..8f90597ddae 100644 --- a/docs-translations/zh-TW/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/zh-TW/tutorial/using-selenium-and-webdriver.md @@ -1,6 +1,6 @@ -# Using Selenium and WebDriver +# 使用 Selenium 和 WebDriver -From [ChromeDriver - WebDriver for Chrome][chrome-driver]: +根據 [ChromeDriver - WebDriver for Chrome][chrome-driver]: > WebDriver is an open source tool for automated testing of web apps across many > browsers. It provides capabilities for navigating to web pages, user input, @@ -8,17 +8,15 @@ From [ChromeDriver - WebDriver for Chrome][chrome-driver]: > implements WebDriver's wire protocol for Chromium. It is being developed by > members of the Chromium and WebDriver teams. -In order to use `chromedriver` with Electron you have to tell it where to -find Electron and make it think Electron is the Chrome browser. +為了與 Electron 一起使用 `chromedriver`,你需要告訴 `chromedriver` 去哪找 Electron 並讓他知道 Electron 是 Chrome 瀏覽器。 -## Setting up with WebDriverJs +## 透過 WebDriverJs 設定 -[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) provides -a Node package for testing with web driver, we will use it as an example. +[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) 提供一個 Node 套件來透過 web driver 做測試,我們將使用它作為例子。 -### 1. Start ChromeDriver +### 1. 啟動 ChromeDriver -First you need to download the `chromedriver` binary, and run it: +首先你需要下載 `chromedriver` 執行檔,然後執行它: ```bash $ ./chromedriver @@ -26,19 +24,17 @@ Starting ChromeDriver (v2.10.291558) on port 9515 Only local connections are allowed. ``` -Remember the port number `9515`, which will be used later +記住埠號(port number) `9515`,等等會使用到它 -### 2. Install WebDriverJS +### 2. 安裝 WebDriverJS ```bash $ npm install selenium-webdriver ``` -### 3. Connect to ChromeDriver +### 3. 連接到 ChromeDriver -The usage of `selenium-webdriver` with Electron is basically the same with -upstream, except that you have to manually specify how to connect chrome driver -and where to find Electron's binary: +與 Electron 一起使用 `selenium-webdriver` 的方法基本上與 upstream 相同,除了你需要手動指定如何連接 chrome driver 和去哪找 Electron 的執行檔: ```javascript const webdriver = require('selenium-webdriver'); @@ -67,14 +63,13 @@ driver.wait(function() { driver.quit(); ``` -## Setting up with WebdriverIO +## 透過 WebdriverIO 設定 -[WebdriverIO](http://webdriver.io/) provides a Node package for testing with web -driver. +[WebdriverIO](http://webdriver.io/) 提供一個 Node 套件來透過 web driver 做測試。 -### 1. Start ChromeDriver +### 1. 啟動 ChromeDriver -First you need to download the `chromedriver` binary, and run it: +首先你需要下載 `chromedriver` 執行檔,然後執行它: ```bash $ chromedriver --url-base=wd/hub --port=9515 @@ -82,15 +77,15 @@ Starting ChromeDriver (v2.10.291558) on port 9515 Only local connections are allowed. ``` -Remember the port number `9515`, which will be used later +記住埠號(port number) `9515`,等等會用到它 -### 2. Install WebdriverIO +### 2. 安裝 WebdriverIO ```bash $ npm install webdriverio ``` -### 3. Connect to chrome driver +### 3. 連接到 chrome driver ```javascript const webdriverio = require('webdriverio'); @@ -119,14 +114,10 @@ client .end(); ``` -## Workflow +## 運作流程 -To test your application without rebuilding Electron, simply -[place](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md) -your app source into Electron's resource directory. +要在不重新建置 Electron 的情況下測試你的應用程式,只需要 [放置](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md) 你的應用程式到 Electron 的資源目錄中即可。 -Alternatively, pass an argument to run with your electron binary that points to -your app's folder. This eliminates the need to copy-paste your app into -Electron's resource directory. +或者,傳遞一個指向你應用程式資料夾的參數來透過你的 Electron 執行檔運行,這會減少複製你應用程式到 Electron 資源資料夾的需求。 [chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/ From 15ce59be64a69919d63cb09ed4d71e77b277ec3d Mon Sep 17 00:00:00 2001 From: fbukevin Date: Thu, 28 Jan 2016 23:23:19 +0800 Subject: [PATCH 079/688] translate zh-TW tutorial devtools-extension.md --- .../zh-TW/tutorial/devtools-extension.md | 44 ++++++------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/docs-translations/zh-TW/tutorial/devtools-extension.md b/docs-translations/zh-TW/tutorial/devtools-extension.md index 7c7ea7d64a2..1a419fb8375 100644 --- a/docs-translations/zh-TW/tutorial/devtools-extension.md +++ b/docs-translations/zh-TW/tutorial/devtools-extension.md @@ -1,62 +1,46 @@ -# DevTools Extension +# DevTools 擴充套件 -To make debugging easier, Electron has basic support for the -[Chrome DevTools Extension][devtools-extension]. +要使除錯更簡單,Electron 有對 [Chrome DevTools(開發人員工具) Extension][devtools-extension] 基本的支援。 -For most DevTools extensions you can simply download the source code and use -the `BrowserWindow.addDevToolsExtension` API to load them. The loaded extensions -will be remembered so you don't need to call the API every time when creating -a window. +多數的 DevTools 擴充可以簡單地透過下載原始碼然後使用 `BrowserWindow.addDevToolsExtension` API 來載入它們,已載入的擴充套件會被記住,如此一來你就不用每次建立一個視窗的時候就要呼叫 API。 -** NOTE: React DevTools does not work, follow the issue here https://github.com/atom/electron/issues/915 ** +** 注意: React DevTools 無法使用,參考 [issue](https://github.com/atom/electron/issues/915) ** -For example, to use the [React DevTools Extension](https://github.com/facebook/react-devtools) -, first you need to download its source code: +例如使用 [React DevTools Extension](https://github.com/facebook/react-devtools),首先你需要下載它的原始碼: ```bash $ cd /some-directory $ git clone --recursive https://github.com/facebook/react-devtools.git ``` -Follow the instructions in [`react-devtools/shells/chrome/Readme.md`](https://github.com/facebook/react-devtools/blob/master/shells/chrome/Readme.md) to build the extension. +照著 [`react-devtools/shells/chrome/Readme.md`](https://github.com/facebook/react-devtools/blob/master/shells/chrome/Readme.md) 的指示來建置擴充套件。 -Then you can load the extension in Electron by opening DevTools in any window, -and running the following code in the DevTools console: +接著你就可以在 Electron 中打開任何視窗來載入擴充套件了,然後在 DevTools console 執行以下的程式碼: ```javascript const BrowserWindow = require('electron').remote.BrowserWindow; BrowserWindow.addDevToolsExtension('/some-directory/react-devtools/shells/chrome'); ``` -To unload the extension, you can call the `BrowserWindow.removeDevToolsExtension` -API with its name and it will not load the next time you open the DevTools: +要卸載擴充套件,你可以呼叫 `BrowserWindow.removeDevToolsExtension` +API,並帶入套件的名稱,則套件就不會在下次起打開 DevTools 的時候載入了: ```javascript BrowserWindow.removeDevToolsExtension('React Developer Tools'); ``` -## Format of DevTools Extension +## DevTools 擴充套件的格式 -Ideally all DevTools extensions written for the Chrome browser can be loaded by -Electron, but they have to be in a plain directory. For those packaged with -`crx` extensions, there is no way for Electron to load them unless you find a -way to extract them into a directory. +理想上,所有寫給 Chrome 瀏覽器用的 DevTools 擴充套件都要能夠被 Electron 載入,但它們需要是在一個普通的目錄下,那些以 `crx` 包裝的擴充套件,Electron 沒有辦法載入它們除非你找到一個解壓縮他們到目錄的方法。 ## Background Pages -Currently Electron doesn't support the background pages feature in Chrome -extensions, so some DevTools extensions that rely on this feature may -not work in Electron. +目前 Electron 沒有支援 Chrome 擴充套件的 background pages,所以一些會用到 background pages 的 DevTools 擴充套件可能會無法在 Electron 中運作。 ## `chrome.*` APIs -Some Chrome extensions may use `chrome.*` APIs for features and while there has -been some effort to implement those APIs in Electron, not all have been -implemented. +一些 Chrome 擴充套件可能使用到 `chrome.*` API,而儘管在 Electron 中有一些這種 API 的實作,還是沒有所有的部分都被實作到。 -Given that not all `chrome.*` APIs are implemented if the DevTools extension is -using APIs other than `chrome.devtools.*`, the extension is very likely not to -work. You can report failing extensions in the issue tracker so that we can add -support for those APIs. +因為並非所有 `chrome.*` API 都有實作,如果一個 DevTools 擴充套件有使用到而非 `chrome.devtools.*`,這個套件非常有可能無法運作,你可以回報失敗的擴充套件到 issue tracker,那我們就可以把這些 API 加入支援。 [devtools-extension]: https://developer.chrome.com/extensions/devtools From 8309e38ce97b1582e4190747b19ca0a5f3761eba Mon Sep 17 00:00:00 2001 From: fbukevin Date: Thu, 28 Jan 2016 23:37:16 +0800 Subject: [PATCH 080/688] translate zh-TW tutorial using-pepper-flash-plugin.md --- docs-translations/zh-TW/README.md | 2 +- .../tutorial/using-pepper-flash-plugin.md | 37 ++++++++----------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/docs-translations/zh-TW/README.md b/docs-translations/zh-TW/README.md index 1e69c974438..29ed827c668 100644 --- a/docs-translations/zh-TW/README.md +++ b/docs-translations/zh-TW/README.md @@ -8,7 +8,7 @@ * [主行程 Debug](tutorial/debugging-main-process.md) * [使用 Selenium 和 WebDriver](tutorial/using-selenium-and-webdriver.md) * [DevTools 擴充](tutorial/devtools-extension.md) -* [使用 Pepper Flash 套件](tutorial/using-pepper-flash-plugin.md) +* [使用 Pepper Flash 外掛](tutorial/using-pepper-flash-plugin.md) ## 教學 diff --git a/docs-translations/zh-TW/tutorial/using-pepper-flash-plugin.md b/docs-translations/zh-TW/tutorial/using-pepper-flash-plugin.md index a9918b220ac..e27554c5168 100644 --- a/docs-translations/zh-TW/tutorial/using-pepper-flash-plugin.md +++ b/docs-translations/zh-TW/tutorial/using-pepper-flash-plugin.md @@ -1,31 +1,26 @@ -# Using Pepper Flash Plugin +# 使用 Pepper Flash 外掛 -Electron now supports the Pepper Flash plugin. To use the Pepper Flash plugin in -Electron, you should manually specify the location of the Pepper Flash plugin -and then enable it in your application. +Electron 現在支援 Pepper Flash 外掛,要在 Electron 中使用 Pepper Flash 外掛,你應該手動指定 Pepper Flash 外掛的位置,並在你的應用程式中啟用它。 -## Prepare a Copy of Flash Plugin +## 準備一份 Flash 外掛 -On OS X and Linux, the details of the Pepper Flash plugin can be found by -navigating to `chrome://plugins` in the Chrome browser. Its location and version -are useful for Electron's Pepper Flash support. You can also copy it to another -location. +在 OS X 和 Linux 上,Pepper Flash 外掛的細節可以透過查看 Chrome 瀏覽器中的 `chrome://plugins` 來得知,它的位置和版本對於 Electron 的 Pepper Flash 支援都有很大的幫助,你可以把它複製一份到別的位置。 -## Add Electron Switch +## 加入 Electron 開關 -You can directly add `--ppapi-flash-path` and `ppapi-flash-version` to the -Electron command line or by using the `app.commandLine.appendSwitch` method -before the app ready event. Also, add the `plugins` switch of `browser-window`. -For example: +你可以直接加入 `--ppapi-flash-path` 和 `ppapi-flash-version` 到 +Electron 命定列或是在應用程式的 ready 事件之前使用 `app.commandLine.appendSwitch` 方法,並且加入 `browser-window` 的 `plugins` 開關。 + +例如: ```javascript -// Specify flash path. -// On Windows, it might be /path/to/pepflashplayer.dll -// On OS X, /path/to/PepperFlashPlayer.plugin -// On Linux, /path/to/libpepflashplayer.so +// 指定 Flash 路徑 +// Windows 中可能是 /path/to/pepflashplayer.dll +// OS X 中 /path/to/PepperFlashPlayer.plugin +// Linux 中 /path/to/libpepflashplayer.so app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); -// Specify flash version, for example, v17.0.0.169 +// 指定 Flash 版本, 例如 v17.0.0.169 app.commandLine.appendSwitch('ppapi-flash-version', '17.0.0.169'); app.on('ready', function() { @@ -41,9 +36,9 @@ app.on('ready', function() { }); ``` -## Enable Flash Plugin in a `` Tag +## 在一個 `` Tag 中啟用 Flash 外掛 -Add `plugins` attribute to `` tag. +把 `plugins` 屬性加入 `` tag。 ```html From 0fe829cff73acee506c77c676da9f3466e5b7fa8 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 29 Jan 2016 09:09:26 +0900 Subject: [PATCH 081/688] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/api/protocol.md | 53 +++++++++++++++++++------ docs-translations/ko-KR/api/session.md | 10 +++++ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/docs-translations/ko-KR/api/protocol.md b/docs-translations/ko-KR/api/protocol.md index f6f2ac65c95..2b42226e2ff 100644 --- a/docs-translations/ko-KR/api/protocol.md +++ b/docs-translations/ko-KR/api/protocol.md @@ -50,14 +50,26 @@ app.on('ready', function() { `completion` 콜백은 `scheme`가 성공적으로 등록되었을 때 `completion(null)` 형식으로 호출되고, 등록에 실패했을 땐 `completion(error)` 형식으로 에러 내용을 담아 호출됩니다. +* `request` Object + * `url` String + * `referrer` String + * `method` String + * `uploadData` Array (optional) +* `callback` Function + +The `uploadData` is an array of `data` objects: + +* `data` Object + * `bytes` Buffer - Content being sent. + * `file` String - Path of file being uploaded. + `request`를 처리할 때 반드시 파일 경로 또는 `path` 속성을 포함하는 객체를 인자에 포함하여 `callback`을 호출해야 합니다. 예: `callback(filePath)` 또는 `callback({path: filePath})`. 만약 `callback`이 아무 인자도 없이 호출되거나 숫자나 `error` 프로퍼티를 가진 객체가 인자로 전달될 경우 `request`는 지정한 `error` 코드(숫자)를 출력합니다. 사용할 수 있는 -에러 코드는 [네트워크 에러 목록](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h)에서 -확인할 수 있습니다. +에러 코드는 [네트워크 에러 목록][net-error]에서 확인할 수 있습니다. 기본적으로 `scheme`은 `http:`와 같이 처리됩니다. `file:`과 같이 "일반적인 URI 문법" 과는 다르게 인식되는 프로토콜은 `protocol.registerStandardSchemes`을 사용하여 표준 @@ -69,9 +81,11 @@ app.on('ready', function() { * `handler` Function * `completion` Function (optional) -`scheme`에 `Buffer`를 응답으로 보내는 프로토콜을 등록합니다. 반드시 `Buffer` 또는 -`data`, `mimeType`, `chart` 속성을 포함한 객체 중 하나를 인자에 포함하여 -`callback`을 호출해야 합니다. +`Buffer`를 응답으로 전송하는 `scheme`의 프로토콜을 등록합니다. + +사용법은 `callback`이 반드시 `Buffer` 객체 또는 `data`, `mimeType`, `charset` +속성을 포함하는 객체와 함께 호출되어야 한다는 점을 제외하면 `registerFileProtocol`과 +사용법이 같습니다. 예제: @@ -90,9 +104,11 @@ protocol.registerBufferProtocol('atom', function(request, callback) { * `handler` Function * `completion` Function (optional) -`scheme`에 `문자열`을 응답으로 보내는 프로토콜을 등록합니다. 반드시 `문자열` 또는 -`data`, `mimeType`, `chart` 속성을 포함한 객체 중 하나를 인자에 포함하여 -`callback`을 호출해야 합니다. +`String`을 응답으로 전송할 `scheme`의 프로토콜을 등록합니다. + +사용법은 `callback`이 반드시 `String` 또는 `data`, `mimeType`, `charset` 속성을 +포함하는 객체와 함께 호출되어야 한다는 점을 제외하면 `registerFileProtocol`과 +사용법이 같습니다. ### `protocol.registerHttpProtocol(scheme, handler[, completion])` @@ -100,17 +116,26 @@ protocol.registerBufferProtocol('atom', function(request, callback) { * `handler` Function * `completion` Function (optional) -`scheme`에 HTTP 요청을 응답으로 보내는 프로토콜을 등록합니다. 반드시 `url`, -`method`, `referrer`, `uploadData` 그리고 `session` 속성을 포함하는 객체를 인자에 -포함하여 `callback`을 호출해야 합니다. +HTTP 요청을 응답으로 전송할 `scheme`의 프로토콜을 등록합니다. + +사용법은 `callback`이 반드시 `url`, `method`, `referrer`, `uploadData`와 +`session` 속성을 포함하는 `redirectRequest` 객체와 함께 호출되어야 한다는 점을 +제외하면 `registerFileProtocol`과 사용법이 같습니다. + +* `redirectRequest` Object + * `url` String + * `method` String + * `session` Object (optional) + * `uploadData` Object (optional) 기본적으로 HTTP 요청은 현재 세션을 재사용합니다. 만약 서로 다른 세션에 요청을 보내고 싶으면 `session`을 `null`로 지정해야 합니다. -POST 요청은 반드시 `uploadData` 객체가 제공되어야 합니다. +POST 요청에는 반드시 `uploadData` 객체가 제공되어야 합니다. + * `uploadData` object * `contentType` String - 컨텐츠의 MIME 타입. - * `data` String - 전송할 컨텐츠. + * `data` String - 전송할 컨텐츠. ### `protocol.unregisterProtocol(scheme[, completion])` @@ -167,3 +192,5 @@ POST 요청은 반드시 `uploadData` 객체가 제공되어야 합니다. * `completion` Function (optional) 가로챈 `scheme`를 삭제하고 기본 핸들러로 복구합니다. + +[net-error]: https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index bf5c157ede6..6f39ab9dcdd 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -329,6 +329,14 @@ session.defaultSession.webRequest.onBeforeSendHeaders(filter, function(details, * `method` String * `resourceType` String * `timestamp` Double + * `uploadData` Array (optional) +* `callback` Function + +`uploadData`는 `data` 객체의 배열입니다: + +* `data` Object + * `bytes` Buffer - 전송될 컨텐츠. + * `file` String - 업로드될 파일의 경로. `callback`은 `response` 객체와 함께 호출되어야 합니다: @@ -353,6 +361,7 @@ HTTP 요청을 보내기 전 요청 헤더를 사용할 수 있을 때 `listener * `resourceType` String * `timestamp` Double * `requestHeaders` Object +* `callback` Function `callback`은 `response` 객체와 함께 호출되어야 합니다: @@ -395,6 +404,7 @@ HTTP 요청을 보내기 전 요청 헤더를 사용할 수 있을 때 `listener * `statusLine` String * `statusCode` Integer * `responseHeaders` Object +* `callback` Function `callback`은 `response` 객체와 함께 호출되어야 합니다: From 77cf30f75825d58589cfc50d3e5f4d73af5c14bd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 29 Jan 2016 11:52:31 +0800 Subject: [PATCH 082/688] Revert "renderer: dont fork the process when there is server redirect" This reverts commit ab9d1bf97ed2015829bcc5381c149d2826d04015. --- atom/renderer/atom_renderer_client.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 15165efa330..3c97db4b978 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -173,7 +173,7 @@ bool AtomRendererClient::ShouldFork(blink::WebLocalFrame* frame, // the OpenURLFromTab is triggered, which means form posting would not work, // we should solve this by patching Chromium in future. *send_referrer = true; - return http_method == "GET" && !is_server_redirect; + return http_method == "GET"; } content::BrowserPluginDelegate* AtomRendererClient::CreateBrowserPluginDelegate( From a26cbf640c74ffdb2cebb1f05c76247945bfd5ae Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 29 Jan 2016 12:38:50 +0800 Subject: [PATCH 083/688] docs: cryptographic algorithms used by Electron Fix #3995. --- .../mac-app-store-submission-guide.md | 63 ++++++++++++++++--- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index 036676fe853..e94a4310618 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -4,6 +4,10 @@ Since v0.34.0, Electron allows submitting packaged apps to the Mac App Store (MAS). This guide provides information on: how to submit your app and the limitations of the MAS build. +__Note:__ From v0.36.0 there was a bug preventing GPU process to start after +the app being sandboxed, so it is recommended to use v0.35.x before this bug +gets fixed. You can find more about this in [issue #3871][issue-3871]. + __Note:__ Submitting an app to Mac App Store requires enrolling [Apple Developer Program][developer-program], which costs money. @@ -73,13 +77,18 @@ INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)" FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Libraries/libnode.dylib" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Electron Framework" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A" codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper.app/" codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper EH.app/" codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper NP.app/" -codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" +if [ -d "$FRAMEWORKS_PATH/Squirrel.framework/Versions/A" ]; then + # Signing a non-MAS build. + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Mantle.framework/Versions/A" + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/ReactiveCocoa.framework/Versions/A" + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Squirrel.framework/Versions/A" +fi +codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" + productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" ``` @@ -98,8 +107,8 @@ before uploading. Then you can [submit your app for review][submit-for-review]. In order to satisfy all requirements for app sandboxing, the following modules have been disabled in the MAS build: -* `crash-reporter` -* `auto-updater` +* `crashReporter` +* `autoUpdater` and the following behaviors have been changed: @@ -108,8 +117,44 @@ and the following behaviors have been changed: * Apps will not be aware of DNS changes. Also, due to the usage of app sandboxing, the resources which can be accessed by - the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for - more information. +the app are strictly limited; you can read [App Sandboxing][app-sandboxing] for +more information. + +## Cryptographic Algorithms Used by Electron + +Depending on the country and region you are located, Mac App Store may require +documenting the cryptographic algorithms used in your app, and even ask you to +submit a copy of U.S. Encryption Registration (ERN) approval. + +Electron uses following cryptographic algorithms: + +* AES - [NIST SP 800-38A](http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf), [NIST SP 800-38D](http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf), [RFC 3394](http://www.ietf.org/rfc/rfc3394.txt) +* HMAC - [FIPS 198-1](http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf) +* ECDSA - ANS X9.62–2005 +* ECDH - ANS X9.63–2001 +* HKDF - [NIST SP 800-56C](http://csrc.nist.gov/publications/nistpubs/800-56C/SP-800-56C.pdf) +* PBKDF2 - [RFC 2898](https://tools.ietf.org/html/rfc2898) +* RSA - [RFC 3447](http://www.ietf.org/rfc/rfc3447) +* SHA - [FIPS 180-4](http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf) +* Blowfish - https://www.schneier.com/cryptography/blowfish/ +* CAST - [RFC 2144](https://tools.ietf.org/html/rfc2144), [RFC 2612](https://tools.ietf.org/html/rfc2612) +* DES - [FIPS 46-3](http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf) +* DH - [RFC 2631](https://tools.ietf.org/html/rfc2631) +* DSA - [ANSI X9.30](http://webstore.ansi.org/RecordDetail.aspx?sku=ANSI+X9.30-1%3A1997) +* EC - [SEC 1](http://www.secg.org/sec1-v2.pdf) +* IDEA - "On the Design and Security of Block Ciphers" book by X. Lai +* MD2 - [RFC 1319](http://tools.ietf.org/html/rfc1319) +* MD4 - [RFC 6150](https://tools.ietf.org/html/rfc6150) +* MD5 - [RFC 1321](https://tools.ietf.org/html/rfc1321) +* MDC2 - [ISO/IEC 10118-2](https://www.openssl.org/docs/manmaster/crypto/mdc2.html) +* RC2 - [RFC 2268](https://tools.ietf.org/html/rfc2268) +* RC4 - [RFC 4345](https://tools.ietf.org/html/rfc4345) +* RC5 - http://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf +* RIPEMD - [ISO/IEC 10118-3](http://webstore.ansi.org/RecordDetail.aspx?sku=ISO%2FIEC%2010118-3:2004) + +On how to get the ERN approval, you can reference the article: [How to legally +submit an app to Apple’s App Store when it uses encryption (or how to obtain an +ERN)][ern-tutorial]. [developer-program]: https://developer.apple.com/support/compare-memberships/ [submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html @@ -118,3 +163,5 @@ Also, due to the usage of app sandboxing, the resources which can be accessed by [create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html [submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html [app-sandboxing]: https://developer.apple.com/app-sandboxing/ +[issue-3871]: https://github.com/atom/electron/issues/3871 +[ern-tutorial]: https://carouselapps.com/2015/12/15/legally-submit-app-apples-app-store-uses-encryption-obtain-ern/ From 30b35644f60294c8cf2d0825ad75c704cb46b623 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 29 Jan 2016 12:43:35 +0800 Subject: [PATCH 084/688] Bump v0.36.6 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index 074e95360b6..ad3c5a8ef69 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.36.5', + 'version%': '0.36.6', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 7d5571189e5..ca91a1f8ca4 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.36.5 + 0.36.6 CFBundleShortVersionString - 0.36.5 + 0.36.6 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 2a80d5ff3a9..4f4be2777be 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,36,5,0 - PRODUCTVERSION 0,36,5,0 + FILEVERSION 0,36,6,0 + PRODUCTVERSION 0,36,6,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.36.5" + VALUE "FileVersion", "0.36.6" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.36.5" + VALUE "ProductVersion", "0.36.6" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 7399b847653..13d71dc47a8 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 36 -#define ATOM_PATCH_VERSION 5 +#define ATOM_PATCH_VERSION 6 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index a12107252da..20b97a4c906 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.36.5", + "version": "0.36.6", "devDependencies": { "asar": "^0.9.0", "eslint": "^1.10.3", From 85e13333c3e0bd1b15738fb98c23ebaedbf1f6e8 Mon Sep 17 00:00:00 2001 From: Robo Date: Sat, 23 Jan 2016 18:59:47 +0530 Subject: [PATCH 085/688] webview: add permission-request event --- atom/browser/api/atom_api_web_contents.cc | 13 ++ atom/browser/api/atom_api_web_contents.h | 4 + atom/browser/atom_browser_client.cc | 18 +++ atom/browser/atom_browser_client.h | 2 + atom/browser/lib/guest-view-manager.js | 22 +++- .../browser/web_contents_permission_helper.cc | 114 ++++++++++++++++++ atom/browser/web_contents_permission_helper.h | 48 ++++++++ atom/common/api/event_emitter_caller.h | 1 + .../lib/web-view/guest-view-internal.js | 12 +- .../lib/web-view/web-view-attributes.js | 1 + docs/api/web-view-tag.md | 26 ++++ filenames.gypi | 2 + 12 files changed, 260 insertions(+), 3 deletions(-) create mode 100644 atom/browser/web_contents_permission_helper.cc create mode 100644 atom/browser/web_contents_permission_helper.h diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 2b14bdc60d8..990d78aa9ca 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -14,6 +14,7 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/native_window.h" +#include "atom/browser/web_contents_permission_helper.h" #include "atom/browser/web_contents_preferences.h" #include "atom/browser/web_view_guest_delegate.h" #include "atom/common/api/api_messages.h" @@ -262,6 +263,9 @@ WebContents::WebContents(v8::Isolate* isolate, // Save the preferences in C++. new WebContentsPreferences(web_contents, options); + // Initialze permission helper. + new WebContentsPermissionHelper(web_contents, this); + web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); if (is_guest) { @@ -444,6 +448,15 @@ void WebContents::FindReply(content::WebContents* web_contents, } } +void WebContents::RequestMediaAccessPermission( + content::WebContents* web_contents, + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) { + auto permission_helper = + WebContentsPermissionHelper::FromWebContents(web_contents); + permission_helper->RequestMediaAccessPermission(request, callback); +} + void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) { // Do nothing, we override this method just to avoid compilation error since // there are two virtual functions named BeforeUnloadFired. diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 10ac7a4f769..6587759efb9 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -195,6 +195,10 @@ class WebContents : public mate::TrackableObject, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) override; + void RequestMediaAccessPermission( + content::WebContents* web_contents, + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) override; // content::WebContentsObserver: void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 5ad8e69ffc7..49637f5342f 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -15,6 +15,7 @@ #include "atom/browser/atom_resource_dispatcher_host_delegate.h" #include "atom/browser/atom_speech_recognition_manager_delegate.h" #include "atom/browser/native_window.h" +#include "atom/browser/web_contents_permission_helper.h" #include "atom/browser/web_contents_preferences.h" #include "atom/browser/window_list.h" #include "atom/common/options_switches.h" @@ -281,6 +282,23 @@ brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( return new AtomBrowserMainParts; } +void AtomBrowserClient::WebNotificationAllowed(int render_process_id, + const base::Closure& callback) { + content::WebContents* web_contents = content::WebContents::FromRenderViewHost( + content::RenderViewHost::FromID(render_process_id, kDefaultRoutingID)); + if (!web_contents) { + callback.Run(); + return; + } + auto permission_helper = + WebContentsPermissionHelper::FromWebContents(web_contents); + if (!permission_helper) { + callback.Run(); + return; + } + permission_helper->RequestWebNotificationPermission(callback); +} + void AtomBrowserClient::RenderProcessHostDestroyed( content::RenderProcessHost* host) { int process_id = host->GetID(); diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index 3c54fab40bc..9e0e979db88 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -81,6 +81,8 @@ class AtomBrowserClient : public brightray::BrowserClient, // brightray::BrowserClient: brightray::BrowserMainParts* OverrideCreateBrowserMainParts( const content::MainFunctionParams&) override; + void WebNotificationAllowed(int render_process_id, + const base::Closure& callback) override; // content::RenderProcessHostObserver: void RenderProcessHostDestroyed(content::RenderProcessHost* host) override; diff --git a/atom/browser/lib/guest-view-manager.js b/atom/browser/lib/guest-view-manager.js index 40f59691e7a..233b1f1e415 100644 --- a/atom/browser/lib/guest-view-manager.js +++ b/atom/browser/lib/guest-view-manager.js @@ -6,10 +6,12 @@ var slice = [].slice; // Doesn't exist in early initialization. var webViewManager = null; -var supportedWebViewEvents = ['load-commit', 'did-finish-load', 'did-fail-load', 'did-frame-finish-load', 'did-start-loading', 'did-stop-loading', 'did-get-response-details', 'did-get-redirect-request', 'dom-ready', 'console-message', 'devtools-opened', 'devtools-closed', 'devtools-focused', 'new-window', 'will-navigate', 'did-navigate', 'did-navigate-in-page', 'close', 'crashed', 'gpu-crashed', 'plugin-crashed', 'destroyed', 'page-title-updated', 'page-favicon-updated', 'enter-html-full-screen', 'leave-html-full-screen', 'media-started-playing', 'media-paused', 'found-in-page', 'did-change-theme-color']; +var supportedWebViewEvents = ['load-commit', 'did-finish-load', 'did-fail-load', 'did-frame-finish-load', 'did-start-loading', 'did-stop-loading', 'did-get-response-details', 'did-get-redirect-request', 'dom-ready', 'console-message', 'devtools-opened', 'devtools-closed', 'devtools-focused', 'new-window', 'will-navigate', 'did-navigate', 'did-navigate-in-page', 'close', 'crashed', 'gpu-crashed', 'plugin-crashed', 'destroyed', 'page-title-updated', 'page-favicon-updated', 'enter-html-full-screen', 'leave-html-full-screen', 'media-started-playing', 'media-paused', 'found-in-page', 'did-change-theme-color', 'permission-request']; var nextInstanceId = 0; +var permissionRequests; var guestInstances = {}; +var guestPermissionRequestsMap = {}; var embedderElementsMap = {}; var reverseEmbedderElementsMap = {}; @@ -110,6 +112,13 @@ var createGuest = function(embedder, params) { fn = function(event) { return guest.on(event, function() { var args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + if (event === 'permission-request') { + if (!guestPermissionRequestsMap[guest.viewInstanceId]) + guestPermissionRequestsMap[guest.viewInstanceId] = {}; + var permission = args[0]; + guestPermissionRequestsMap[guest.viewInstanceId][permission] = args[1]; + args.pop(); + } return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + guest.viewInstanceId, event].concat(slice.call(args))); }); }; @@ -157,7 +166,8 @@ var attachGuest = function(embedder, elementInstanceId, guestInstanceId, params) nodeIntegration: (ref1 = params.nodeintegration) != null ? ref1 : false, plugins: params.plugins, webSecurity: !params.disablewebsecurity, - blinkFeatures: params.blinkfeatures + blinkFeatures: params.blinkfeatures, + webNotification: !params.disablewebnotification, }; if (params.preload) { webPreferences.preloadURL = params.preload; @@ -174,6 +184,7 @@ var destroyGuest = function(embedder, id) { webViewManager.removeGuest(embedder, id); guestInstances[id].guest.destroy(); delete guestInstances[id]; + delete permissionRequests[id]; key = reverseEmbedderElementsMap[id]; if (key != null) { delete reverseEmbedderElementsMap[id]; @@ -193,6 +204,13 @@ ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', function(event, id) { return destroyGuest(event.sender, id); }); +ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE', function(event, viewInstanceId, permission, allowed) { + permissionRequests = guestPermissionRequestsMap[viewInstanceId]; + if (permissionRequests && permissionRequests[permission] !== null) { + permissionRequests[permission].apply(null, [allowed]); + } +}); + ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', function(event, id, params) { var ref1; return (ref1 = guestInstances[id]) != null ? ref1.guest.setSize(params) : void 0; diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc new file mode 100644 index 00000000000..91ae6046177 --- /dev/null +++ b/atom/browser/web_contents_permission_helper.cc @@ -0,0 +1,114 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/web_contents_permission_helper.h" + +#include + +#include "atom/browser/api/atom_api_web_contents.h" +#include "content/public/browser/media_capture_devices.h" + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::WebContentsPermissionHelper); + +namespace atom { + +namespace { + +const content::MediaStreamDevice* FindDeviceWithId( + const content::MediaStreamDevices& devices, + const std::string& device_id) { + if (device_id.empty()) + return &(*devices.begin()); + for (const auto& iter : devices) + if (iter.id == device_id) + return &(iter); + return nullptr; +} + +void MediaAccessAllowed( + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) { + content::MediaStreamDevices devices; + content::MediaStreamRequestResult result = content::MEDIA_DEVICE_NO_HARDWARE; + + if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) { + const content::MediaStreamDevices& audio_devices = + content::MediaCaptureDevices::GetInstance()->GetAudioCaptureDevices(); + const content::MediaStreamDevice* audio_device = + FindDeviceWithId(audio_devices, request.requested_audio_device_id); + if (audio_device) + devices.push_back(*audio_device); + } + + if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) { + const content::MediaStreamDevices& video_devices = + content::MediaCaptureDevices::GetInstance()->GetVideoCaptureDevices(); + const content::MediaStreamDevice* video_device = + FindDeviceWithId(video_devices, request.requested_video_device_id); + if (video_device) + devices.push_back(*video_device); + } + + if (!devices.empty()) + result = content::MEDIA_DEVICE_OK; + + callback.Run(devices, result, scoped_ptr()); +} + +} // namespace + +WebContentsPermissionHelper::WebContentsPermissionHelper( + content::WebContents* web_contents, + api::WebContents* api_web_contents) + : api_web_contents_(api_web_contents) { + web_contents->SetUserData(UserDataKey(), this); +} + +WebContentsPermissionHelper::~WebContentsPermissionHelper() { +} + +void WebContentsPermissionHelper::RequestMediaAccessPermission( + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) { + if (api_web_contents_->IsGuest()) { + const std::string& permission = "media"; + permission_map_[permission] = base::Bind(&MediaAccessAllowed, + request, + callback); + api_web_contents_->Emit( + "permission-request", + permission, + base::Bind(&WebContentsPermissionHelper::OnPermissionResponse, + base::Unretained(this), permission)); + return; + } + MediaAccessAllowed(request, callback); +} + +void WebContentsPermissionHelper::RequestWebNotificationPermission( + const base::Closure& callback) { + if (api_web_contents_->IsGuest()) { + const std::string& permission = "webNotification"; + permission_map_[permission] = callback; + api_web_contents_->Emit( + "permission-request", + permission, + base::Bind(&WebContentsPermissionHelper::OnPermissionResponse, + base::Unretained(this), permission)); + return; + } + callback.Run(); +} + +void WebContentsPermissionHelper::OnPermissionResponse( + const std::string& permission, bool allowed) { + auto it = permission_map_.find(permission); + if (it != permission_map_.end()) { + if (allowed) + it->second.Run(); + permission_map_.erase(permission); + } +} + +} // namespace atom diff --git a/atom/browser/web_contents_permission_helper.h b/atom/browser/web_contents_permission_helper.h new file mode 100644 index 00000000000..80e76fd685a --- /dev/null +++ b/atom/browser/web_contents_permission_helper.h @@ -0,0 +1,48 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_ +#define ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_ + +#include +#include + +#include "base/callback.h" +#include "content/public/browser/web_contents_user_data.h" +#include "content/public/common/media_stream_request.h" + +namespace atom { + +namespace api { +class WebContents; +} + +// Applies the permission requested for WebContents. +class WebContentsPermissionHelper + : public content::WebContentsUserData { + public: + WebContentsPermissionHelper(content::WebContents* web_contents, + api::WebContents* api_web_contents); + ~WebContentsPermissionHelper() override; + + void RequestMediaAccessPermission( + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback); + void RequestWebNotificationPermission(const base::Closure& callback); + + void OnPermissionResponse(const std::string& permission, bool allowed); + + private: + friend class content::WebContentsUserData; + + std::map permission_map_; + + api::WebContents* api_web_contents_; // Weak reference + + DISALLOW_COPY_AND_ASSIGN(WebContentsPermissionHelper); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_ diff --git a/atom/common/api/event_emitter_caller.h b/atom/common/api/event_emitter_caller.h index a2567da9d10..26a4cbc45b9 100644 --- a/atom/common/api/event_emitter_caller.h +++ b/atom/common/api/event_emitter_caller.h @@ -7,6 +7,7 @@ #include +#include "atom/common/native_mate_converters/callback.h" #include "native_mate/converter.h" namespace mate { diff --git a/atom/renderer/lib/web-view/guest-view-internal.js b/atom/renderer/lib/web-view/guest-view-internal.js index a7427abd631..e6a1519b0f4 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.js +++ b/atom/renderer/lib/web-view/guest-view-internal.js @@ -34,7 +34,8 @@ var WEB_VIEW_EVENTS = { 'page-favicon-updated': ['favicons'], 'enter-html-full-screen': [], 'leave-html-full-screen': [], - 'found-in-page': ['result'] + 'found-in-page': ['result'], + 'permission-request': ['permission', 'allow', 'deny'] }; var DEPRECATED_EVENTS = { @@ -64,6 +65,15 @@ module.exports = { ipcRenderer.on("ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + viewInstanceId, function() { var eventName = arguments[1]; var args = 3 <= arguments.length ? slice.call(arguments, 2) : []; + if (eventName === 'permission-request') { + var allow = function allow() { + ipcRenderer.send("ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE", viewInstanceId, args[0], true); + }; + var deny = function deny() { + ipcRenderer.send("ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE", viewInstanceId, args[0], false); + }; + args = args.concat([allow, deny]); + } return dispatchEvent.apply(null, [webView, eventName, eventName].concat(slice.call(args))); }); ipcRenderer.on("ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-" + viewInstanceId, function() { diff --git a/atom/renderer/lib/web-view/web-view-attributes.js b/atom/renderer/lib/web-view/web-view-attributes.js index 4ad4bd72501..180924f5b56 100644 --- a/atom/renderer/lib/web-view/web-view-attributes.js +++ b/atom/renderer/lib/web-view/web-view-attributes.js @@ -311,6 +311,7 @@ WebViewImpl.prototype.setupWebViewAttributes = function() { this.attributes[webViewConstants.ATTRIBUTE_ALLOWPOPUPS] = new BooleanAttribute(webViewConstants.ATTRIBUTE_ALLOWPOPUPS, this); this.attributes[webViewConstants.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this); this.attributes[webViewConstants.ATTRIBUTE_BLINKFEATURES] = new BlinkFeaturesAttribute(this); + this.attributes[webViewConstants.ATTRIBUTE_DISABLEWEBNOTIFICATION] = new BooleanAttribute(webViewConstants.ATTRIBUTE_DISABLEWEBNOTIFICATION, this); autosizeAttributes = [webViewConstants.ATTRIBUTE_MAXHEIGHT, webViewConstants.ATTRIBUTE_MAXWIDTH, webViewConstants.ATTRIBUTE_MINHEIGHT, webViewConstants.ATTRIBUTE_MINWIDTH]; results = []; for (i = 0, len = autosizeAttributes.length; i < len; i++) { diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 9cb8f49af35..630dbdc9585 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -167,6 +167,14 @@ A list of strings which specifies the blink features to be enabled separated by The full list of supported feature strings can be found in the [setFeatureEnabledFromString][blink-feature-string] function. +### `disablewebnotification` + +```html + +``` + +If "on", the guest page will have web notifications disabled. + ## Methods The `webview` tag has the following methods: @@ -736,4 +744,22 @@ Emitted when DevTools is closed. Emitted when DevTools is focused / opened. +### Event: 'permission-request' + +Returns: + +* `permission` String - The type of permission being requested. Enum of 'media', 'webNotification'. +* `allow` Function - Allows the permission. +* `deny` Function - Deny the permission. This is the default behaviour if `allow` is not called. + +Emitted when guest page requires special permission. + +```javascript +// This will deny guest page access to the webkitGetUserMedia API. +webview.addEventListener('permission-request', function(e) { + if (e.permission === 'media') + e.deny(); +}); +``` + [blink-feature-string]: https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/platform/RuntimeEnabledFeatures.cpp&sq=package:chromium&type=cs&l=527 diff --git a/filenames.gypi b/filenames.gypi index 4aa47fc3580..3c9cd4b6919 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -256,6 +256,8 @@ 'atom/browser/ui/x/window_state_watcher.h', 'atom/browser/ui/x/x_window_utils.cc', 'atom/browser/ui/x/x_window_utils.h', + 'atom/browser/web_contents_permission_helper.cc', + 'atom/browser/web_contents_permission_helper.h', 'atom/browser/web_contents_preferences.cc', 'atom/browser/web_contents_preferences.h', 'atom/browser/web_dialog_helper.cc', From f32bf08eb3fa3ad63d663e81eb8af558b39dea87 Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 25 Jan 2016 22:07:15 +0530 Subject: [PATCH 086/688] add spec --- atom/browser/atom_browser_client.cc | 9 ++--- atom/browser/atom_browser_client.h | 5 +-- atom/browser/lib/guest-view-manager.js | 36 +++++++++++++++++-- .../browser/web_contents_permission_helper.cc | 19 ++++++---- atom/browser/web_contents_permission_helper.h | 5 +-- .../lib/web-view/web-view-attributes.js | 1 - docs/api/web-view-tag.md | 8 ----- spec/fixtures/pages/permission-request.html | 7 ++++ spec/webview-spec.js | 19 +++++++++- 9 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 spec/fixtures/pages/permission-request.html diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 49637f5342f..b395f3dd0cb 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -282,18 +282,19 @@ brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( return new AtomBrowserMainParts; } -void AtomBrowserClient::WebNotificationAllowed(int render_process_id, - const base::Closure& callback) { +void AtomBrowserClient::WebNotificationAllowed( + int render_process_id, + const base::Callback& callback) { content::WebContents* web_contents = content::WebContents::FromRenderViewHost( content::RenderViewHost::FromID(render_process_id, kDefaultRoutingID)); if (!web_contents) { - callback.Run(); + callback.Run(true); return; } auto permission_helper = WebContentsPermissionHelper::FromWebContents(web_contents); if (!permission_helper) { - callback.Run(); + callback.Run(true); return; } permission_helper->RequestWebNotificationPermission(callback); diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index 9e0e979db88..4af66cc041a 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -81,8 +81,9 @@ class AtomBrowserClient : public brightray::BrowserClient, // brightray::BrowserClient: brightray::BrowserMainParts* OverrideCreateBrowserMainParts( const content::MainFunctionParams&) override; - void WebNotificationAllowed(int render_process_id, - const base::Closure& callback) override; + void WebNotificationAllowed( + int render_process_id, + const base::Callback& callback) override; // content::RenderProcessHostObserver: void RenderProcessHostDestroyed(content::RenderProcessHost* host) override; diff --git a/atom/browser/lib/guest-view-manager.js b/atom/browser/lib/guest-view-manager.js index 233b1f1e415..b50d0c9503f 100644 --- a/atom/browser/lib/guest-view-manager.js +++ b/atom/browser/lib/guest-view-manager.js @@ -6,7 +6,39 @@ var slice = [].slice; // Doesn't exist in early initialization. var webViewManager = null; -var supportedWebViewEvents = ['load-commit', 'did-finish-load', 'did-fail-load', 'did-frame-finish-load', 'did-start-loading', 'did-stop-loading', 'did-get-response-details', 'did-get-redirect-request', 'dom-ready', 'console-message', 'devtools-opened', 'devtools-closed', 'devtools-focused', 'new-window', 'will-navigate', 'did-navigate', 'did-navigate-in-page', 'close', 'crashed', 'gpu-crashed', 'plugin-crashed', 'destroyed', 'page-title-updated', 'page-favicon-updated', 'enter-html-full-screen', 'leave-html-full-screen', 'media-started-playing', 'media-paused', 'found-in-page', 'did-change-theme-color', 'permission-request']; +var supportedWebViewEvents = [ + 'load-commit', + 'did-finish-load', + 'did-fail-load', + 'did-frame-finish-load', + 'did-start-loading', + 'did-stop-loading', + 'did-get-response-details', + 'did-get-redirect-request', + 'dom-ready', + 'console-message', + 'devtools-opened', + 'devtools-closed', + 'devtools-focused', + 'new-window', + 'will-navigate', + 'did-navigate', + 'did-navigate-in-page', + 'close', + 'crashed', + 'gpu-crashed', + 'plugin-crashed', + 'destroyed', + 'page-title-updated', + 'page-favicon-updated', + 'enter-html-full-screen', + 'leave-html-full-screen', + 'media-started-playing', + 'media-paused', + 'found-in-page', + 'did-change-theme-color', + 'permission-request' +]; var nextInstanceId = 0; var permissionRequests; @@ -184,7 +216,7 @@ var destroyGuest = function(embedder, id) { webViewManager.removeGuest(embedder, id); guestInstances[id].guest.destroy(); delete guestInstances[id]; - delete permissionRequests[id]; + delete guestPermissionRequestsMap[id]; key = reverseEmbedderElementsMap[id]; if (key != null) { delete reverseEmbedderElementsMap[id]; diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index 91ae6046177..5c82aa41df6 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -28,7 +28,15 @@ const content::MediaStreamDevice* FindDeviceWithId( void MediaAccessAllowed( const content::MediaStreamRequest& request, - const content::MediaResponseCallback& callback) { + const content::MediaResponseCallback& callback, + bool allowed) { + if (!allowed) { + callback.Run(content::MediaStreamDevices(), + content::MEDIA_DEVICE_PERMISSION_DENIED, + scoped_ptr()); + return; + } + content::MediaStreamDevices devices; content::MediaStreamRequestResult result = content::MEDIA_DEVICE_NO_HARDWARE; @@ -83,11 +91,11 @@ void WebContentsPermissionHelper::RequestMediaAccessPermission( base::Unretained(this), permission)); return; } - MediaAccessAllowed(request, callback); + MediaAccessAllowed(request, callback, true); } void WebContentsPermissionHelper::RequestWebNotificationPermission( - const base::Closure& callback) { + const base::Callback& callback) { if (api_web_contents_->IsGuest()) { const std::string& permission = "webNotification"; permission_map_[permission] = callback; @@ -98,15 +106,14 @@ void WebContentsPermissionHelper::RequestWebNotificationPermission( base::Unretained(this), permission)); return; } - callback.Run(); + callback.Run(true); } void WebContentsPermissionHelper::OnPermissionResponse( const std::string& permission, bool allowed) { auto it = permission_map_.find(permission); if (it != permission_map_.end()) { - if (allowed) - it->second.Run(); + it->second.Run(allowed); permission_map_.erase(permission); } } diff --git a/atom/browser/web_contents_permission_helper.h b/atom/browser/web_contents_permission_helper.h index 80e76fd685a..4beac035c02 100644 --- a/atom/browser/web_contents_permission_helper.h +++ b/atom/browser/web_contents_permission_helper.h @@ -29,14 +29,15 @@ class WebContentsPermissionHelper void RequestMediaAccessPermission( const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback); - void RequestWebNotificationPermission(const base::Closure& callback); + void RequestWebNotificationPermission( + const base::Callback& callback); void OnPermissionResponse(const std::string& permission, bool allowed); private: friend class content::WebContentsUserData; - std::map permission_map_; + std::map> permission_map_; api::WebContents* api_web_contents_; // Weak reference diff --git a/atom/renderer/lib/web-view/web-view-attributes.js b/atom/renderer/lib/web-view/web-view-attributes.js index 180924f5b56..4ad4bd72501 100644 --- a/atom/renderer/lib/web-view/web-view-attributes.js +++ b/atom/renderer/lib/web-view/web-view-attributes.js @@ -311,7 +311,6 @@ WebViewImpl.prototype.setupWebViewAttributes = function() { this.attributes[webViewConstants.ATTRIBUTE_ALLOWPOPUPS] = new BooleanAttribute(webViewConstants.ATTRIBUTE_ALLOWPOPUPS, this); this.attributes[webViewConstants.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this); this.attributes[webViewConstants.ATTRIBUTE_BLINKFEATURES] = new BlinkFeaturesAttribute(this); - this.attributes[webViewConstants.ATTRIBUTE_DISABLEWEBNOTIFICATION] = new BooleanAttribute(webViewConstants.ATTRIBUTE_DISABLEWEBNOTIFICATION, this); autosizeAttributes = [webViewConstants.ATTRIBUTE_MAXHEIGHT, webViewConstants.ATTRIBUTE_MAXWIDTH, webViewConstants.ATTRIBUTE_MINHEIGHT, webViewConstants.ATTRIBUTE_MINWIDTH]; results = []; for (i = 0, len = autosizeAttributes.length; i < len; i++) { diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 630dbdc9585..67a3d12171c 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -167,14 +167,6 @@ A list of strings which specifies the blink features to be enabled separated by The full list of supported feature strings can be found in the [setFeatureEnabledFromString][blink-feature-string] function. -### `disablewebnotification` - -```html - -``` - -If "on", the guest page will have web notifications disabled. - ## Methods The `webview` tag has the following methods: diff --git a/spec/fixtures/pages/permission-request.html b/spec/fixtures/pages/permission-request.html new file mode 100644 index 00000000000..0d968a9a66b --- /dev/null +++ b/spec/fixtures/pages/permission-request.html @@ -0,0 +1,7 @@ + diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 0eaa59c5fd3..e40afcaefeb 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -624,7 +624,7 @@ describe(' tag', function() { return document.body.appendChild(webview); }); }); - return xdescribe('did-change-theme-color event', function() { + xdescribe('did-change-theme-color event', function() { return it('emits when theme color changes', function(done) { webview.addEventListener('did-change-theme-color', function() { return done(); @@ -633,4 +633,21 @@ describe(' tag', function() { return document.body.appendChild(webview); }); }); + describe('permission-request event', function() { + it ('emits when using navigator.getUserMedia api', function(done) { + webview.addEventListener('ipc-message', function(e) { + assert(e.channel, 'message'); + assert(e.args, ['PermissionDeniedError']); + done(); + }); + webview.addEventListener('permission-request', function(e) { + if (e.permission === 'media') { + e.deny(); + } + }); + webview.src = "file://" + fixtures + "/pages/permission-request.html"; + webview.setAttribute('nodeintegration', 'on'); + document.body.appendChild(webview); + }); + }); }); From 7a370ccd0f0aee2480e9fec2704b77dfb9747373 Mon Sep 17 00:00:00 2001 From: Simon Madine Date: Fri, 29 Jan 2016 12:30:19 +0100 Subject: [PATCH 087/688] :apple: Add 'Hide' to App API for OS X only --- atom/browser/api/atom_api_app.cc | 1 + atom/browser/browser.h | 3 +++ atom/browser/browser_mac.mm | 4 ++++ docs/api/app.md | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 394014e8b27..441b05587a2 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -356,6 +356,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("quit", base::Bind(&Browser::Quit, browser)) .SetMethod("exit", base::Bind(&Browser::Exit, browser)) .SetMethod("focus", base::Bind(&Browser::Focus, browser)) + .SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("getVersion", base::Bind(&Browser::GetVersion, browser)) .SetMethod("setVersion", base::Bind(&Browser::SetVersion, browser)) .SetMethod("getName", base::Bind(&Browser::GetName, browser)) diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 0b55fb600cf..711415e39cc 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -55,6 +55,9 @@ class Browser : public WindowListObserver { // Focus the application. void Focus(); + // Focus the application. + void Hide(); + // Returns the version of the executable (or bundle). std::string GetVersion() const; diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 1eb7fabdab0..db898017b3d 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -18,6 +18,10 @@ void Browser::Focus() { [[AtomApplication sharedApplication] activateIgnoringOtherApps:YES]; } +void Browser::Hide() { + [[AtomApplication sharedApplication] hide:nil]; +} + void Browser::AddRecentDocument(const base::FilePath& path) { NSString* path_string = base::mac::FilePathToNSString(path); if (!path_string) diff --git a/docs/api/app.md b/docs/api/app.md index a26defb447a..808f5fabadc 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -244,6 +244,10 @@ This method guarantees that all `beforeunload` and `unload` event handlers are correctly executed. It is possible that a window cancels the quitting by returning `false` in the `beforeunload` event handler. +### `app.hide()` _OS X_ + +Hides all application windows without minimising them. + ### `app.exit(exitCode)` * `exitCode` Integer From 0169f31feba407ccd8e18b5079db6c3940fc784e Mon Sep 17 00:00:00 2001 From: Petr Felzmann Date: Fri, 29 Jan 2016 20:10:18 +0100 Subject: [PATCH 088/688] fix bullets formatting in documentation --- docs/api/session.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/api/session.md b/docs/api/session.md index da5bac23592..fed8c31c746 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -213,6 +213,7 @@ proxyURL = ["://"][":"] ``` For example: + * `http=foopy:80;ftp=foopy2` - Use HTTP proxy `foopy:80` for `http://` URLs, and HTTP proxy `foopy2:80` for `ftp://` URLs. * `foopy:80` - Use HTTP proxy `foopy:80` for all URLs. From bdc2b2559c8b72fa3a9c2c7f335d459ea6356713 Mon Sep 17 00:00:00 2001 From: Brad Metcalf Date: Fri, 29 Jan 2016 13:27:47 -0600 Subject: [PATCH 089/688] Added missing angle bracket to replace() method --- docs/api/web-view-tag.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 9cb8f49af35..c410287553a 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -361,7 +361,7 @@ Executes editing command `selectAll` in page. Executes editing command `unselect` in page. -### `.replace(text)` * `text` String From 839612c9ae88d8ba6a55ec4f93036aac2b815355 Mon Sep 17 00:00:00 2001 From: Luke Adams Date: Fri, 29 Jan 2016 13:57:48 -0600 Subject: [PATCH 090/688] Bump minimum OSX version to 10.9 --- atom/browser/resources/mac/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index ca91a1f8ca4..74cb6e5e67e 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -23,7 +23,7 @@ LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion - 10.8.0 + 10.9.0 NSMainNibFile MainMenu NSPrincipalClass From 1002d0de74ef19cea3176eb5f56d48cf6c273294 Mon Sep 17 00:00:00 2001 From: Luke Adams Date: Fri, 29 Jan 2016 14:03:49 -0600 Subject: [PATCH 091/688] Bump minimum OSX version to 10.9 (documentation) --- docs/tutorial/supported-platforms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/supported-platforms.md b/docs/tutorial/supported-platforms.md index 9d1a293d5f5..a7f736995d2 100644 --- a/docs/tutorial/supported-platforms.md +++ b/docs/tutorial/supported-platforms.md @@ -5,7 +5,7 @@ Following platforms are supported by Electron: ### OS X Only 64bit binaries are provided for OS X, and the minimum OS X version -supported is OS X 10.8. +supported is OS X 10.9. ### Windows From 6a643ec3c86852a17edb472b1a1b9b53120f3ace Mon Sep 17 00:00:00 2001 From: Simon Madine Date: Fri, 29 Jan 2016 22:51:06 +0100 Subject: [PATCH 092/688] Only add Hide if OS_X is defined --- atom/browser/api/atom_api_app.cc | 4 +++- atom/browser/browser.h | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 441b05587a2..0562cf893af 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -356,7 +356,6 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("quit", base::Bind(&Browser::Quit, browser)) .SetMethod("exit", base::Bind(&Browser::Exit, browser)) .SetMethod("focus", base::Bind(&Browser::Focus, browser)) - .SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("getVersion", base::Bind(&Browser::GetVersion, browser)) .SetMethod("setVersion", base::Bind(&Browser::SetVersion, browser)) .SetMethod("getName", base::Bind(&Browser::GetName, browser)) @@ -368,6 +367,9 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( base::Bind(&Browser::ClearRecentDocuments, browser)) .SetMethod("setAppUserModelId", base::Bind(&Browser::SetAppUserModelID, browser)) +#if defined(OS_MACOSX) + .SetMethod("hide", base::Bind(&Browser::Hide, browser)) +#endif #if defined(OS_WIN) .SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser)) diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 711415e39cc..dc811fc4a6f 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -55,9 +55,6 @@ class Browser : public WindowListObserver { // Focus the application. void Focus(); - // Focus the application. - void Hide(); - // Returns the version of the executable (or bundle). std::string GetVersion() const; @@ -80,6 +77,9 @@ class Browser : public WindowListObserver { void SetAppUserModelID(const base::string16& name); #if defined(OS_MACOSX) + // Hide the application. + void Hide(); + // Bounce the dock icon. enum BounceType { BOUNCE_CRITICAL = 0, From 899294a0408b950495906e8297084617bd412319 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Jan 2016 11:47:22 +0800 Subject: [PATCH 093/688] win: Don't close the handle since we already closed the fd Fix #4266. --- atom/common/asar/archive.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index 7527932b977..37ff0f45d60 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -130,8 +130,11 @@ Archive::Archive(const base::FilePath& path) Archive::~Archive() { #if defined(OS_WIN) - if (fd_ != -1) + if (fd_ != -1) { _close(fd_); + // Don't close the handle since we already closed the fd. + file_.TakePlatformFile(); + } #endif } From 5d16257c2d2ed70b74583bd9bbf9f05e73ef994d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Jan 2016 12:20:28 +0800 Subject: [PATCH 094/688] Fix "Object has been destroyed" error in "page-title-updated" event Close #4249. --- atom/browser/api/lib/browser-window.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/lib/browser-window.js b/atom/browser/api/lib/browser-window.js index b71c85a1910..a9649f853d7 100644 --- a/atom/browser/api/lib/browser-window.js +++ b/atom/browser/api/lib/browser-window.js @@ -55,14 +55,16 @@ BrowserWindow.prototype._init = function() { })(this)); // Change window title to page title. - this.webContents.on('page-title-updated', (function(_this) { - return function(event, title) { - _this.emit('page-title-updated', event, title); - if (!event.defaultPrevented) { - return _this.setTitle(title); - } - }; - })(this)); + this.webContents.on('page-title-updated', (event, title) => { + // The page-title-updated event is not emitted immediately (see #3645), so + // when the callback is called the BrowserWindow might have been closed. + if (this.isDestroyed()) + return; + // Route the event to BrowserWindow. + this.emit('page-title-updated', event, title); + if (!event.defaultPrevented) + this.setTitle(title); + }); // Sometimes the webContents doesn't get focus when window is shown, so we have // to force focusing on webContents in this case. The safest way is to focus it From 3f68b2f22780e830296602dc9feaac88aed80e8d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Jan 2016 12:58:21 +0800 Subject: [PATCH 095/688] Check whether sender is destroyed before calling sender.send Fix #4279. --- atom/browser/lib/rpc-server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index b3e6ddc7832..2f2b739e4a1 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -162,12 +162,12 @@ var unwrapArgs = function(sender, args) { }); let callIntoRenderer = function(...args) { - if (rendererReleased) + if (rendererReleased || sender.isDestroyed()) throw new Error(`Attempting to call a function in a renderer window that has been closed or released. Function provided here: ${meta.location}.`); sender.send('ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, args)); }; v8Util.setDestructor(callIntoRenderer, function() { - if (!rendererReleased) + if (!rendererReleased && !sender.isDestroyed()) sender.send('ATOM_RENDERER_RELEASE_CALLBACK', meta.id); }); sender.callbacks.set(meta.id, callIntoRenderer); From 9d8e23c8229aa31fb4ece7bae5e0857696a8e075 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Jan 2016 13:20:46 +0800 Subject: [PATCH 096/688] Bump v0.36.7 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index ad3c5a8ef69..dbaf6db5629 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.36.6', + 'version%': '0.36.7', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 74cb6e5e67e..74725c94dc5 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.36.6 + 0.36.7 CFBundleShortVersionString - 0.36.6 + 0.36.7 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 4f4be2777be..298d0bce73c 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,36,6,0 - PRODUCTVERSION 0,36,6,0 + FILEVERSION 0,36,7,0 + PRODUCTVERSION 0,36,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.36.6" + VALUE "FileVersion", "0.36.7" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.36.6" + VALUE "ProductVersion", "0.36.7" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 13d71dc47a8..a4f886c7e7d 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 36 -#define ATOM_PATCH_VERSION 6 +#define ATOM_PATCH_VERSION 7 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index 20b97a4c906..3f0983bc441 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.36.6", + "version": "0.36.7", "devDependencies": { "asar": "^0.9.0", "eslint": "^1.10.3", From 0c9174bc7ca28e6e879704f69a5c7d24bbe674bb Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Sat, 30 Jan 2016 06:33:55 +0100 Subject: [PATCH 097/688] Introduced the cursor-changed event with one parameter - the name of the cursor type --- atom/browser/api/atom_api_web_contents.cc | 9 ++ atom/browser/api/atom_api_web_contents.h | 3 + filenames.gypi | 2 + mw/cursor/cursor_event_filter.cc | 150 ++++++++++++++++++++++ mw/cursor/cursor_event_filter.h | 30 +++++ 5 files changed, 194 insertions(+) create mode 100644 mw/cursor/cursor_event_filter.cc create mode 100644 mw/cursor/cursor_event_filter.h diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 2b14bdc60d8..0b557f2dfc4 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -56,9 +56,12 @@ #include "net/url_request/url_request_context.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/base/l10n/l10n_util.h" +#include "mw/cursor/cursor_event_filter.h" #include "atom/common/node_includes.h" +#include + namespace { struct PrintSettings { @@ -619,6 +622,8 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage) IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync, OnRendererMessageSync) + IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange, + handled = false) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -1039,6 +1044,10 @@ void WebContents::EndFrameSubscription() { view->EndFrameSubscription(); } +void WebContents::OnCursorChange(const content::WebCursor& cursor) { + Emit("cursor-changed", CursorChangeEvent::toString(cursor)); +} + void WebContents::SetSize(const SetSizeParams& params) { if (guest_delegate_) guest_delegate_->SetSize(params); diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 10ac7a4f769..21e201c7af1 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -14,6 +14,7 @@ #include "atom/browser/common_web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/favicon_url.h" +#include "content/common/cursors/webcursor.h" #include "native_mate/handle.h" #include "ui/gfx/image/image.h" @@ -255,6 +256,8 @@ class WebContents : public mate::TrackableObject, return ++request_id_; } + void OnCursorChange(const content::WebCursor& cursor); + // Called when received a message from renderer. void OnRendererMessage(const base::string16& channel, const base::ListValue& args); diff --git a/filenames.gypi b/filenames.gypi index 4aa47fc3580..b94d2b752cf 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -371,6 +371,8 @@ 'atom/renderer/node_array_buffer_bridge.h', 'atom/utility/atom_content_utility_client.cc', 'atom/utility/atom_content_utility_client.h', + 'mw/cursor/cursor_event_filter.cc', + 'mw/cursor/cursor_event_filter.h', 'chromium_src/chrome/browser/browser_process.cc', 'chromium_src/chrome/browser/browser_process.h', 'chromium_src/chrome/browser/chrome_process_finder_win.cc', diff --git a/mw/cursor/cursor_event_filter.cc b/mw/cursor/cursor_event_filter.cc new file mode 100644 index 00000000000..00c6d58bdfe --- /dev/null +++ b/mw/cursor/cursor_event_filter.cc @@ -0,0 +1,150 @@ +#include "mw/cursor/cursor_event_filter.h" +#include "content/common/view_messages.h" + +namespace atom { + +std::string CursorChangeEvent::toString( + const content::WebCursor& cursor) { + content::WebCursor::CursorInfo* info = new content::WebCursor::CursorInfo(); + cursor.GetCursorInfo(info); + + switch(info->type){ + case blink::WebCursorInfo::Type::TypePointer: + return "Pointer"; + break; + case blink::WebCursorInfo::Type::TypeCross: + return "Cross"; + break; + case blink::WebCursorInfo::Type::TypeHand: + return "Hand"; + break; + case blink::WebCursorInfo::Type::TypeIBeam: + return "IBeam"; + break; + case blink::WebCursorInfo::Type::TypeWait: + return "Wait"; + break; + case blink::WebCursorInfo::Type::TypeHelp: + return "Help"; + break; + case blink::WebCursorInfo::Type::TypeEastResize: + return "EastResize"; + break; + case blink::WebCursorInfo::Type::TypeNorthResize: + return "NorthResize"; + break; + case blink::WebCursorInfo::Type::TypeNorthEastResize: + return "NorthEastResize"; + break; + case blink::WebCursorInfo::Type::TypeNorthWestResize: + return "NorthWestResize"; + break; + case blink::WebCursorInfo::Type::TypeSouthResize: + return "SouthResize"; + break; + case blink::WebCursorInfo::Type::TypeSouthEastResize: + return "SouthEastResize"; + break; + case blink::WebCursorInfo::Type::TypeSouthWestResize: + return "SouthWestResize"; + break; + case blink::WebCursorInfo::Type::TypeWestResize: + return "WestResize"; + break; + case blink::WebCursorInfo::Type::TypeNorthSouthResize: + return "NorthSouthResize"; + break; + case blink::WebCursorInfo::Type::TypeEastWestResize: + return "EastWestResize"; + break; + case blink::WebCursorInfo::Type::TypeNorthEastSouthWestResize: + return "NorthEastSouthWestResize"; + break; + case blink::WebCursorInfo::Type::TypeNorthWestSouthEastResize: + return "NorthWestSouthEastResize"; + break; + case blink::WebCursorInfo::Type::TypeColumnResize: + return "ColumnResize"; + break; + case blink::WebCursorInfo::Type::TypeRowResize: + return "RowResize"; + break; + case blink::WebCursorInfo::Type::TypeMiddlePanning: + return "MiddlePanning"; + break; + case blink::WebCursorInfo::Type::TypeEastPanning: + return "EastPanning"; + break; + case blink::WebCursorInfo::Type::TypeNorthPanning: + return "NorthPanning"; + break; + case blink::WebCursorInfo::Type::TypeNorthEastPanning: + return "NorthEastPanning"; + break; + case blink::WebCursorInfo::Type::TypeNorthWestPanning: + return "NorthWestPanning"; + break; + case blink::WebCursorInfo::Type::TypeSouthPanning: + return "SouthPanning"; + break; + case blink::WebCursorInfo::Type::TypeSouthEastPanning: + return "SouthEastPanning"; + break; + case blink::WebCursorInfo::Type::TypeSouthWestPanning: + return "SouthWestPanning"; + break; + case blink::WebCursorInfo::Type::TypeWestPanning: + return "WestPanning"; + break; + case blink::WebCursorInfo::Type::TypeMove: + return "Move"; + break; + case blink::WebCursorInfo::Type::TypeVerticalText: + return "VerticalText"; + break; + case blink::WebCursorInfo::Type::TypeCell: + return "Cell"; + break; + case blink::WebCursorInfo::Type::TypeContextMenu: + return "ContextMenu"; + break; + case blink::WebCursorInfo::Type::TypeAlias: + return "Alias"; + break; + case blink::WebCursorInfo::Type::TypeProgress: + return "Progress"; + break; + case blink::WebCursorInfo::Type::TypeNoDrop: + return "NoDrop"; + break; + case blink::WebCursorInfo::Type::TypeCopy: + return "Copy"; + break; + case blink::WebCursorInfo::Type::TypeNone: + return "None"; + break; + case blink::WebCursorInfo::Type::TypeNotAllowed: + return "NotAllowed"; + break; + case blink::WebCursorInfo::Type::TypeZoomIn: + return "ZoomIn"; + break; + case blink::WebCursorInfo::Type::TypeZoomOut: + return "ZoomOut"; + break; + case blink::WebCursorInfo::Type::TypeGrab: + return "Grab"; + break; + case blink::WebCursorInfo::Type::TypeGrabbing: + return "Grabbing"; + break; + case blink::WebCursorInfo::Type::TypeCustom: + return "Custom"; + break; + default: + return "Pointer"; + break; + } +} + +} diff --git a/mw/cursor/cursor_event_filter.h b/mw/cursor/cursor_event_filter.h new file mode 100644 index 00000000000..31bc74498f4 --- /dev/null +++ b/mw/cursor/cursor_event_filter.h @@ -0,0 +1,30 @@ +#ifndef MW_CURSOR_EVENT_H_ +#define MW_CURSOR_EVENT_H_ + +#include "content/common/cursors/webcursor.h" +#include "ipc/ipc_message_macros.h" + +#define IPC_MESSAGE_HANDLER_CODE(msg_class, member_func, code) \ + IPC_MESSAGE_FORWARD_CODE(msg_class, this, \ + _IpcMessageHandlerClass::member_func, code) + +#define IPC_MESSAGE_FORWARD_CODE(msg_class, obj, member_func, code) \ + case msg_class::ID: { \ + TRACK_RUN_IN_THIS_SCOPED_REGION(member_func); \ + if (!msg_class::Dispatch(&ipc_message__, obj, this, param__, \ + &member_func)) \ + ipc_message__.set_dispatch_error(); \ + code; \ + } \ + break; + +namespace atom { + +class CursorChangeEvent { + public: + static std::string toString(const content::WebCursor& cursor); +}; + +} + +#endif // MW_CURSOR_EVENT_H_ From 2a278ceb8fe1c0c40a70de40c39f400db901fd09 Mon Sep 17 00:00:00 2001 From: Robo Date: Sat, 30 Jan 2016 16:49:18 +0530 Subject: [PATCH 098/688] delegate to permission manager for other permissions --- atom/browser/api/atom_api_web_contents.cc | 18 ++- atom/browser/api/atom_api_web_contents.h | 4 + atom/browser/atom_browser_client.cc | 4 +- atom/browser/atom_browser_context.cc | 6 + atom/browser/atom_browser_context.h | 7 ++ atom/browser/atom_permission_manager.cc | 107 ++++++++++++++++++ atom/browser/atom_permission_manager.h | 75 ++++++++++++ atom/browser/lib/guest-view-manager.js | 38 +++---- .../browser/web_contents_permission_helper.cc | 56 +++------ atom/browser/web_contents_permission_helper.h | 22 ++-- .../content_converter.cc | 44 +++++++ .../content_converter.h | 14 +++ .../lib/web-view/guest-view-internal.js | 4 +- filenames.gypi | 2 + 14 files changed, 324 insertions(+), 77 deletions(-) create mode 100644 atom/browser/atom_permission_manager.cc create mode 100644 atom/browser/atom_permission_manager.h diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 990d78aa9ca..01c069cf87d 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -13,6 +13,7 @@ #include "atom/browser/atom_browser_client.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" +#include "atom/browser/atom_permission_manager.h" #include "atom/browser/native_window.h" #include "atom/browser/web_contents_permission_helper.h" #include "atom/browser/web_contents_preferences.h" @@ -263,8 +264,8 @@ WebContents::WebContents(v8::Isolate* isolate, // Save the preferences in C++. new WebContentsPreferences(web_contents, options); - // Initialze permission helper. - new WebContentsPermissionHelper(web_contents, this); + // Intialize permission helper. + WebContentsPermissionHelper::CreateForWebContents(web_contents); web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); @@ -1066,6 +1067,17 @@ bool WebContents::IsGuest() const { return type_ == WEB_VIEW; } +void WebContents::SetPermissionRequestHandler(v8::Local val, + mate::Arguments* args) { + AtomPermissionManager::RequestHandler handler; + if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) { + args->ThrowError("Must pass null or function"); + return; + } + GetBrowserContext()->permission_manager() + ->SetPermissionRequestHandler(GetID(), handler); +} + v8::Local WebContents::GetWebPreferences(v8::Isolate* isolate) { WebContentsPreferences* web_preferences = WebContentsPreferences::FromWebContents(web_contents()); @@ -1165,6 +1177,8 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("_printToPDF", &WebContents::PrintToPDF) .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) + .SetMethod("setPermissionRequestHandler", + &WebContents::SetPermissionRequestHandler) .SetProperty("session", &WebContents::Session) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents) .SetProperty("debugger", &WebContents::Debugger); diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 6587759efb9..6232aa3bf0c 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -133,6 +133,10 @@ class WebContents : public mate::TrackableObject, void SetAllowTransparency(bool allow); bool IsGuest() const; + // Handler for permission requests. + void SetPermissionRequestHandler(v8::Local val, + mate::Arguments* args); + // Returns the web preferences of current WebContents. v8::Local GetWebPreferences(v8::Isolate* isolate); diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index b395f3dd0cb..1fe435673db 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -288,13 +288,13 @@ void AtomBrowserClient::WebNotificationAllowed( content::WebContents* web_contents = content::WebContents::FromRenderViewHost( content::RenderViewHost::FromID(render_process_id, kDefaultRoutingID)); if (!web_contents) { - callback.Run(true); + callback.Run(false); return; } auto permission_helper = WebContentsPermissionHelper::FromWebContents(web_contents); if (!permission_helper) { - callback.Run(true); + callback.Run(false); return; } permission_helper->RequestWebNotificationPermission(callback); diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index ac59f8c3133..39eee1b8aff 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -13,6 +13,7 @@ #include "atom/browser/net/atom_url_request_job_factory.h" #include "atom/browser/net/asar/asar_protocol_handler.h" #include "atom/browser/net/http_protocol_handler.h" +#include "atom/browser/atom_permission_manager.h" #include "atom/browser/web_view_manager.h" #include "atom/common/atom_version.h" #include "atom/common/chrome_version.h" @@ -67,6 +68,7 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition, cert_verifier_(nullptr), job_factory_(new AtomURLRequestJobFactory), network_delegate_(new AtomNetworkDelegate), + permission_manager_(new AtomPermissionManager), allow_ntlm_everywhere_(false) { } @@ -169,6 +171,10 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() { return guest_manager_.get(); } +content::PermissionManager* AtomBrowserContext::GetPermissionManager() { + return permission_manager_.get(); +} + scoped_ptr AtomBrowserContext::CreateCertVerifier() { DCHECK(!cert_verifier_); cert_verifier_ = new AtomCertVerifier; diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index 9c94a60c305..44cd1f5b79e 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -14,6 +14,7 @@ namespace atom { class AtomDownloadManagerDelegate; class AtomCertVerifier; class AtomNetworkDelegate; +class AtomPermissionManager; class AtomURLRequestJobFactory; class WebViewManager; @@ -37,6 +38,7 @@ class AtomBrowserContext : public brightray::BrowserContext { // content::BrowserContext: content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; content::BrowserPluginGuestManager* GetGuestManager() override; + content::PermissionManager* GetPermissionManager() override; // brightray::BrowserContext: void RegisterPrefs(PrefRegistrySimple* pref_registry) override; @@ -49,9 +51,14 @@ class AtomBrowserContext : public brightray::BrowserContext { AtomNetworkDelegate* network_delegate() const { return network_delegate_; } + AtomPermissionManager* permission_manager() const { + return permission_manager_.get(); + } + private: scoped_ptr download_manager_delegate_; scoped_ptr guest_manager_; + scoped_ptr permission_manager_; // Managed by brightray::BrowserContext. AtomCertVerifier* cert_verifier_; diff --git a/atom/browser/atom_permission_manager.cc b/atom/browser/atom_permission_manager.cc new file mode 100644 index 00000000000..badef0a1d34 --- /dev/null +++ b/atom/browser/atom_permission_manager.cc @@ -0,0 +1,107 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/atom_permission_manager.h" + +#include "content/public/browser/permission_type.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" + +namespace atom { + +AtomPermissionManager::AtomPermissionManager() + : request_id_(0) { +} + +AtomPermissionManager::~AtomPermissionManager() { +} + +void AtomPermissionManager::SetPermissionRequestHandler( + int id, + const RequestHandler& handler) { + if (handler.is_null()) { + request_handler_map_.erase(id); + return; + } + request_handler_map_[id] = handler; +} + +void AtomPermissionManager::RequestPermission( + content::PermissionType permission, + content::RenderFrameHost* render_frame_host, + const GURL& origin, + const base::Callback& callback) { + bool user_gesture = false; + RequestPermission(permission, render_frame_host, origin, user_gesture, + base::Bind(&AtomPermissionManager::OnPermissionResponse, + base::Unretained(this), callback)); +} + +void AtomPermissionManager::OnPermissionResponse( + const base::Callback& callback, + content::PermissionStatus status) { + if (status == content::PERMISSION_STATUS_GRANTED) + callback.Run(true); + else + callback.Run(false); +} + +int AtomPermissionManager::RequestPermission( + content::PermissionType permission, + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + bool user_gesture, + const ResponseCallback& callback) { + auto request_handler = + request_handler_map_.find(render_frame_host->GetProcess()->GetID()); + if (request_handler != request_handler_map_.end()) { + pending_requests_[++request_id_] = callback; + request_handler->second.Run(permission, callback); + return request_id_; + } + + callback.Run(content::PERMISSION_STATUS_GRANTED); + return kNoPendingOperation; +} + +void AtomPermissionManager::CancelPermissionRequest(int request_id) { + auto request = pending_requests_.find(request_id); + if (request != pending_requests_.end()) { + request->second.Run(content::PERMISSION_STATUS_DENIED); + pending_requests_.erase(request); + } +} + +void AtomPermissionManager::ResetPermission( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) { +} + +content::PermissionStatus AtomPermissionManager::GetPermissionStatus( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) { + return content::PERMISSION_STATUS_DENIED; +} + +void AtomPermissionManager::RegisterPermissionUsage( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) { +} + +int AtomPermissionManager::SubscribePermissionStatusChange( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin, + const ResponseCallback& callback) { + return -1; +} + +void AtomPermissionManager::UnsubscribePermissionStatusChange( + int subscription_id) { +} + +} // namespace atom diff --git a/atom/browser/atom_permission_manager.h b/atom/browser/atom_permission_manager.h new file mode 100644 index 00000000000..697bcda6f37 --- /dev/null +++ b/atom/browser/atom_permission_manager.h @@ -0,0 +1,75 @@ +// Copyright (c) 2016 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_ATOM_PERMISSION_MANAGER_H_ +#define ATOM_BROWSER_ATOM_PERMISSION_MANAGER_H_ + +#include + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "content/public/browser/permission_manager.h" + +namespace atom { + +class AtomPermissionManager : public content::PermissionManager { + public: + AtomPermissionManager(); + ~AtomPermissionManager() override; + + using ResponseCallback = + base::Callback; + using RequestHandler = + base::Callback; + + void SetPermissionRequestHandler(int id, const RequestHandler& handler); + void RequestPermission( + content::PermissionType permission, + content::RenderFrameHost* render_frame_host, + const GURL& origin, + const base::Callback& callback); + void OnPermissionResponse( + const base::Callback& callback, + content::PermissionStatus status); + + protected: + // content::PermissionManager: + int RequestPermission( + content::PermissionType permission, + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + bool user_gesture, + const ResponseCallback& callback) override; + void CancelPermissionRequest(int request_id) override; + void ResetPermission(content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) override; + content::PermissionStatus GetPermissionStatus( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) override; + void RegisterPermissionUsage(content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) override; + int SubscribePermissionStatusChange( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin, + const base::Callback& callback) override; + void UnsubscribePermissionStatusChange(int subscription_id) override; + + private: + std::map request_handler_map_; + + std::map pending_requests_; + + int request_id_; + + DISALLOW_COPY_AND_ASSIGN(AtomPermissionManager); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_ATOM_PERMISSION_MANAGER_H_ diff --git a/atom/browser/lib/guest-view-manager.js b/atom/browser/lib/guest-view-manager.js index b50d0c9503f..f529260e797 100644 --- a/atom/browser/lib/guest-view-manager.js +++ b/atom/browser/lib/guest-view-manager.js @@ -36,15 +36,13 @@ var supportedWebViewEvents = [ 'media-started-playing', 'media-paused', 'found-in-page', - 'did-change-theme-color', - 'permission-request' + 'did-change-theme-color' ]; var nextInstanceId = 0; -var permissionRequests; var guestInstances = {}; -var guestPermissionRequestsMap = {}; var embedderElementsMap = {}; +var pendingRequestsMap = {}; var reverseEmbedderElementsMap = {}; // Moves the last element of array to the first one. @@ -137,20 +135,19 @@ var createGuest = function(embedder, params) { if (params.allowtransparency != null) { this.setAllowTransparency(params.allowtransparency); } - return guest.allowPopups = params.allowpopups; + guest.allowPopups = params.allowpopups; + this.setPermissionRequestHandler((permission, callback) => { + if (!pendingRequestsMap[this.viewInstanceId]) + pendingRequestsMap[this.viewInstanceId] = {}; + pendingRequestsMap[this.viewInstanceId][permission] = callback; + embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + this.viewInstanceId, "permission-request", permission]); + }); }); // Dispatch events to embedder. fn = function(event) { return guest.on(event, function() { var args = 2 <= arguments.length ? slice.call(arguments, 1) : []; - if (event === 'permission-request') { - if (!guestPermissionRequestsMap[guest.viewInstanceId]) - guestPermissionRequestsMap[guest.viewInstanceId] = {}; - var permission = args[0]; - guestPermissionRequestsMap[guest.viewInstanceId][permission] = args[1]; - args.pop(); - } return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + guest.viewInstanceId, event].concat(slice.call(args))); }); }; @@ -171,6 +168,7 @@ var createGuest = function(embedder, params) { var args = 2 <= arguments.length ? slice.call(arguments, 1) : []; return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-" + guest.viewInstanceId].concat(slice.call(args))); }); + return id; }; @@ -216,7 +214,7 @@ var destroyGuest = function(embedder, id) { webViewManager.removeGuest(embedder, id); guestInstances[id].guest.destroy(); delete guestInstances[id]; - delete guestPermissionRequestsMap[id]; + delete pendingRequestsMap[id]; key = reverseEmbedderElementsMap[id]; if (key != null) { delete reverseEmbedderElementsMap[id]; @@ -236,13 +234,6 @@ ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', function(event, id) { return destroyGuest(event.sender, id); }); -ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE', function(event, viewInstanceId, permission, allowed) { - permissionRequests = guestPermissionRequestsMap[viewInstanceId]; - if (permissionRequests && permissionRequests[permission] !== null) { - permissionRequests[permission].apply(null, [allowed]); - } -}); - ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', function(event, id, params) { var ref1; return (ref1 = guestInstances[id]) != null ? ref1.guest.setSize(params) : void 0; @@ -253,6 +244,13 @@ ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', function(even return (ref1 = guestInstances[id]) != null ? ref1.guest.setAllowTransparency(allowtransparency) : void 0; }); +ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE', function(event, id, permission, allowed) { + if (pendingRequestsMap[id] != null) { + const callback = pendingRequestsMap[id][permission]; + callback.apply(null, [allowed]); + } +}); + // Returns WebContents from its guest id. exports.getGuest = function(id) { var ref1; diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index 5c82aa41df6..04a6a5d9883 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -6,8 +6,9 @@ #include -#include "atom/browser/api/atom_api_web_contents.h" +#include "atom/browser/atom_permission_manager.h" #include "content/public/browser/media_capture_devices.h" +#include "content/public/browser/render_process_host.h" DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::WebContentsPermissionHelper); @@ -67,55 +68,32 @@ void MediaAccessAllowed( } // namespace WebContentsPermissionHelper::WebContentsPermissionHelper( - content::WebContents* web_contents, - api::WebContents* api_web_contents) - : api_web_contents_(api_web_contents) { - web_contents->SetUserData(UserDataKey(), this); + content::WebContents* web_contents) + : web_contents_(web_contents) { } WebContentsPermissionHelper::~WebContentsPermissionHelper() { } +void WebContentsPermissionHelper::RequestPermission( + content::PermissionType permission, + const base::Callback& callback) { + auto rfh = web_contents_->GetMainFrame(); + auto permission_manager = browser_context()->permission_manager(); + auto origin = web_contents_->GetLastCommittedURL(); + permission_manager->RequestPermission(permission, rfh, origin, callback); +} + void WebContentsPermissionHelper::RequestMediaAccessPermission( const content::MediaStreamRequest& request, - const content::MediaResponseCallback& callback) { - if (api_web_contents_->IsGuest()) { - const std::string& permission = "media"; - permission_map_[permission] = base::Bind(&MediaAccessAllowed, - request, - callback); - api_web_contents_->Emit( - "permission-request", - permission, - base::Bind(&WebContentsPermissionHelper::OnPermissionResponse, - base::Unretained(this), permission)); - return; - } - MediaAccessAllowed(request, callback, true); + const content::MediaResponseCallback& response_callback) { + auto callback = base::Bind(&MediaAccessAllowed, request, response_callback); + RequestPermission(content::PermissionType::AUDIO_CAPTURE, callback); } void WebContentsPermissionHelper::RequestWebNotificationPermission( const base::Callback& callback) { - if (api_web_contents_->IsGuest()) { - const std::string& permission = "webNotification"; - permission_map_[permission] = callback; - api_web_contents_->Emit( - "permission-request", - permission, - base::Bind(&WebContentsPermissionHelper::OnPermissionResponse, - base::Unretained(this), permission)); - return; - } - callback.Run(true); -} - -void WebContentsPermissionHelper::OnPermissionResponse( - const std::string& permission, bool allowed) { - auto it = permission_map_.find(permission); - if (it != permission_map_.end()) { - it->second.Run(allowed); - permission_map_.erase(permission); - } + RequestPermission(content::PermissionType::NOTIFICATIONS, callback); } } // namespace atom diff --git a/atom/browser/web_contents_permission_helper.h b/atom/browser/web_contents_permission_helper.h index 4beac035c02..2c845a60f76 100644 --- a/atom/browser/web_contents_permission_helper.h +++ b/atom/browser/web_contents_permission_helper.h @@ -5,25 +5,18 @@ #ifndef ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_ #define ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_ -#include -#include - +#include "atom/browser/atom_browser_context.h" #include "base/callback.h" +#include "content/public/browser/permission_type.h" #include "content/public/browser/web_contents_user_data.h" #include "content/public/common/media_stream_request.h" namespace atom { -namespace api { -class WebContents; -} - // Applies the permission requested for WebContents. class WebContentsPermissionHelper : public content::WebContentsUserData { public: - WebContentsPermissionHelper(content::WebContents* web_contents, - api::WebContents* api_web_contents); ~WebContentsPermissionHelper() override; void RequestMediaAccessPermission( @@ -32,14 +25,19 @@ class WebContentsPermissionHelper void RequestWebNotificationPermission( const base::Callback& callback); - void OnPermissionResponse(const std::string& permission, bool allowed); + AtomBrowserContext* browser_context() const { + return static_cast(web_contents_->GetBrowserContext()); + } private: + explicit WebContentsPermissionHelper(content::WebContents* web_contents); friend class content::WebContentsUserData; - std::map> permission_map_; + void RequestPermission( + content::PermissionType permission, + const base::Callback& callback); - api::WebContents* api_web_contents_; // Weak reference + content::WebContents* web_contents_; DISALLOW_COPY_AND_ASSIGN(WebContentsPermissionHelper); }; diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index d79094f79d4..d85188dad1f 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -98,6 +98,50 @@ v8::Local Converter::ToV8( return mate::ConvertToV8(isolate, dict); } +// static +bool Converter::FromV8( + v8::Isolate* isolate, + v8::Local val, + content::PermissionStatus* out) { + std::string status; + if (!ConvertFromV8(isolate, val, &status)) + return false; + + if (status == "granted") + *out = content::PERMISSION_STATUS_GRANTED; + else if (status == "denied" || status.empty()) + *out = content::PERMISSION_STATUS_DENIED; + else + return false; + + return true; +} + +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, const content::PermissionType& val) { + switch (val) { + case content::PermissionType::MIDI_SYSEX: + return StringToV8(isolate, "midiSysex"); + case content::PermissionType::PUSH_MESSAGING: + return StringToV8(isolate, "pushMessaging"); + case content::PermissionType::NOTIFICATIONS: + return StringToV8(isolate, "notifications"); + case content::PermissionType::GEOLOCATION: + return StringToV8(isolate, "geolocation"); + case content::PermissionType::AUDIO_CAPTURE: + case content::PermissionType::VIDEO_CAPTURE: + return StringToV8(isolate, "media"); + case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER: + return StringToV8(isolate, "mediaKeySystem"); + case content::PermissionType::MIDI: + return StringToV8(isolate, "midi"); + case content::PermissionType::DURABLE_STORAGE: + default: + return StringToV8(isolate, "unknown"); + } +} + // static bool Converter::FromV8( v8::Isolate* isolate, diff --git a/atom/common/native_mate_converters/content_converter.h b/atom/common/native_mate_converters/content_converter.h index a5708e022b5..6c9130b1887 100644 --- a/atom/common/native_mate_converters/content_converter.h +++ b/atom/common/native_mate_converters/content_converter.h @@ -7,7 +7,9 @@ #include +#include "content/public/browser/permission_type.h" #include "content/public/common/menu_item.h" +#include "content/public/common/permission_status.mojom.h" #include "content/public/common/stop_find_action.h" #include "native_mate/converter.h" @@ -33,6 +35,18 @@ struct Converter { const ContextMenuParamsWithWebContents& val); }; +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + content::PermissionStatus* out); +}; + +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + const content::PermissionType& val); +}; + template<> struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, diff --git a/atom/renderer/lib/web-view/guest-view-internal.js b/atom/renderer/lib/web-view/guest-view-internal.js index e6a1519b0f4..acade1f41c0 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.js +++ b/atom/renderer/lib/web-view/guest-view-internal.js @@ -67,10 +67,10 @@ module.exports = { var args = 3 <= arguments.length ? slice.call(arguments, 2) : []; if (eventName === 'permission-request') { var allow = function allow() { - ipcRenderer.send("ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE", viewInstanceId, args[0], true); + ipcRenderer.send("ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE", viewInstanceId, args[0], "granted"); }; var deny = function deny() { - ipcRenderer.send("ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE", viewInstanceId, args[0], false); + ipcRenderer.send("ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE", viewInstanceId, args[0], "denied"); }; args = args.concat([allow, deny]); } diff --git a/filenames.gypi b/filenames.gypi index 3c9cd4b6919..beb4fcac548 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -144,6 +144,8 @@ 'atom/browser/atom_browser_main_parts_posix.cc', 'atom/browser/atom_javascript_dialog_manager.cc', 'atom/browser/atom_javascript_dialog_manager.h', + 'atom/browser/atom_permission_manager.cc', + 'atom/browser/atom_permission_manager.h', 'atom/browser/atom_quota_permission_context.cc', 'atom/browser/atom_quota_permission_context.h', 'atom/browser/atom_resource_dispatcher_host_delegate.cc', From 0aa0efa43957e7324f2e8b001e6256c72a35f77d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Jan 2016 20:48:07 +0800 Subject: [PATCH 099/688] Do not print warning for FILE_ERROR_NOT_FOUND Close #4282. --- atom/common/asar/archive.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index 37ff0f45d60..35451410a8d 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -140,7 +140,10 @@ Archive::~Archive() { bool Archive::Init() { if (!file_.IsValid()) { - LOG(ERROR) << base::File::ErrorToString(file_.error_details()); + if (file_.error_details() != base::File::FILE_ERROR_NOT_FOUND) { + LOG(WARNING) << "Opening " << path_.value() + << ": " << base::File::ErrorToString(file_.error_details()); + } return false; } From f7556de9fb4e6a6ccc96e07e120749ca32902afd Mon Sep 17 00:00:00 2001 From: Robo Date: Sat, 30 Jan 2016 19:01:10 +0530 Subject: [PATCH 100/688] add spec for new permissions --- atom/browser/api/atom_api_web_contents.cc | 2 +- atom/browser/atom_browser_context.cc | 2 +- atom/browser/atom_permission_manager.cc | 13 +++++-- atom/browser/atom_permission_manager.h | 2 ++ atom/browser/lib/guest-view-manager.js | 4 ++- atom/browser/web_contents_permission_helper.h | 1 - atom/common/api/event_emitter_caller.h | 1 - docs/api/web-view-tag.md | 2 +- .../pages/permissions/geolocation.html | 5 +++ .../media.html} | 0 spec/fixtures/pages/permissions/midi.html | 5 +++ spec/webview-spec.js | 34 ++++++++++++++++++- 12 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 spec/fixtures/pages/permissions/geolocation.html rename spec/fixtures/pages/{permission-request.html => permissions/media.html} (100%) create mode 100644 spec/fixtures/pages/permissions/midi.html diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 01c069cf87d..c6ab110b832 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1177,7 +1177,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("_printToPDF", &WebContents::PrintToPDF) .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) - .SetMethod("setPermissionRequestHandler", + .SetMethod("_setPermissionRequestHandler", &WebContents::SetPermissionRequestHandler) .SetProperty("session", &WebContents::Session) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents) diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 39eee1b8aff..35358ac08a4 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -65,10 +65,10 @@ std::string RemoveWhitespace(const std::string& str) { AtomBrowserContext::AtomBrowserContext(const std::string& partition, bool in_memory) : brightray::BrowserContext(partition, in_memory), + permission_manager_(new AtomPermissionManager), cert_verifier_(nullptr), job_factory_(new AtomURLRequestJobFactory), network_delegate_(new AtomNetworkDelegate), - permission_manager_(new AtomPermissionManager), allow_ntlm_everywhere_(false) { } diff --git a/atom/browser/atom_permission_manager.cc b/atom/browser/atom_permission_manager.cc index badef0a1d34..ccd456e7c20 100644 --- a/atom/browser/atom_permission_manager.cc +++ b/atom/browser/atom_permission_manager.cc @@ -4,6 +4,7 @@ #include "atom/browser/atom_permission_manager.h" +#include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -53,8 +54,14 @@ int AtomPermissionManager::RequestPermission( const GURL& requesting_origin, bool user_gesture, const ResponseCallback& callback) { - auto request_handler = - request_handler_map_.find(render_frame_host->GetProcess()->GetID()); + int process_id = render_frame_host->GetProcess()->GetID(); + auto request_handler = request_handler_map_.find(process_id); + + if (permission == content::PermissionType::MIDI_SYSEX) { + content::ChildProcessSecurityPolicy::GetInstance()-> + GrantSendMidiSysExMessage(process_id); + } + if (request_handler != request_handler_map_.end()) { pending_requests_[++request_id_] = callback; request_handler->second.Run(permission, callback); @@ -83,7 +90,7 @@ content::PermissionStatus AtomPermissionManager::GetPermissionStatus( content::PermissionType permission, const GURL& requesting_origin, const GURL& embedding_origin) { - return content::PERMISSION_STATUS_DENIED; + return content::PERMISSION_STATUS_GRANTED; } void AtomPermissionManager::RegisterPermissionUsage( diff --git a/atom/browser/atom_permission_manager.h b/atom/browser/atom_permission_manager.h index 697bcda6f37..fb449037f64 100644 --- a/atom/browser/atom_permission_manager.h +++ b/atom/browser/atom_permission_manager.h @@ -24,7 +24,9 @@ class AtomPermissionManager : public content::PermissionManager { base::Callback; + // Handler to dispatch permission requests in JS. void SetPermissionRequestHandler(int id, const RequestHandler& handler); + void RequestPermission( content::PermissionType permission, content::RenderFrameHost* render_frame_host, diff --git a/atom/browser/lib/guest-view-manager.js b/atom/browser/lib/guest-view-manager.js index f529260e797..d4332070fa6 100644 --- a/atom/browser/lib/guest-view-manager.js +++ b/atom/browser/lib/guest-view-manager.js @@ -136,7 +136,9 @@ var createGuest = function(embedder, params) { this.setAllowTransparency(params.allowtransparency); } guest.allowPopups = params.allowpopups; - this.setPermissionRequestHandler((permission, callback) => { + + // Dispatches permission request event. + this._setPermissionRequestHandler((permission, callback) => { if (!pendingRequestsMap[this.viewInstanceId]) pendingRequestsMap[this.viewInstanceId] = {}; pendingRequestsMap[this.viewInstanceId][permission] = callback; diff --git a/atom/browser/web_contents_permission_helper.h b/atom/browser/web_contents_permission_helper.h index 2c845a60f76..749e90184c2 100644 --- a/atom/browser/web_contents_permission_helper.h +++ b/atom/browser/web_contents_permission_helper.h @@ -6,7 +6,6 @@ #define ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_ #include "atom/browser/atom_browser_context.h" -#include "base/callback.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/web_contents_user_data.h" #include "content/public/common/media_stream_request.h" diff --git a/atom/common/api/event_emitter_caller.h b/atom/common/api/event_emitter_caller.h index 26a4cbc45b9..a2567da9d10 100644 --- a/atom/common/api/event_emitter_caller.h +++ b/atom/common/api/event_emitter_caller.h @@ -7,7 +7,6 @@ #include -#include "atom/common/native_mate_converters/callback.h" #include "native_mate/converter.h" namespace mate { diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 67a3d12171c..229ee12f1a5 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -740,7 +740,7 @@ Emitted when DevTools is focused / opened. Returns: -* `permission` String - The type of permission being requested. Enum of 'media', 'webNotification'. +* `permission` String - The type of permission being requested. Enum of 'media', 'notifications', 'midiSysex', 'geolocation'. * `allow` Function - Allows the permission. * `deny` Function - Deny the permission. This is the default behaviour if `allow` is not called. diff --git a/spec/fixtures/pages/permissions/geolocation.html b/spec/fixtures/pages/permissions/geolocation.html new file mode 100644 index 00000000000..1d1b4fc4245 --- /dev/null +++ b/spec/fixtures/pages/permissions/geolocation.html @@ -0,0 +1,5 @@ + diff --git a/spec/fixtures/pages/permission-request.html b/spec/fixtures/pages/permissions/media.html similarity index 100% rename from spec/fixtures/pages/permission-request.html rename to spec/fixtures/pages/permissions/media.html diff --git a/spec/fixtures/pages/permissions/midi.html b/spec/fixtures/pages/permissions/midi.html new file mode 100644 index 00000000000..c6bd8c137e3 --- /dev/null +++ b/spec/fixtures/pages/permissions/midi.html @@ -0,0 +1,5 @@ + diff --git a/spec/webview-spec.js b/spec/webview-spec.js index e40afcaefeb..190a3266090 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -645,7 +645,39 @@ describe(' tag', function() { e.deny(); } }); - webview.src = "file://" + fixtures + "/pages/permission-request.html"; + webview.src = "file://" + fixtures + "/pages/permissions/media.html"; + webview.setAttribute('nodeintegration', 'on'); + document.body.appendChild(webview); + }); + + it ('emits when using navigator.geolocation api', function(done) { + webview.addEventListener('ipc-message', function(e) { + assert(e.channel, 'message'); + assert(e.args, ['ERROR(1): User denied Geolocation']); + done(); + }); + webview.addEventListener('permission-request', function(e) { + if (e.permission === 'geolocation') { + e.deny(); + } + }); + webview.src = "file://" + fixtures + "/pages/permissions/geolocation.html"; + webview.setAttribute('nodeintegration', 'on'); + document.body.appendChild(webview); + }); + + it ('emits when using navigator.requestMIDIAccess api', function(done) { + webview.addEventListener('ipc-message', function(e) { + assert(e.channel, 'message'); + assert(e.args, ['SecurityError']); + done(); + }); + webview.addEventListener('permission-request', function(e) { + if (e.permission === 'midiSysex') { + e.deny(); + } + }); + webview.src = "file://" + fixtures + "/pages/permissions/midi.html"; webview.setAttribute('nodeintegration', 'on'); document.body.appendChild(webview); }); From f9efdc4435587db840d2e0424a29c041cea5e77c Mon Sep 17 00:00:00 2001 From: Simon Madine Date: Sat, 30 Jan 2016 21:40:32 +0100 Subject: [PATCH 101/688] :apple: Add Show to API for OS X --- atom/browser/api/atom_api_app.cc | 1 + atom/browser/browser.h | 3 +++ atom/browser/browser_mac.mm | 4 ++++ docs/api/app.md | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 0562cf893af..e54d7fee176 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -369,6 +369,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( base::Bind(&Browser::SetAppUserModelID, browser)) #if defined(OS_MACOSX) .SetMethod("hide", base::Bind(&Browser::Hide, browser)) + .SetMethod("show", base::Bind(&Browser::Show, browser)) #endif #if defined(OS_WIN) .SetMethod("setUserTasks", diff --git a/atom/browser/browser.h b/atom/browser/browser.h index dc811fc4a6f..2c44eaa107b 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -80,6 +80,9 @@ class Browser : public WindowListObserver { // Hide the application. void Hide(); + // Show the application. + void Show(); + // Bounce the dock icon. enum BounceType { BOUNCE_CRITICAL = 0, diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index db898017b3d..bf9c9ef69e8 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -22,6 +22,10 @@ void Browser::Hide() { [[AtomApplication sharedApplication] hide:nil]; } +void Browser::Show() { + [[AtomApplication sharedApplication] unhide:nil]; +} + void Browser::AddRecentDocument(const base::FilePath& path) { NSString* path_string = base::mac::FilePathToNSString(path); if (!path_string) diff --git a/docs/api/app.md b/docs/api/app.md index 808f5fabadc..4b5c6ee2a6a 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -248,6 +248,10 @@ returning `false` in the `beforeunload` event handler. Hides all application windows without minimising them. +### `app.show()` _OS X_ + +Shows application windows after they were hidden. Does not automatically focus them. + ### `app.exit(exitCode)` * `exitCode` Integer From 61e0219e9124e409916ccac6a6118407edac4854 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Sun, 31 Jan 2016 02:27:14 +0100 Subject: [PATCH 102/688] Added documentation, restructured the files to fit better with electron's style and fixed a typo in keyboard_util's name. --- atom/browser/api/atom_api_web_contents.cc | 6 +- atom/browser/api/atom_api_web_contents.h | 1 + atom/browser/ui/accelerator_util.cc | 2 +- .../{keyboad_util.cc => keyboard_util.cc} | 2 +- .../{keyboad_util.h => keyboard_util.h} | 6 +- atom/common/mouse_util.cc | 67 ++++++++ atom/common/mouse_util.h | 36 +++++ .../native_mate_converters/blink_converter.cc | 2 +- docs/api/web-contents.md | 18 +++ filenames.gypi | 8 +- mw/cursor/cursor_event_filter.cc | 150 ------------------ mw/cursor/cursor_event_filter.h | 30 ---- 12 files changed, 134 insertions(+), 194 deletions(-) rename atom/common/{keyboad_util.cc => keyboard_util.cc} (98%) rename atom/common/{keyboad_util.h => keyboard_util.h} (83%) create mode 100644 atom/common/mouse_util.cc create mode 100644 atom/common/mouse_util.h delete mode 100644 mw/cursor/cursor_event_filter.cc delete mode 100644 mw/cursor/cursor_event_filter.h diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 0b557f2dfc4..091c44ed517 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -27,6 +27,7 @@ #include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/value_converter.h" +#include "atom/common/mouse_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "brightray/browser/inspectable_web_contents.h" @@ -56,12 +57,9 @@ #include "net/url_request/url_request_context.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/base/l10n/l10n_util.h" -#include "mw/cursor/cursor_event_filter.h" #include "atom/common/node_includes.h" -#include - namespace { struct PrintSettings { @@ -1045,7 +1043,7 @@ void WebContents::EndFrameSubscription() { } void WebContents::OnCursorChange(const content::WebCursor& cursor) { - Emit("cursor-changed", CursorChangeEvent::toString(cursor)); + Emit("cursor-changed", CursorTypeToString(cursor)); } void WebContents::SetSize(const SetSizeParams& params) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 21e201c7af1..e00798b6c13 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -256,6 +256,7 @@ class WebContents : public mate::TrackableObject, return ++request_id_; } + // Called when we receive a CursorChange message from chromium. void OnCursorChange(const content::WebCursor& cursor); // Called when received a message from renderer. diff --git a/atom/browser/ui/accelerator_util.cc b/atom/browser/ui/accelerator_util.cc index a0b90e0c7e5..39138d8e49b 100644 --- a/atom/browser/ui/accelerator_util.cc +++ b/atom/browser/ui/accelerator_util.cc @@ -9,7 +9,7 @@ #include #include -#include "atom/common/keyboad_util.h" +#include "atom/common/keyboard_util.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" diff --git a/atom/common/keyboad_util.cc b/atom/common/keyboard_util.cc similarity index 98% rename from atom/common/keyboad_util.cc rename to atom/common/keyboard_util.cc index 7d7c5d99fab..e5dedd84ded 100644 --- a/atom/common/keyboad_util.cc +++ b/atom/common/keyboard_util.cc @@ -3,7 +3,7 @@ // found in the LICENSE file. #include -#include "atom/common/keyboad_util.h" +#include "atom/common/keyboard_util.h" namespace atom { diff --git a/atom/common/keyboad_util.h b/atom/common/keyboard_util.h similarity index 83% rename from atom/common/keyboad_util.h rename to atom/common/keyboard_util.h index 4a85c190635..d3168d4447e 100644 --- a/atom/common/keyboad_util.h +++ b/atom/common/keyboard_util.h @@ -2,8 +2,8 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#ifndef ATOM_COMMON_KEYBOAD_UTIL_H_ -#define ATOM_COMMON_KEYBOAD_UTIL_H_ +#ifndef ATOM_COMMON_KEYBOARD_UTIL_H_ +#define ATOM_COMMON_KEYBOARD_UTIL_H_ #include #include "ui/events/keycodes/keyboard_codes.h" @@ -20,4 +20,4 @@ ui::KeyboardCode KeyboardCodeFromKeyIdentifier(const std::string& chr); } // namespace atom -#endif // ATOM_COMMON_KEYBOAD_UTIL_H_ +#endif // ATOM_COMMON_KEYBOARD_UTIL_H_ diff --git a/atom/common/mouse_util.cc b/atom/common/mouse_util.cc new file mode 100644 index 00000000000..8178668ca15 --- /dev/null +++ b/atom/common/mouse_util.cc @@ -0,0 +1,67 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include +#include "atom/common/mouse_util.h" + +using Cursor = blink::WebCursorInfo::Type; + +namespace atom { + +std::string CursorTypeToString(const content::WebCursor& cursor) { + content::WebCursor::CursorInfo* info = new content::WebCursor::CursorInfo(); + cursor.GetCursorInfo(info); + + switch (info->type) { + case Cursor::TypePointer: return "pointer"; + case Cursor::TypeCross: return "cross"; + case Cursor::TypeHand: return "hand"; + case Cursor::TypeIBeam: return "i-beam"; + case Cursor::TypeWait: return "wait"; + case Cursor::TypeHelp: return "help"; + case Cursor::TypeEastResize: return "east-resize"; + case Cursor::TypeNorthResize: return "north-resize"; + case Cursor::TypeNorthEastResize: return "north-east-resize"; + case Cursor::TypeNorthWestResize: return "north-west-resize"; + case Cursor::TypeSouthResize: return "south-resize"; + case Cursor::TypeSouthEastResize: return "south-east-resize"; + case Cursor::TypeSouthWestResize: return "south-west-resize"; + case Cursor::TypeWestResize: return "west-resize"; + case Cursor::TypeNorthSouthResize: return "north-south-resize"; + case Cursor::TypeEastWestResize: return "east-west-resize"; + case Cursor::TypeNorthEastSouthWestResize: + return "north-east-south-west-resize"; + case Cursor::TypeNorthWestSouthEastResize: + return "north-west-south-east-resize"; + case Cursor::TypeColumnResize: return "column-resize"; + case Cursor::TypeRowResize: return "row-resize"; + case Cursor::TypeMiddlePanning: return "middle-panning"; + case Cursor::TypeEastPanning: return "east-panning"; + case Cursor::TypeNorthPanning: return "north-panning"; + case Cursor::TypeNorthEastPanning: return "north-east-panning"; + case Cursor::TypeNorthWestPanning: return "north-west-panning"; + case Cursor::TypeSouthPanning: return "south-panning"; + case Cursor::TypeSouthEastPanning: return "south-east-panning"; + case Cursor::TypeSouthWestPanning: return "south-west-panning"; + case Cursor::TypeWestPanning: return "west-panning"; + case Cursor::TypeMove: return "move"; + case Cursor::TypeVerticalText: return "vertical-text"; + case Cursor::TypeCell: return "cell"; + case Cursor::TypeContextMenu: return "context-menu"; + case Cursor::TypeAlias: return "alias"; + case Cursor::TypeProgress: return "progress"; + case Cursor::TypeNoDrop: return "nodrop"; + case Cursor::TypeCopy: return "copy"; + case Cursor::TypeNone: return "none"; + case Cursor::TypeNotAllowed: return "not-allowed"; + case Cursor::TypeZoomIn: return "zoom-in"; + case Cursor::TypeZoomOut: return "zoom-out"; + case Cursor::TypeGrab: return "grab"; + case Cursor::TypeGrabbing: return "grabbing"; + case Cursor::TypeCustom: return "custom"; + default: return "pointer"; + } +} + +} // namespace atom diff --git a/atom/common/mouse_util.h b/atom/common/mouse_util.h new file mode 100644 index 00000000000..9ea130821eb --- /dev/null +++ b/atom/common/mouse_util.h @@ -0,0 +1,36 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_COMMON_MOUSE_UTIL_H_ +#define ATOM_COMMON_MOUSE_UTIL_H_ + +#include +#include "content/common/cursors/webcursor.h" +#include "ipc/ipc_message_macros.h" + +// IPC macros similar to the already existing ones in the chromium source. +// We need these to listen to the cursor change IPC message while still +// letting chromium handle the actual cursor change by setting handled = false. +#define IPC_MESSAGE_HANDLER_CODE(msg_class, member_func, code) \ + IPC_MESSAGE_FORWARD_CODE(msg_class, this, \ + _IpcMessageHandlerClass::member_func, code) + +#define IPC_MESSAGE_FORWARD_CODE(msg_class, obj, member_func, code) \ + case msg_class::ID: { \ + TRACK_RUN_IN_THIS_SCOPED_REGION(member_func); \ + if (!msg_class::Dispatch(&ipc_message__, obj, this, param__, \ + &member_func)) \ + ipc_message__.set_dispatch_error(); \ + code; \ + } \ + break; + +namespace atom { + +// Returns the cursor's type as a string. +std::string CursorTypeToString(const content::WebCursor& cursor); + +} // namespace atom + +#endif // ATOM_COMMON_MOUSE_UTIL_H_ diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index 095490ab883..fdb894b3346 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -7,7 +7,7 @@ #include #include -#include "atom/common/keyboad_util.h" +#include "atom/common/keyboard_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "content/public/browser/native_web_keyboard_event.h" diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 939a0962997..a3fcc37da3c 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -281,6 +281,24 @@ Emitted when a page's theme color changes. This is usually due to encountering a ``` +### Event: 'cursor-changed' + +Returns: + +* `event` Event +* `type` String + +Emitted when the cursor's type changes. The `type` parameter can be `pointer`, +`cross`, `hand`, `i-beam`, `wait`, `help`, `east-resize`, `north-resize`, +`north-east-resize`, `north-west-resize`, `south-resize`, `south-east-resize`, +`south-west-resize`, `west-resize`, `north-south-resize`, `east-west-resize`, +`north-east-south-west-resize`, `north-west-south-east-resize`, `column-resize`, +`row-resize`, `middle-panning`, `east-panning`, `north-panning`, +`north-east-panning`, `north-west-panning`, `south-panning`, +`south-east-panning`, `south-west-panning`, `west-panning`, `move`, +`vertical-text`, `cell`, `context-menu`, `alias`, `progress`, `nodrop`, `copy`, +`none`, `not-allowed`, `zoom-in`, `zoom-out`, `grab`, `grabbing`, `custom`. + ## Instance Methods The `webContents` object has the following instance methods: diff --git a/filenames.gypi b/filenames.gypi index b94d2b752cf..748b3b9252c 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -317,8 +317,10 @@ 'atom/common/google_api_key.h', 'atom/common/id_weak_map.cc', 'atom/common/id_weak_map.h', - 'atom/common/keyboad_util.cc', - 'atom/common/keyboad_util.h', + 'atom/common/keyboard_util.cc', + 'atom/common/keyboard_util.h', + 'atom/common/mouse_util.cc', + 'atom/common/mouse_util.h', 'atom/common/linux/application_info.cc', 'atom/common/native_mate_converters/accelerator_converter.cc', 'atom/common/native_mate_converters/accelerator_converter.h', @@ -371,8 +373,6 @@ 'atom/renderer/node_array_buffer_bridge.h', 'atom/utility/atom_content_utility_client.cc', 'atom/utility/atom_content_utility_client.h', - 'mw/cursor/cursor_event_filter.cc', - 'mw/cursor/cursor_event_filter.h', 'chromium_src/chrome/browser/browser_process.cc', 'chromium_src/chrome/browser/browser_process.h', 'chromium_src/chrome/browser/chrome_process_finder_win.cc', diff --git a/mw/cursor/cursor_event_filter.cc b/mw/cursor/cursor_event_filter.cc deleted file mode 100644 index 00c6d58bdfe..00000000000 --- a/mw/cursor/cursor_event_filter.cc +++ /dev/null @@ -1,150 +0,0 @@ -#include "mw/cursor/cursor_event_filter.h" -#include "content/common/view_messages.h" - -namespace atom { - -std::string CursorChangeEvent::toString( - const content::WebCursor& cursor) { - content::WebCursor::CursorInfo* info = new content::WebCursor::CursorInfo(); - cursor.GetCursorInfo(info); - - switch(info->type){ - case blink::WebCursorInfo::Type::TypePointer: - return "Pointer"; - break; - case blink::WebCursorInfo::Type::TypeCross: - return "Cross"; - break; - case blink::WebCursorInfo::Type::TypeHand: - return "Hand"; - break; - case blink::WebCursorInfo::Type::TypeIBeam: - return "IBeam"; - break; - case blink::WebCursorInfo::Type::TypeWait: - return "Wait"; - break; - case blink::WebCursorInfo::Type::TypeHelp: - return "Help"; - break; - case blink::WebCursorInfo::Type::TypeEastResize: - return "EastResize"; - break; - case blink::WebCursorInfo::Type::TypeNorthResize: - return "NorthResize"; - break; - case blink::WebCursorInfo::Type::TypeNorthEastResize: - return "NorthEastResize"; - break; - case blink::WebCursorInfo::Type::TypeNorthWestResize: - return "NorthWestResize"; - break; - case blink::WebCursorInfo::Type::TypeSouthResize: - return "SouthResize"; - break; - case blink::WebCursorInfo::Type::TypeSouthEastResize: - return "SouthEastResize"; - break; - case blink::WebCursorInfo::Type::TypeSouthWestResize: - return "SouthWestResize"; - break; - case blink::WebCursorInfo::Type::TypeWestResize: - return "WestResize"; - break; - case blink::WebCursorInfo::Type::TypeNorthSouthResize: - return "NorthSouthResize"; - break; - case blink::WebCursorInfo::Type::TypeEastWestResize: - return "EastWestResize"; - break; - case blink::WebCursorInfo::Type::TypeNorthEastSouthWestResize: - return "NorthEastSouthWestResize"; - break; - case blink::WebCursorInfo::Type::TypeNorthWestSouthEastResize: - return "NorthWestSouthEastResize"; - break; - case blink::WebCursorInfo::Type::TypeColumnResize: - return "ColumnResize"; - break; - case blink::WebCursorInfo::Type::TypeRowResize: - return "RowResize"; - break; - case blink::WebCursorInfo::Type::TypeMiddlePanning: - return "MiddlePanning"; - break; - case blink::WebCursorInfo::Type::TypeEastPanning: - return "EastPanning"; - break; - case blink::WebCursorInfo::Type::TypeNorthPanning: - return "NorthPanning"; - break; - case blink::WebCursorInfo::Type::TypeNorthEastPanning: - return "NorthEastPanning"; - break; - case blink::WebCursorInfo::Type::TypeNorthWestPanning: - return "NorthWestPanning"; - break; - case blink::WebCursorInfo::Type::TypeSouthPanning: - return "SouthPanning"; - break; - case blink::WebCursorInfo::Type::TypeSouthEastPanning: - return "SouthEastPanning"; - break; - case blink::WebCursorInfo::Type::TypeSouthWestPanning: - return "SouthWestPanning"; - break; - case blink::WebCursorInfo::Type::TypeWestPanning: - return "WestPanning"; - break; - case blink::WebCursorInfo::Type::TypeMove: - return "Move"; - break; - case blink::WebCursorInfo::Type::TypeVerticalText: - return "VerticalText"; - break; - case blink::WebCursorInfo::Type::TypeCell: - return "Cell"; - break; - case blink::WebCursorInfo::Type::TypeContextMenu: - return "ContextMenu"; - break; - case blink::WebCursorInfo::Type::TypeAlias: - return "Alias"; - break; - case blink::WebCursorInfo::Type::TypeProgress: - return "Progress"; - break; - case blink::WebCursorInfo::Type::TypeNoDrop: - return "NoDrop"; - break; - case blink::WebCursorInfo::Type::TypeCopy: - return "Copy"; - break; - case blink::WebCursorInfo::Type::TypeNone: - return "None"; - break; - case blink::WebCursorInfo::Type::TypeNotAllowed: - return "NotAllowed"; - break; - case blink::WebCursorInfo::Type::TypeZoomIn: - return "ZoomIn"; - break; - case blink::WebCursorInfo::Type::TypeZoomOut: - return "ZoomOut"; - break; - case blink::WebCursorInfo::Type::TypeGrab: - return "Grab"; - break; - case blink::WebCursorInfo::Type::TypeGrabbing: - return "Grabbing"; - break; - case blink::WebCursorInfo::Type::TypeCustom: - return "Custom"; - break; - default: - return "Pointer"; - break; - } -} - -} diff --git a/mw/cursor/cursor_event_filter.h b/mw/cursor/cursor_event_filter.h deleted file mode 100644 index 31bc74498f4..00000000000 --- a/mw/cursor/cursor_event_filter.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef MW_CURSOR_EVENT_H_ -#define MW_CURSOR_EVENT_H_ - -#include "content/common/cursors/webcursor.h" -#include "ipc/ipc_message_macros.h" - -#define IPC_MESSAGE_HANDLER_CODE(msg_class, member_func, code) \ - IPC_MESSAGE_FORWARD_CODE(msg_class, this, \ - _IpcMessageHandlerClass::member_func, code) - -#define IPC_MESSAGE_FORWARD_CODE(msg_class, obj, member_func, code) \ - case msg_class::ID: { \ - TRACK_RUN_IN_THIS_SCOPED_REGION(member_func); \ - if (!msg_class::Dispatch(&ipc_message__, obj, this, param__, \ - &member_func)) \ - ipc_message__.set_dispatch_error(); \ - code; \ - } \ - break; - -namespace atom { - -class CursorChangeEvent { - public: - static std::string toString(const content::WebCursor& cursor); -}; - -} - -#endif // MW_CURSOR_EVENT_H_ From 07721c28b61cc191ef4dbfe4098f78bbb7dbbfe3 Mon Sep 17 00:00:00 2001 From: wgrafael Date: Sun, 31 Jan 2016 00:02:06 -0200 Subject: [PATCH 103/688] update the "janelas" to "windows" System Operation windows and not literal windows! --- docs-translations/pt-BR/tutorial/application-distribution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs-translations/pt-BR/tutorial/application-distribution.md b/docs-translations/pt-BR/tutorial/application-distribution.md index 41f2457c408..9079ba0c50b 100644 --- a/docs-translations/pt-BR/tutorial/application-distribution.md +++ b/docs-translations/pt-BR/tutorial/application-distribution.md @@ -58,7 +58,7 @@ Mais detalhes podem ser encontrados em [Empacotamento da aplicação](../../../d Depois de empacotar seu aplicativo Electron, você vai querer renomear a marca Electron antes de distribuí-lo aos usuários. -### Janelas +### Windows Você pode renomear `electron.exe` para o nome que desejar e editar o seu ícone e outras informações com ferramentas como [rcedit](https://github.com/atom/rcedit) ou @@ -115,4 +115,4 @@ uma tarefa para o Grunt foi criado e irá cuidar desta tarefa automaticamente pa [grunt-build-atom-shell](https://github.com/paulcbetts/grunt-build-atom-shell). Esta tarefa irá automaticamente editar o arquivo `.gyp`, compilar o código -e reconstruir os módulos nativos da aplicação para utilizar o novo nome. \ No newline at end of file +e reconstruir os módulos nativos da aplicação para utilizar o novo nome. From 0f539adab9cbe507dcee291e6dfc821bafae83e9 Mon Sep 17 00:00:00 2001 From: Takahito Yamatoya Date: Mon, 1 Feb 2016 00:20:36 +0900 Subject: [PATCH 104/688] :memo: Update as upstream [ci skip] --- docs-translations/jp/api/app.md | 6 ++ .../jp/api/environment-variables.md | 5 ++ docs-translations/jp/api/protocol.md | 41 +++++++++++--- docs-translations/jp/api/session.md | 11 ++++ docs-translations/jp/api/synopsis.md | 3 +- docs-translations/jp/faq/electron-faq.md | 33 +++++++++++ .../jp/tutorial/debugging-main-process.md | 4 +- .../desktop-environment-integration.md | 11 +--- .../mac-app-store-submission-guide.md | 55 ++++++++++++++++--- .../jp/tutorial/supported-platforms.md | 2 +- 10 files changed, 141 insertions(+), 30 deletions(-) diff --git a/docs-translations/jp/api/app.md b/docs-translations/jp/api/app.md index d0df22bb404..8d109937358 100644 --- a/docs-translations/jp/api/app.md +++ b/docs-translations/jp/api/app.md @@ -431,6 +431,12 @@ dock アイコンを表示します。 アプリケーションの[dock menu][dock-menu]を設定します。 +### `app.dock.setIcon(image)` _OS X_ + +* `image` [NativeImage](native-image.md) + +dock アイコンに紐づいた`image`を設定します。 + [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx diff --git a/docs-translations/jp/api/environment-variables.md b/docs-translations/jp/api/environment-variables.md index 39fd8f80e0f..f5277f14659 100644 --- a/docs-translations/jp/api/environment-variables.md +++ b/docs-translations/jp/api/environment-variables.md @@ -24,6 +24,11 @@ Windows コンソール上: Chromeのインターナルログをコンソールに出力します。 + +## `ELECTRON_LOG_ASAR_READS` + +ASARファイルからElectronが読み込んだとき、システム`tmpdir`へ読み込みオフセットとファイルのパスを記録します。ファイルの順序を最適化するために、得られたファイルはASARモジュールに提供されます。 + ## `ELECTRON_ENABLE_STACK_DUMPING` Electronがクラッシュしたとき、コンソールにスタックとレースを出力します。 diff --git a/docs-translations/jp/api/protocol.md b/docs-translations/jp/api/protocol.md index 841c64512a7..9f341b2f974 100644 --- a/docs-translations/jp/api/protocol.md +++ b/docs-translations/jp/api/protocol.md @@ -45,9 +45,22 @@ app.on('ready', function() { レスポンスとしてファイルを送信する`scheme`のプロトコルを登録します。`scheme`で`request`が生成された時、`handler`は`handler(request, callback)`で呼び出されます。`scheme` 登録が成功したり、`completion(error)`が失敗したときに、`completion` は`completion(null)`で呼び出されます。 +* `request` Object + * `url` String + * `referrer` String + * `method` String + * `uploadData` Array (オプション) +* `callback` Function + +`uploadData` は `data` オブジェクトの配列です: + +* `data` Object + * `bytes` Buffer - 送信するコンテンツ + * `file` String - アップロードするファイルパス + `request`をハンドルするために、`callback`はファイルパスまたは`path`プロパティを持つオブジェクトで呼び出すべきです。例えば、`callback(filePath)` または`callback({path: filePath})`です。 -何もなし、数字、`error`プロパティを持つオブジェクトで、`callback`が呼び出された時、 `request`は指定した`error`番号で失敗します。使用できる提供されているエラー番号は、[net error list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h)を参照してください。 +何もなし、数字、`error`プロパティを持つオブジェクトで、`callback`が呼び出された時、 `request`は指定した`error`番号で失敗します。使用できる提供されているエラー番号は、[net error list][net-error]を参照してください。 既定では、`scheme`は、`file:`のような一般的なURIの構文に続くプロトコルと違う解析がされ、`http:`のように扱われます。なので、恐らく標準的なスキーマーのように扱われるスキーマーを持つために、`protocol.registerStandardSchemes` を呼び出したくなります。 @@ -57,7 +70,9 @@ app.on('ready', function() { * `handler` Function * `completion` Function (optional) -レスポンスとして`Buffer`を送信する`scheme`プロトコルを登録します。`callback`は、`Buffer`オブジェクトまたは`data`と `mimeType`、`chart`プロパティを持つオブジェクトを呼び出す必要があります。 +レスポンスとして`Buffer`を送信する`scheme`プロトコルを登録します。 + + `callback`は、`Buffer`オブジェクトまたは、`data`と`mimeType`、 `charset`プロパティを持つオブジェクトのどちらかで呼ばれる必要があることを除いて、この使用方法は、`registerFileProtocol`と同じです。 例: @@ -76,7 +91,9 @@ protocol.registerBufferProtocol('atom', function(request, callback) { * `handler` Function * `completion` Function (optional) -レスポンスとして`String`を送信する`scheme`プロトコルを登録します。`callback`は、`String`または`data`と `mimeType`、`chart`プロパティを持つオブジェクトを呼び出す必要があります。 +レスポンスとして`String`を送信する`scheme`プロトコルを登録します。 + +`callback`は、`String`または`data`と `mimeType`、`chart`プロパティを持つオブジェクトを呼び出す必要があることを除いて、使用方法は`registerFileProtocol`と同じです。 ### `protocol.registerHttpProtocol(scheme, handler[, completion])` @@ -84,14 +101,22 @@ protocol.registerBufferProtocol('atom', function(request, callback) { * `handler` Function * `completion` Function (optional) -レスポンスとしてHTTPリクエストを送信する`scheme`プロトコルを登録します。`callback`は、`url`と`method`、`referrer`、`uploadData`、`session`プロパティを持つオブジェクトを呼び出す必要があります。 +レスポンスとしてHTTPリクエストを送信する`scheme`プロトコルを登録します。 + +`callback`は、`url`と`method`、`referrer`、`uploadData`、`session`プロパティを持つオブジェクトを呼び出す必要があることを除いて、使用方法は`registerFileProtocol`と同じです。 + +* `redirectRequest` Object + * `url` String + * `method` String + * `session` Object (オプション) + * `uploadData` Object (オプション) 既定では、HTTPリクエストは現在のセッションを再利用します。別のセッションでリクエストをしたい場合、`session` に `null`を設定する必要があります。 POSTリクエストは`uploadData`オブジェクトを提供する必要があります。 * `uploadData` object * `contentType` String - コンテンツのMIMEタイプ - * `data` String - 送信されるコンテンツ + * `data` String - 送信されるコンテンツ ### `protocol.unregisterProtocol(scheme[, completion])` @@ -139,12 +164,12 @@ POSTリクエストは`uploadData`オブジェクトを提供する必要があ `scheme`プロトコルをインターセプタ―し、レスポンスとして新しいHTTPリクエストを送信するプロトコルの新しいハンドラーとして`handler`を使います。 -Intercepts `scheme` protocol and uses `handler` as the protocol's new handler -which sends a new HTTP request as a response. - ### `protocol.uninterceptProtocol(scheme[, completion])` * `scheme` String * `completion` Function インターセプタ―したインストールされた`scheme`を削除し、オリジナルハンドラーをリストアします。 + + +[net-error]: https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h diff --git a/docs-translations/jp/api/session.md b/docs-translations/jp/api/session.md index 9385ac3e891..a5d47d404a6 100644 --- a/docs-translations/jp/api/session.md +++ b/docs-translations/jp/api/session.md @@ -197,6 +197,7 @@ proxyURL = ["://"][":"] ``` 具体例: + * `http=foopy:80;ftp=foopy2` - `http://`URLは`foopy:80`HTTPプロキシを使用し、`ftp://`URLは`foopy2:80` HTTPプロキシを使用します。 * `foopy:80` - 全てのURLで`foopy:80`を使用します。 * `foopy:80,bar,direct://` - 全てのURLで`foopy:80`HTTPプロキシを使用し、`foopy:80`が提供されていなければ`bar`を使用し、さらに使えない場合はプロキシを使いません。 @@ -296,6 +297,14 @@ session.defaultSession.webRequest.onBeforeSendHeaders(filter, function(details, * `method` String * `resourceType` String * `timestamp` Double + * `uploadData` Array (オプション) + * `callback` Function + +`uploadData`は `data`オブジェクトの配列です。 + +* `data` Object + * `bytes` Buffer - 送信されるコンテンツ + * `file` String - アップロードされるファイルパス `callback`は`response`オブジェクトでコールされる必要があります: @@ -317,6 +326,7 @@ session.defaultSession.webRequest.onBeforeSendHeaders(filter, function(details, * `resourceType` String * `timestamp` Double * `requestHeaders` Object +* `callback` Function The `callback` has to be called with an `response` object: @@ -355,6 +365,7 @@ The `callback` has to be called with an `response` object: * `statusLine` String * `statusCode` Integer * `responseHeaders` Object +* `callback` Function `callback`は`response`オブジェクトでコールされる必要があります: diff --git a/docs-translations/jp/api/synopsis.md b/docs-translations/jp/api/synopsis.md index a2f701807ea..683f5611eb1 100644 --- a/docs-translations/jp/api/synopsis.md +++ b/docs-translations/jp/api/synopsis.md @@ -4,7 +4,7 @@ Electron では全ての [Node.js のビルトインモジュール](http://node Electron はネイティブのデスクトップアプリケーション開発のための幾つかの追加のビルトインモジュールも提供しています。メインプロセスでだけ使えるモジュールもあれば、レンダラプロセス(ウェブページ)でだけ使えるモジュール、あるいはメインプロセス、レンダラプロセスどちらでも使えるモジュールもあります。 -基本的なルールは:[GUI][gui]、または低レベルのシステムに関連するモジュールはメインモジュールでだけ利用できるべきです。これらのモジュールを使用できるようにするためには [メインプロセス対レンダラプロセス][main-process] スクリプトの概念を理解する必要があります。 +基本的なルールは:[GUI][gui]、または低レベルのシステムに関連するモジュールはメインモジュールでだけ利用できるべきです。これらのモジュールを使用できるようにするためには [メインプロセス対レンダラプロセス](../tutorial/quick-start.md#メインプロセス)スクリプトの概念を理解する必要があります。 メインプロセススクリプトは普通の Node.js スクリプトのようなものです: @@ -64,6 +64,5 @@ require('electron').hideInternalModules() ``` [gui]: https://en.wikipedia.org/wiki/Graphical_user_interface -[main-process]: ../tutorial/quick-start.md#メインプロセス [desctructuring-assignment]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment [issue-387]: https://github.com/atom/electron/issues/387 diff --git a/docs-translations/jp/faq/electron-faq.md b/docs-translations/jp/faq/electron-faq.md index b7383197477..c8a65227717 100644 --- a/docs-translations/jp/faq/electron-faq.md +++ b/docs-translations/jp/faq/electron-faq.md @@ -69,5 +69,38 @@ delete window.module; ``` +## `require('electron').xxx` は定義されていません。 + +Electronの組み込みモジュールを使うとに、次のようなエラーに遭遇するかもしれません。 + +``` +> require('electron').webFrame.setZoomFactor(1.0); +Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined +``` + +これは、ローカルまたはグローバルのどちらかで [npm `electron` module][electron-module] をインストールしたことが原因で、Electronの組み込みモジュールを上書きしてしまいます。 + +正しい組み込みモジュールを使用しているかを確認するために、`electron`モジュールのパスを出力します。 + +```javascript +console.log(require.resolve('electron')); +``` + +そして、次の形式かどうかを確認します。 + +``` +"/path/to/Electron.app/Contents/Resources/atom.asar/renderer/api/lib/exports/electron.js" +``` + +If it is something like もし、`node_modules/electron/index.js` のような形式の場合は、npm `electron` モジュールを削除するか、それをリネームします。 + +```bash +npm uninstall electron +npm uninstall -g electron +``` + +しかし、組み込みモジュールを使用しているのに、まだこのエラーが出る場合、不適切なプロセスでモジュールを使用しようとしている可能性が高いです。例えば、`electron.app`はメインプロセスのみで使え、一方で`electron.webFrame`はレンダラープロセスのみに提供されています。 + [memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx +[electron-module]: https://www.npmjs.com/package/electron diff --git a/docs-translations/jp/tutorial/debugging-main-process.md b/docs-translations/jp/tutorial/debugging-main-process.md index 0839d351598..ffffdeb83ac 100644 --- a/docs-translations/jp/tutorial/debugging-main-process.md +++ b/docs-translations/jp/tutorial/debugging-main-process.md @@ -55,13 +55,13 @@ $ electron --debug=5858 your/app $ electron --debug-brk=5858 your/app ``` -### 5. Electronを使用して、[node-inspector][node-inspector] サーバーを開始する +### 6. Electronを使用して、[node-inspector][node-inspector] サーバーを開始する ```bash $ ELECTRON_RUN_AS_NODE=true path/to/electron.exe node_modules/node-inspector/bin/inspector.js ``` -### 6. デバッグUIを読み込みます +### 7. デバッグUIを読み込みます Chromeブラウザで、 http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 を開きます。エントリーラインを見るために、debug-brkを始めるには、ポーズをクリックします。 diff --git a/docs-translations/jp/tutorial/desktop-environment-integration.md b/docs-translations/jp/tutorial/desktop-environment-integration.md index 24d3e9d2aaa..0ef44b2f47c 100644 --- a/docs-translations/jp/tutorial/desktop-environment-integration.md +++ b/docs-translations/jp/tutorial/desktop-environment-integration.md @@ -25,16 +25,7 @@ myNotification.onclick = function () { * Windows 10では、通知はすぐに動作します。 * Windows 8.1 と Windows 8では、[Application User Model ID][app-user-model-id]で、アプリへのショートカットはスタートメニューにインストールされます。しかし、スタートメニューにピン止めをする必要がありません。 -* Windows 7以前は、通知はサポートされていません。 しかし、[Tray API](tray-balloon)を使用してバルーンヒントを送信することができます。 - -通知にイメージを使うために、通知オプションの `icon` プロパティにローカルのイメージファイル(`png`が望ましい)を設定します。 正しくない、または`http/https`の URLを設定した場合でも、通知は表示されますが、イメージは表示されません。 - -```javascript -new Notification('Title', { - body: 'Notification with icon', - icon: 'file:///C:/Users/feriese/Desktop/icon.png' -}); -``` +* Windows 7以前は、通知はサポートされていません。 しかし、[Tray API][tray-balloon]を使用してバルーンヒントを送信することができます。 その上で、bodyの最大サイズは250文字であることに留意してください。Windowsチームは、通知は200文字にすることを推奨しています。 diff --git a/docs-translations/jp/tutorial/mac-app-store-submission-guide.md b/docs-translations/jp/tutorial/mac-app-store-submission-guide.md index b2cf9d26d30..47d7a76b925 100644 --- a/docs-translations/jp/tutorial/mac-app-store-submission-guide.md +++ b/docs-translations/jp/tutorial/mac-app-store-submission-guide.md @@ -2,6 +2,8 @@ v0.34.0から、ElectronはMac App Store (MAS)にパッケージ化したアプリを登録することができます。このガイドでは、MASビルド用の制限とアプリを登録する方法についての情報を提供します。 +__Note:__ v0.36.0から、アプリがサンドボックス化された後GPUプロセスを妨害するバグがあるので、このバグが修正されるまでは、v0.35.xを使用することを推奨します。[issue #3871][issue-3871]で、このことに関する追加情報を確認できます。 + __Note:__ Mac App Storeにアプリを登録するには、費用が発生する[Apple Developer Program][developer-program]に登録する必要があります。 ## アプリを登録する方法 @@ -63,13 +65,18 @@ INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)" FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Libraries/libnode.dylib" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Electron Framework" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A" codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper.app/" codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper EH.app/" codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper NP.app/" -codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" +if [ -d "$FRAMEWORKS_PATH/Squirrel.framework/Versions/A" ]; then + # Signing a non-MAS build. + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Mantle.framework/Versions/A" + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/ReactiveCocoa.framework/Versions/A" + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Squirrel.framework/Versions/A" +fi +codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" + productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" ``` @@ -83,8 +90,8 @@ OS Xで、サンドボックスにアプリを新しく追加した場合、基 アプリのサンドボックスですべての要件を満たすために、MASビルドで次のモジュールを無効にしてください。 -* `crash-reporter` -* `auto-updater` +* `crashReporter` +* `autoUpdater` 次の挙動を変更してください。 @@ -92,7 +99,39 @@ OS Xで、サンドボックスにアプリを新しく追加した場合、基 * 一部のアクセシビリティ機能が動作しないことがあります。 * アプリはDNSの変更を認識しません。 -アプリのサンドボックスでの使用が原因で、アプリがアクセスできるリソースは厳密に制限されています。詳細は、 [App Sandboxing][app-sandboxing] を参照してください。 +アプリのサンドボックスでの使用では、アプリがアクセスできるリソースは厳密に制限されています。詳細は、 [App Sandboxing][app-sandboxing] を参照してください。 + +## Electronが使用する暗号化アルゴリズム + +あなたが住んでいる国や地域に依存して、Mac App Store がアプリで使用する暗号化アルゴリズムを文章化することを要求することがあり、暗号登録番号(U.S. Encryption Registration (ERN))の同意のコピーの提出を求められます。 + +Electron は次の暗号アルゴリズムを使用しています: + +* AES - [NIST SP 800-38A](http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf), [NIST SP 800-38D](http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf), [RFC 3394](http://www.ietf.org/rfc/rfc3394.txt) +* HMAC - [FIPS 198-1](http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf) +* ECDSA - ANS X9.62–2005 +* ECDH - ANS X9.63–2001 +* HKDF - [NIST SP 800-56C](http://csrc.nist.gov/publications/nistpubs/800-56C/SP-800-56C.pdf) +* PBKDF2 - [RFC 2898](https://tools.ietf.org/html/rfc2898) +* RSA - [RFC 3447](http://www.ietf.org/rfc/rfc3447) +* SHA - [FIPS 180-4](http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf) +* Blowfish - https://www.schneier.com/cryptography/blowfish/ +* CAST - [RFC 2144](https://tools.ietf.org/html/rfc2144), [RFC 2612](https://tools.ietf.org/html/rfc2612) +* DES - [FIPS 46-3](http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf) +* DH - [RFC 2631](https://tools.ietf.org/html/rfc2631) +* DSA - [ANSI X9.30](http://webstore.ansi.org/RecordDetail.aspx?sku=ANSI+X9.30-1%3A1997) +* EC - [SEC 1](http://www.secg.org/sec1-v2.pdf) +* IDEA - "On the Design and Security of Block Ciphers" book by X. Lai +* MD2 - [RFC 1319](http://tools.ietf.org/html/rfc1319) +* MD4 - [RFC 6150](https://tools.ietf.org/html/rfc6150) +* MD5 - [RFC 1321](https://tools.ietf.org/html/rfc1321) +* MDC2 - [ISO/IEC 10118-2](https://www.openssl.org/docs/manmaster/crypto/mdc2.html) +* RC2 - [RFC 2268](https://tools.ietf.org/html/rfc2268) +* RC4 - [RFC 4345](https://tools.ietf.org/html/rfc4345) +* RC5 - http://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf +* RIPEMD - [ISO/IEC 10118-3](http://webstore.ansi.org/RecordDetail.aspx?sku=ISO%2FIEC%2010118-3:2004) + +ERNの同意を取得するには、 [How to legally submit an app to Apple’s App Store when it uses encryption (or how to obtain an ERN)][ern-tutorial]を参照してくだsだい。 [developer-program]: https://developer.apple.com/support/compare-memberships/ [submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html @@ -101,3 +140,5 @@ OS Xで、サンドボックスにアプリを新しく追加した場合、基 [create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html [submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html [app-sandboxing]: https://developer.apple.com/app-sandboxing/ +[issue-3871]: https://github.com/atom/electron/issues/3871 +[ern-tutorial]: https://carouselapps.com/2015/12/15/legally-submit-app-apples-app-store-uses-encryption-obtain-ern/ diff --git a/docs-translations/jp/tutorial/supported-platforms.md b/docs-translations/jp/tutorial/supported-platforms.md index 8482931ed21..7d9f24b7ab6 100644 --- a/docs-translations/jp/tutorial/supported-platforms.md +++ b/docs-translations/jp/tutorial/supported-platforms.md @@ -4,7 +4,7 @@ Electronでは次のプラットフォームをサポートします。 ### OS X -OS X用に提供しているバイナリは64bitのみで、サポートするOS Xのバージョンは、OS X 10.8 以降です。 +OS X用に提供しているバイナリは64bitのみで、サポートするOS Xのバージョンは、OS X 10.9 以降です。 ### Windows From 066c189249f6392945d8c8a2e7373df705d6e983 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Sun, 31 Jan 2016 17:00:14 +0100 Subject: [PATCH 105/688] Renamed some cursor types to their CSS names and added a way to handle custom cursors properly. --- atom/browser/api/atom_api_web_contents.cc | 11 +++- atom/common/mouse_util.cc | 61 +++++++++++------------ atom/common/mouse_util.h | 2 +- docs/api/web-contents.md | 24 +++++---- 4 files changed, 53 insertions(+), 45 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 091c44ed517..ba067dac496 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1043,7 +1043,16 @@ void WebContents::EndFrameSubscription() { } void WebContents::OnCursorChange(const content::WebCursor& cursor) { - Emit("cursor-changed", CursorTypeToString(cursor)); + content::WebCursor::CursorInfo* info = new content::WebCursor::CursorInfo(); + cursor.GetCursorInfo(info); + + if (cursor.IsCustom()) { + Emit("cursor-changed", CursorTypeToString(info), + gfx::Image::CreateFrom1xBitmap(info->custom_image), + info->image_scale_factor); + } else { + Emit("cursor-changed", CursorTypeToString(info)); + } } void WebContents::SetSize(const SetSizeParams& params) { diff --git a/atom/common/mouse_util.cc b/atom/common/mouse_util.cc index 8178668ca15..8b7e4bbbc22 100644 --- a/atom/common/mouse_util.cc +++ b/atom/common/mouse_util.cc @@ -9,42 +9,37 @@ using Cursor = blink::WebCursorInfo::Type; namespace atom { -std::string CursorTypeToString(const content::WebCursor& cursor) { - content::WebCursor::CursorInfo* info = new content::WebCursor::CursorInfo(); - cursor.GetCursorInfo(info); - +std::string CursorTypeToString(const content::WebCursor::CursorInfo* info) { switch (info->type) { - case Cursor::TypePointer: return "pointer"; - case Cursor::TypeCross: return "cross"; - case Cursor::TypeHand: return "hand"; - case Cursor::TypeIBeam: return "i-beam"; + case Cursor::TypePointer: return "default"; + case Cursor::TypeCross: return "crosshair"; + case Cursor::TypeHand: return "pointer"; + case Cursor::TypeIBeam: return "text"; case Cursor::TypeWait: return "wait"; case Cursor::TypeHelp: return "help"; - case Cursor::TypeEastResize: return "east-resize"; - case Cursor::TypeNorthResize: return "north-resize"; - case Cursor::TypeNorthEastResize: return "north-east-resize"; - case Cursor::TypeNorthWestResize: return "north-west-resize"; - case Cursor::TypeSouthResize: return "south-resize"; - case Cursor::TypeSouthEastResize: return "south-east-resize"; - case Cursor::TypeSouthWestResize: return "south-west-resize"; - case Cursor::TypeWestResize: return "west-resize"; - case Cursor::TypeNorthSouthResize: return "north-south-resize"; - case Cursor::TypeEastWestResize: return "east-west-resize"; - case Cursor::TypeNorthEastSouthWestResize: - return "north-east-south-west-resize"; - case Cursor::TypeNorthWestSouthEastResize: - return "north-west-south-east-resize"; - case Cursor::TypeColumnResize: return "column-resize"; + case Cursor::TypeEastResize: return "e-resize"; + case Cursor::TypeNorthResize: return "n-resize"; + case Cursor::TypeNorthEastResize: return "ne-resize"; + case Cursor::TypeNorthWestResize: return "nw-resize"; + case Cursor::TypeSouthResize: return "s-resize"; + case Cursor::TypeSouthEastResize: return "se-resize"; + case Cursor::TypeSouthWestResize: return "sw-resize"; + case Cursor::TypeWestResize: return "w-resize"; + case Cursor::TypeNorthSouthResize: return "ns-resize"; + case Cursor::TypeEastWestResize: return "ew-resize"; + case Cursor::TypeNorthEastSouthWestResize: return "nesw-resize"; + case Cursor::TypeNorthWestSouthEastResize: return "nwse-resize"; + case Cursor::TypeColumnResize: return "col-resize"; case Cursor::TypeRowResize: return "row-resize"; - case Cursor::TypeMiddlePanning: return "middle-panning"; - case Cursor::TypeEastPanning: return "east-panning"; - case Cursor::TypeNorthPanning: return "north-panning"; - case Cursor::TypeNorthEastPanning: return "north-east-panning"; - case Cursor::TypeNorthWestPanning: return "north-west-panning"; - case Cursor::TypeSouthPanning: return "south-panning"; - case Cursor::TypeSouthEastPanning: return "south-east-panning"; - case Cursor::TypeSouthWestPanning: return "south-west-panning"; - case Cursor::TypeWestPanning: return "west-panning"; + case Cursor::TypeMiddlePanning: return "m-panning"; + case Cursor::TypeEastPanning: return "e-panning"; + case Cursor::TypeNorthPanning: return "n-panning"; + case Cursor::TypeNorthEastPanning: return "ne-panning"; + case Cursor::TypeNorthWestPanning: return "nw-panning"; + case Cursor::TypeSouthPanning: return "s-panning"; + case Cursor::TypeSouthEastPanning: return "se-panning"; + case Cursor::TypeSouthWestPanning: return "sw-panning"; + case Cursor::TypeWestPanning: return "w-panning"; case Cursor::TypeMove: return "move"; case Cursor::TypeVerticalText: return "vertical-text"; case Cursor::TypeCell: return "cell"; @@ -60,7 +55,7 @@ std::string CursorTypeToString(const content::WebCursor& cursor) { case Cursor::TypeGrab: return "grab"; case Cursor::TypeGrabbing: return "grabbing"; case Cursor::TypeCustom: return "custom"; - default: return "pointer"; + default: return "default"; } } diff --git a/atom/common/mouse_util.h b/atom/common/mouse_util.h index 9ea130821eb..f754f9a066a 100644 --- a/atom/common/mouse_util.h +++ b/atom/common/mouse_util.h @@ -29,7 +29,7 @@ namespace atom { // Returns the cursor's type as a string. -std::string CursorTypeToString(const content::WebCursor& cursor); +std::string CursorTypeToString(const content::WebCursor::CursorInfo* info); } // namespace atom diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index a3fcc37da3c..2dded8a042f 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -287,17 +287,21 @@ Returns: * `event` Event * `type` String +* `image` NativeImage +* `scale` Float -Emitted when the cursor's type changes. The `type` parameter can be `pointer`, -`cross`, `hand`, `i-beam`, `wait`, `help`, `east-resize`, `north-resize`, -`north-east-resize`, `north-west-resize`, `south-resize`, `south-east-resize`, -`south-west-resize`, `west-resize`, `north-south-resize`, `east-west-resize`, -`north-east-south-west-resize`, `north-west-south-east-resize`, `column-resize`, -`row-resize`, `middle-panning`, `east-panning`, `north-panning`, -`north-east-panning`, `north-west-panning`, `south-panning`, -`south-east-panning`, `south-west-panning`, `west-panning`, `move`, -`vertical-text`, `cell`, `context-menu`, `alias`, `progress`, `nodrop`, `copy`, -`none`, `not-allowed`, `zoom-in`, `zoom-out`, `grab`, `grabbing`, `custom`. +Emitted when the cursor's type changes. The `type` parameter can be `default`, +`crosshair`, `pointer`, `text`, `wait`, `help`, `e-resize`, `n-resize`, +`ne-resize`, `nw-resize`, `s-resize`, `se-resize`, `sw-resize`, `w-resize`, +`ns-resize`, `ew-resize`, `nesw-resize`, `nwse-resize`, `col-resize`, +`row-resize`, `m-panning`, `e-panning`, `n-panning`, `ne-panning`, `nw-panning`, +`s-panning`, `se-panning`, `sw-panning`, `w-panning`, `move`, `vertical-text`, +`cell`, `context-menu`, `alias`, `progress`, `nodrop`, `copy`, `none`, +`not-allowed`, `zoom-in`, `zoom-out`, `grab`, `grabbing`, `custom`. + +If the `type` parameter is `custom`, the `image` parameter will hold the custom +cursor image in a `NativeImage`, and the `scale` will hold scaling information +for the image. ## Instance Methods From 1d629640bfc779a87d8c332d3fc7c0187de7c81e Mon Sep 17 00:00:00 2001 From: Belleve Invis Date: Mon, 1 Feb 2016 00:28:44 +0800 Subject: [PATCH 106/688] Add link to BrowserWindow::setMenu --- docs/api/menu.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/api/menu.md b/docs/api/menu.md index 1de3b4f101e..49a499a3d4b 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -296,6 +296,11 @@ no matter what label you set. To change it you have to change your app's name by modifying your app bundle's `Info.plist` file. See [About Information Property List Files][AboutInformationPropertyListFiles] for more information. +## Setting Menu for Specific Browser Window (*Linux* *Windows*) + +The [`setMenu` method][setMenu] of browser windows can set the menu of certain +browser window. + ## Menu Item Position You can make use of `position` and `id` to control how the item will be placed @@ -371,3 +376,5 @@ Menu: ``` [AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html +[setMenu]: +https://github.com/atom/electron/blob/master/docs/api/browser-window.md#winsetmenumenu-linux-windows From 04c3e083fb9922f3a2f4a11cf55002a1639eebbf Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 1 Feb 2016 00:43:29 +0530 Subject: [PATCH 107/688] remove unnecessary getter --- atom/browser/api/atom_api_web_contents.cc | 5 +++-- atom/browser/atom_browser_context.cc | 3 ++- atom/browser/atom_browser_context.h | 4 ---- atom/browser/web_contents_permission_helper.cc | 4 +++- atom/browser/web_contents_permission_helper.h | 5 ----- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index c6ab110b832..fa19130422a 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1074,8 +1074,9 @@ void WebContents::SetPermissionRequestHandler(v8::Local val, args->ThrowError("Must pass null or function"); return; } - GetBrowserContext()->permission_manager() - ->SetPermissionRequestHandler(GetID(), handler); + auto permission_manager = static_cast( + web_contents()->GetBrowserContext()->GetPermissionManager()); + permission_manager->SetPermissionRequestHandler(GetID(), handler); } v8::Local WebContents::GetWebPreferences(v8::Isolate* isolate) { diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 35358ac08a4..be004c8f6db 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -65,7 +65,6 @@ std::string RemoveWhitespace(const std::string& str) { AtomBrowserContext::AtomBrowserContext(const std::string& partition, bool in_memory) : brightray::BrowserContext(partition, in_memory), - permission_manager_(new AtomPermissionManager), cert_verifier_(nullptr), job_factory_(new AtomURLRequestJobFactory), network_delegate_(new AtomNetworkDelegate), @@ -172,6 +171,8 @@ content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() { } content::PermissionManager* AtomBrowserContext::GetPermissionManager() { + if (!permission_manager_.get()) + permission_manager_.reset(new AtomPermissionManager); return permission_manager_.get(); } diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index 44cd1f5b79e..d959adbc753 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -51,10 +51,6 @@ class AtomBrowserContext : public brightray::BrowserContext { AtomNetworkDelegate* network_delegate() const { return network_delegate_; } - AtomPermissionManager* permission_manager() const { - return permission_manager_.get(); - } - private: scoped_ptr download_manager_delegate_; scoped_ptr guest_manager_; diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index 04a6a5d9883..cf7ae1f30ec 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -7,6 +7,7 @@ #include #include "atom/browser/atom_permission_manager.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/media_capture_devices.h" #include "content/public/browser/render_process_host.h" @@ -79,7 +80,8 @@ void WebContentsPermissionHelper::RequestPermission( content::PermissionType permission, const base::Callback& callback) { auto rfh = web_contents_->GetMainFrame(); - auto permission_manager = browser_context()->permission_manager(); + auto permission_manager = static_cast( + web_contents_->GetBrowserContext()->GetPermissionManager()); auto origin = web_contents_->GetLastCommittedURL(); permission_manager->RequestPermission(permission, rfh, origin, callback); } diff --git a/atom/browser/web_contents_permission_helper.h b/atom/browser/web_contents_permission_helper.h index 749e90184c2..6bd2bb2559e 100644 --- a/atom/browser/web_contents_permission_helper.h +++ b/atom/browser/web_contents_permission_helper.h @@ -5,7 +5,6 @@ #ifndef ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_ #define ATOM_BROWSER_WEB_CONTENTS_PERMISSION_HELPER_H_ -#include "atom/browser/atom_browser_context.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/web_contents_user_data.h" #include "content/public/common/media_stream_request.h" @@ -24,10 +23,6 @@ class WebContentsPermissionHelper void RequestWebNotificationPermission( const base::Callback& callback); - AtomBrowserContext* browser_context() const { - return static_cast(web_contents_->GetBrowserContext()); - } - private: explicit WebContentsPermissionHelper(content::WebContents* web_contents); friend class content::WebContentsUserData; From d471952adf934bc0ad71ab13a881aac4f5866c00 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Sun, 31 Jan 2016 07:05:39 +0900 Subject: [PATCH 108/688] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/api/session.md | 1 + .../mac-app-store-submission-guide.md | 60 ++++++++++++++++--- .../ko-KR/tutorial/supported-platforms.md | 2 +- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index 6f39ab9dcdd..de5c08848cf 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -212,6 +212,7 @@ proxyURL = ["://"][":"] ``` 예시: + * `http=foopy:80;ftp=foopy2` - http:// URL에 `foopy:80` HTTP 프록시를 사용합니다. `foopy2:80` 는 ftp:// URL에 사용됩니다. * `foopy:80` - 모든 URL에 `foopy:80` 프록시를 사용합니다. diff --git a/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md b/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md index d316d16da83..c319f344b63 100644 --- a/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md +++ b/docs-translations/ko-KR/tutorial/mac-app-store-submission-guide.md @@ -4,6 +4,10 @@ Electron은 v0.34.0 버전부터 앱 패키지를 Mac App Store(MAS)에 제출 되었습니다. 이 가이드는 어플리케이션을 앱 스토어에 등록하는 방법과 빌드의 한계에 대한 설명을 제공합니다. +__참고:__ v0.36.0 버전부터 어플리케이션이 샌드박스화 된 상태로 실행되면 GPU 작동을 +방지하는 버그가 있었습니다. 따라서 이 버그가 고쳐지기 전까진 v0.35.x 버전을 사용하는 +것을 권장합니다. 이 버그에 관한 자세한 사항은 [issue #3871][issue-3871]를 참고하세요. + __참고:__ Mac App Store에 어플리케이션을 등록하려면 [Apple Developer Program][developer-program]에 등록되어 있어야 하며 비용이 발생할 수 있습니다. @@ -73,13 +77,18 @@ INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)" FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Libraries/libnode.dylib" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Electron Framework" -codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A" codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper.app/" codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper EH.app/" codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper NP.app/" -codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" +if [ -d "$FRAMEWORKS_PATH/Squirrel.framework/Versions/A" ]; then + # non-MAS 빌드 서명 + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Mantle.framework/Versions/A" + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/ReactiveCocoa.framework/Versions/A" + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Squirrel.framework/Versions/A" +fi +codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" + productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" ``` @@ -98,8 +107,8 @@ productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RES 모든 어플리케이션 샌드박스에 대한 요구 사항을 충족시키기 위해, 다음 모듈들은 MAS 빌드에서 비활성화됩니다: -* `crash-reporter` -* `auto-updater` +* `crashReporter` +* `autoUpdater` 그리고 다음 동작으로 대체됩니다: @@ -111,7 +120,42 @@ productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RES 엄격하게 제한되어 있습니다. 자세한 내용은 [App Sandboxing][app-sandboxing] 문서를 참고하세요. -**역주:** [Mac 앱 배포 가이드 공식 문서](https://developer.apple.com/osx/distribution/kr/) +## Electron에서 사용하는 암호화 알고리즘 + +국가와 살고 있는 지역에 따라, 맥 앱스토어는 제출한 어플리케이션에서 사용하는 암호화 +알고리즘의 문서를 요구할 수 있습니다. 심지어 U.S. Encryption Registration (ERN)의 +승인 사본을 제출하라고 할 수도 있습니다. + +Electron은 다음과 같은 암호화 알고리즘을 사용합니다: + +* AES - [NIST SP 800-38A](http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf), [NIST SP 800-38D](http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf), [RFC 3394](http://www.ietf.org/rfc/rfc3394.txt) +* HMAC - [FIPS 198-1](http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf) +* ECDSA - ANS X9.62–2005 +* ECDH - ANS X9.63–2001 +* HKDF - [NIST SP 800-56C](http://csrc.nist.gov/publications/nistpubs/800-56C/SP-800-56C.pdf) +* PBKDF2 - [RFC 2898](https://tools.ietf.org/html/rfc2898) +* RSA - [RFC 3447](http://www.ietf.org/rfc/rfc3447) +* SHA - [FIPS 180-4](http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf) +* Blowfish - https://www.schneier.com/cryptography/blowfish/ +* CAST - [RFC 2144](https://tools.ietf.org/html/rfc2144), [RFC 2612](https://tools.ietf.org/html/rfc2612) +* DES - [FIPS 46-3](http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf) +* DH - [RFC 2631](https://tools.ietf.org/html/rfc2631) +* DSA - [ANSI X9.30](http://webstore.ansi.org/RecordDetail.aspx?sku=ANSI+X9.30-1%3A1997) +* EC - [SEC 1](http://www.secg.org/sec1-v2.pdf) +* IDEA - "On the Design and Security of Block Ciphers" book by X. Lai +* MD2 - [RFC 1319](http://tools.ietf.org/html/rfc1319) +* MD4 - [RFC 6150](https://tools.ietf.org/html/rfc6150) +* MD5 - [RFC 1321](https://tools.ietf.org/html/rfc1321) +* MDC2 - [ISO/IEC 10118-2](https://www.openssl.org/docs/manmaster/crypto/mdc2.html) +* RC2 - [RFC 2268](https://tools.ietf.org/html/rfc2268) +* RC4 - [RFC 4345](https://tools.ietf.org/html/rfc4345) +* RC5 - http://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf +* RIPEMD - [ISO/IEC 10118-3](http://webstore.ansi.org/RecordDetail.aspx?sku=ISO%2FIEC%2010118-3:2004) + +ERN의 승인을 얻는 방법은, 다음 글을 참고하는 것이 좋습니다: +[어플리케이션이 암호화를 사용할 때, 합법적으로 Apple의 앱 스토어에 제출하는 방법 (또는 ERN의 승인을 얻는 방법)][ern-tutorial]. + +**역주:** [Mac 앱 배포 가이드 공식 한국어 문서](https://developer.apple.com/osx/distribution/kr/) [developer-program]: https://developer.apple.com/support/compare-memberships/ [submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html @@ -120,3 +164,5 @@ productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RES [create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html [submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html [app-sandboxing]: https://developer.apple.com/app-sandboxing/ +[issue-3871]: https://github.com/atom/electron/issues/3871 +[ern-tutorial]: https://carouselapps.com/2015/12/15/legally-submit-app-apples-app-store-uses-encryption-obtain-ern/ diff --git a/docs-translations/ko-KR/tutorial/supported-platforms.md b/docs-translations/ko-KR/tutorial/supported-platforms.md index 3b3a00d7215..656d31308e0 100644 --- a/docs-translations/ko-KR/tutorial/supported-platforms.md +++ b/docs-translations/ko-KR/tutorial/supported-platforms.md @@ -4,7 +4,7 @@ Electron에선 다음과 같은 플랫폼을 지원합니다: ### OS X -OS X는 64비트 바이너리만 제공됩니다. 그리고 최소 OS X 지원 버전은 10.8입니다. +OS X는 64비트 바이너리만 제공됩니다. 그리고 최소 OS X 지원 버전은 10.9입니다. ### Windows From 745253a36943b613eb737b5bd85a2012dfbd4441 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Mon, 1 Feb 2016 07:17:58 +0100 Subject: [PATCH 109/688] Quick fix for the memory leak + docs --- atom/browser/api/atom_api_web_contents.cc | 8 ++++---- atom/common/mouse_util.cc | 4 ++-- atom/common/mouse_util.h | 2 +- docs/api/web-contents.md | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index ba067dac496..b7b0576d8bf 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1043,13 +1043,13 @@ void WebContents::EndFrameSubscription() { } void WebContents::OnCursorChange(const content::WebCursor& cursor) { - content::WebCursor::CursorInfo* info = new content::WebCursor::CursorInfo(); - cursor.GetCursorInfo(info); + content::WebCursor::CursorInfo info; + cursor.GetCursorInfo(&info); if (cursor.IsCustom()) { Emit("cursor-changed", CursorTypeToString(info), - gfx::Image::CreateFrom1xBitmap(info->custom_image), - info->image_scale_factor); + gfx::Image::CreateFrom1xBitmap(info.custom_image), + info.image_scale_factor); } else { Emit("cursor-changed", CursorTypeToString(info)); } diff --git a/atom/common/mouse_util.cc b/atom/common/mouse_util.cc index 8b7e4bbbc22..69aadaa7a04 100644 --- a/atom/common/mouse_util.cc +++ b/atom/common/mouse_util.cc @@ -9,8 +9,8 @@ using Cursor = blink::WebCursorInfo::Type; namespace atom { -std::string CursorTypeToString(const content::WebCursor::CursorInfo* info) { - switch (info->type) { +std::string CursorTypeToString(const content::WebCursor::CursorInfo& info) { + switch (info.type) { case Cursor::TypePointer: return "default"; case Cursor::TypeCross: return "crosshair"; case Cursor::TypeHand: return "pointer"; diff --git a/atom/common/mouse_util.h b/atom/common/mouse_util.h index f754f9a066a..2fd937422da 100644 --- a/atom/common/mouse_util.h +++ b/atom/common/mouse_util.h @@ -29,7 +29,7 @@ namespace atom { // Returns the cursor's type as a string. -std::string CursorTypeToString(const content::WebCursor::CursorInfo* info); +std::string CursorTypeToString(const content::WebCursor::CursorInfo& info); } // namespace atom diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 2dded8a042f..afdd08c4d00 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -287,8 +287,8 @@ Returns: * `event` Event * `type` String -* `image` NativeImage -* `scale` Float +* `image` NativeImage (optional) +* `scale` Float (optional) Emitted when the cursor's type changes. The `type` parameter can be `default`, `crosshair`, `pointer`, `text`, `wait`, `help`, `e-resize`, `n-resize`, From db26dcaf4c6c22f5bc04f074d0e98c056f9fd312 Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 1 Feb 2016 03:05:34 +0530 Subject: [PATCH 110/688] expose handler from session and remove permission-request event --- atom/browser/api/atom_api_session.cc | 16 +++++ atom/browser/api/atom_api_session.h | 2 + atom/browser/api/atom_api_web_contents.cc | 15 ----- atom/browser/api/atom_api_web_contents.h | 4 -- atom/browser/atom_permission_manager.cc | 63 +++++++++---------- atom/browser/atom_permission_manager.h | 32 +++++----- atom/browser/lib/guest-view-manager.js | 23 +------ .../browser/web_contents_permission_helper.cc | 15 ++++- .../content_converter.cc | 7 +++ .../content_converter.h | 6 ++ .../lib/web-view/guest-view-internal.js | 12 +--- docs/api/session.md | 23 +++++++ docs/api/web-view-tag.md | 18 ------ spec/webview-spec.js | 32 +++++----- 14 files changed, 134 insertions(+), 134 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 1cc76ebfa23..b0c99141f75 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -14,8 +14,10 @@ #include "atom/browser/api/save_page_handler.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" +#include "atom/browser/atom_permission_manager.h" #include "atom/browser/net/atom_cert_verifier.h" #include "atom/common/native_mate_converters/callback.h" +#include "atom/common/native_mate_converters/content_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/net_converter.h" @@ -397,6 +399,18 @@ void Session::SetCertVerifyProc(v8::Local val, browser_context_->cert_verifier()->SetVerifyProc(proc); } +void Session::SetPermissionRequestHandler(v8::Local val, + mate::Arguments* args) { + AtomPermissionManager::RequestHandler handler; + if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) { + args->ThrowError("Must pass null or function"); + return; + } + auto permission_manager = static_cast( + browser_context()->GetPermissionManager()); + permission_manager->SetPermissionRequestHandler(handler); +} + v8::Local Session::Cookies(v8::Isolate* isolate) { if (cookies_.IsEmpty()) { auto handle = atom::api::Cookies::Create(isolate, browser_context()); @@ -448,6 +462,8 @@ void Session::BuildPrototype(v8::Isolate* isolate, .SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation) .SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation) .SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc) + .SetMethod("setPermissionRequestHandler", + &Session::SetPermissionRequestHandler) .SetProperty("cookies", &Session::Cookies) .SetProperty("webRequest", &Session::WebRequest); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 37a5a45a6c9..efcafbfe5e3 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -76,6 +76,8 @@ class Session: public mate::TrackableObject, void EnableNetworkEmulation(const mate::Dictionary& options); void DisableNetworkEmulation(); void SetCertVerifyProc(v8::Local proc, mate::Arguments* args); + void SetPermissionRequestHandler(v8::Local val, + mate::Arguments* args); v8::Local Cookies(v8::Isolate* isolate); v8::Local WebRequest(v8::Isolate* isolate); diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index fa19130422a..0a9e6c3ad6f 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -13,7 +13,6 @@ #include "atom/browser/atom_browser_client.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" -#include "atom/browser/atom_permission_manager.h" #include "atom/browser/native_window.h" #include "atom/browser/web_contents_permission_helper.h" #include "atom/browser/web_contents_preferences.h" @@ -1067,18 +1066,6 @@ bool WebContents::IsGuest() const { return type_ == WEB_VIEW; } -void WebContents::SetPermissionRequestHandler(v8::Local val, - mate::Arguments* args) { - AtomPermissionManager::RequestHandler handler; - if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) { - args->ThrowError("Must pass null or function"); - return; - } - auto permission_manager = static_cast( - web_contents()->GetBrowserContext()->GetPermissionManager()); - permission_manager->SetPermissionRequestHandler(GetID(), handler); -} - v8::Local WebContents::GetWebPreferences(v8::Isolate* isolate) { WebContentsPreferences* web_preferences = WebContentsPreferences::FromWebContents(web_contents()); @@ -1178,8 +1165,6 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("_printToPDF", &WebContents::PrintToPDF) .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) - .SetMethod("_setPermissionRequestHandler", - &WebContents::SetPermissionRequestHandler) .SetProperty("session", &WebContents::Session) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents) .SetProperty("debugger", &WebContents::Debugger); diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 6232aa3bf0c..6587759efb9 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -133,10 +133,6 @@ class WebContents : public mate::TrackableObject, void SetAllowTransparency(bool allow); bool IsGuest() const; - // Handler for permission requests. - void SetPermissionRequestHandler(v8::Local val, - mate::Arguments* args); - // Returns the web preferences of current WebContents. v8::Local GetWebPreferences(v8::Isolate* isolate); diff --git a/atom/browser/atom_permission_manager.cc b/atom/browser/atom_permission_manager.cc index ccd456e7c20..c245a278c3b 100644 --- a/atom/browser/atom_permission_manager.cc +++ b/atom/browser/atom_permission_manager.cc @@ -8,6 +8,7 @@ #include "content/public/browser/permission_type.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" namespace atom { @@ -19,33 +20,13 @@ AtomPermissionManager::~AtomPermissionManager() { } void AtomPermissionManager::SetPermissionRequestHandler( - int id, const RequestHandler& handler) { - if (handler.is_null()) { - request_handler_map_.erase(id); - return; + if (handler.is_null() && !pending_requests_.empty()) { + for (const auto& request : pending_requests_) + request.second.Run(content::PERMISSION_STATUS_DENIED); + pending_requests_.clear(); } - request_handler_map_[id] = handler; -} - -void AtomPermissionManager::RequestPermission( - content::PermissionType permission, - content::RenderFrameHost* render_frame_host, - const GURL& origin, - const base::Callback& callback) { - bool user_gesture = false; - RequestPermission(permission, render_frame_host, origin, user_gesture, - base::Bind(&AtomPermissionManager::OnPermissionResponse, - base::Unretained(this), callback)); -} - -void AtomPermissionManager::OnPermissionResponse( - const base::Callback& callback, - content::PermissionStatus status) { - if (status == content::PERMISSION_STATUS_GRANTED) - callback.Run(true); - else - callback.Run(false); + request_handler_ = handler; } int AtomPermissionManager::RequestPermission( @@ -53,25 +34,39 @@ int AtomPermissionManager::RequestPermission( content::RenderFrameHost* render_frame_host, const GURL& requesting_origin, bool user_gesture, - const ResponseCallback& callback) { - int process_id = render_frame_host->GetProcess()->GetID(); - auto request_handler = request_handler_map_.find(process_id); - + const ResponseCallback& response_callback) { if (permission == content::PermissionType::MIDI_SYSEX) { content::ChildProcessSecurityPolicy::GetInstance()-> - GrantSendMidiSysExMessage(process_id); + GrantSendMidiSysExMessage(render_frame_host->GetProcess()->GetID()); } - if (request_handler != request_handler_map_.end()) { - pending_requests_[++request_id_] = callback; - request_handler->second.Run(permission, callback); + if (!request_handler_.is_null()) { + auto web_contents = + content::WebContents::FromRenderFrameHost(render_frame_host); + ++request_id_; + auto callback = base::Bind(&AtomPermissionManager::OnPermissionResponse, + base::Unretained(this), + request_id_, + requesting_origin, + response_callback); + pending_requests_[request_id_] = callback; + request_handler_.Run(web_contents, permission, callback); return request_id_; } - callback.Run(content::PERMISSION_STATUS_GRANTED); + response_callback.Run(content::PERMISSION_STATUS_GRANTED); return kNoPendingOperation; } +void AtomPermissionManager::OnPermissionResponse( + int request_id, + const GURL& origin, + const ResponseCallback& callback, + content::PermissionStatus status) { + callback.Run(status); + pending_requests_.erase(request_id); +} + void AtomPermissionManager::CancelPermissionRequest(int request_id) { auto request = pending_requests_.find(request_id); if (request != pending_requests_.end()) { diff --git a/atom/browser/atom_permission_manager.h b/atom/browser/atom_permission_manager.h index fb449037f64..8d8729acc66 100644 --- a/atom/browser/atom_permission_manager.h +++ b/atom/browser/atom_permission_manager.h @@ -7,10 +7,13 @@ #include -#include "base/callback_forward.h" -#include "base/macros.h" +#include "base/callback.h" #include "content/public/browser/permission_manager.h" +namespace content { +class WebContents; +} + namespace atom { class AtomPermissionManager : public content::PermissionManager { @@ -21,22 +24,13 @@ class AtomPermissionManager : public content::PermissionManager { using ResponseCallback = base::Callback; using RequestHandler = - base::Callback; // Handler to dispatch permission requests in JS. - void SetPermissionRequestHandler(int id, const RequestHandler& handler); + void SetPermissionRequestHandler(const RequestHandler& handler); - void RequestPermission( - content::PermissionType permission, - content::RenderFrameHost* render_frame_host, - const GURL& origin, - const base::Callback& callback); - void OnPermissionResponse( - const base::Callback& callback, - content::PermissionStatus status); - - protected: // content::PermissionManager: int RequestPermission( content::PermissionType permission, @@ -44,6 +38,14 @@ class AtomPermissionManager : public content::PermissionManager { const GURL& requesting_origin, bool user_gesture, const ResponseCallback& callback) override; + + protected: + void OnPermissionResponse(int request_id, + const GURL& url, + const ResponseCallback& callback, + content::PermissionStatus status); + + // content::PermissionManager: void CancelPermissionRequest(int request_id) override; void ResetPermission(content::PermissionType permission, const GURL& requesting_origin, @@ -63,7 +65,7 @@ class AtomPermissionManager : public content::PermissionManager { void UnsubscribePermissionStatusChange(int subscription_id) override; private: - std::map request_handler_map_; + RequestHandler request_handler_; std::map pending_requests_; diff --git a/atom/browser/lib/guest-view-manager.js b/atom/browser/lib/guest-view-manager.js index d4332070fa6..b41b9b3a0f5 100644 --- a/atom/browser/lib/guest-view-manager.js +++ b/atom/browser/lib/guest-view-manager.js @@ -42,7 +42,6 @@ var supportedWebViewEvents = [ var nextInstanceId = 0; var guestInstances = {}; var embedderElementsMap = {}; -var pendingRequestsMap = {}; var reverseEmbedderElementsMap = {}; // Moves the last element of array to the first one. @@ -135,15 +134,7 @@ var createGuest = function(embedder, params) { if (params.allowtransparency != null) { this.setAllowTransparency(params.allowtransparency); } - guest.allowPopups = params.allowpopups; - - // Dispatches permission request event. - this._setPermissionRequestHandler((permission, callback) => { - if (!pendingRequestsMap[this.viewInstanceId]) - pendingRequestsMap[this.viewInstanceId] = {}; - pendingRequestsMap[this.viewInstanceId][permission] = callback; - embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + this.viewInstanceId, "permission-request", permission]); - }); + return guest.allowPopups = params.allowpopups; }); // Dispatch events to embedder. @@ -170,7 +161,6 @@ var createGuest = function(embedder, params) { var args = 2 <= arguments.length ? slice.call(arguments, 1) : []; return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-" + guest.viewInstanceId].concat(slice.call(args))); }); - return id; }; @@ -198,8 +188,7 @@ var attachGuest = function(embedder, elementInstanceId, guestInstanceId, params) nodeIntegration: (ref1 = params.nodeintegration) != null ? ref1 : false, plugins: params.plugins, webSecurity: !params.disablewebsecurity, - blinkFeatures: params.blinkfeatures, - webNotification: !params.disablewebnotification, + blinkFeatures: params.blinkfeatures }; if (params.preload) { webPreferences.preloadURL = params.preload; @@ -216,7 +205,6 @@ var destroyGuest = function(embedder, id) { webViewManager.removeGuest(embedder, id); guestInstances[id].guest.destroy(); delete guestInstances[id]; - delete pendingRequestsMap[id]; key = reverseEmbedderElementsMap[id]; if (key != null) { delete reverseEmbedderElementsMap[id]; @@ -246,13 +234,6 @@ ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', function(even return (ref1 = guestInstances[id]) != null ? ref1.guest.setAllowTransparency(allowtransparency) : void 0; }); -ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE', function(event, id, permission, allowed) { - if (pendingRequestsMap[id] != null) { - const callback = pendingRequestsMap[id][permission]; - callback.apply(null, [allowed]); - } -}); - // Returns WebContents from its guest id. exports.getGuest = function(id) { var ref1; diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index cf7ae1f30ec..da2ad57ad97 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -66,6 +66,14 @@ void MediaAccessAllowed( callback.Run(devices, result, scoped_ptr()); } +void OnPermissionResponse(const base::Callback& callback, + content::PermissionStatus status) { + if (status == content::PERMISSION_STATUS_GRANTED) + callback.Run(true); + else + callback.Run(false); +} + } // namespace WebContentsPermissionHelper::WebContentsPermissionHelper( @@ -83,13 +91,18 @@ void WebContentsPermissionHelper::RequestPermission( auto permission_manager = static_cast( web_contents_->GetBrowserContext()->GetPermissionManager()); auto origin = web_contents_->GetLastCommittedURL(); - permission_manager->RequestPermission(permission, rfh, origin, callback); + bool user_gesture = false; + permission_manager->RequestPermission( + permission, rfh, origin, user_gesture, + base::Bind(&OnPermissionResponse, callback)); } void WebContentsPermissionHelper::RequestMediaAccessPermission( const content::MediaStreamRequest& request, const content::MediaResponseCallback& response_callback) { auto callback = base::Bind(&MediaAccessAllowed, request, response_callback); + // The permission type doesn't matter here, AUDIO_CAPTURE/VIDEO_CAPTURE + // are presented as same type in content_converter.h. RequestPermission(content::PermissionType::AUDIO_CAPTURE, callback); } diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index d85188dad1f..15066085af0 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -7,6 +7,7 @@ #include #include +#include "atom/browser/api/atom_api_web_contents.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "content/public/browser/web_contents.h" @@ -163,4 +164,10 @@ bool Converter::FromV8( return true; } +// static +v8::Local Converter::ToV8( + v8::Isolate* isolate, content::WebContents* val) { + return atom::api::WebContents::CreateFrom(isolate, val).ToV8(); +} + } // namespace mate diff --git a/atom/common/native_mate_converters/content_converter.h b/atom/common/native_mate_converters/content_converter.h index 6c9130b1887..b1a42b6897c 100644 --- a/atom/common/native_mate_converters/content_converter.h +++ b/atom/common/native_mate_converters/content_converter.h @@ -53,6 +53,12 @@ struct Converter { content::StopFindAction* out); }; +template<> +struct Converter { + static v8::Local ToV8(v8::Isolate* isolate, + content::WebContents* val); +}; + } // namespace mate #endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_CONTENT_CONVERTER_H_ diff --git a/atom/renderer/lib/web-view/guest-view-internal.js b/atom/renderer/lib/web-view/guest-view-internal.js index acade1f41c0..a7427abd631 100644 --- a/atom/renderer/lib/web-view/guest-view-internal.js +++ b/atom/renderer/lib/web-view/guest-view-internal.js @@ -34,8 +34,7 @@ var WEB_VIEW_EVENTS = { 'page-favicon-updated': ['favicons'], 'enter-html-full-screen': [], 'leave-html-full-screen': [], - 'found-in-page': ['result'], - 'permission-request': ['permission', 'allow', 'deny'] + 'found-in-page': ['result'] }; var DEPRECATED_EVENTS = { @@ -65,15 +64,6 @@ module.exports = { ipcRenderer.on("ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + viewInstanceId, function() { var eventName = arguments[1]; var args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - if (eventName === 'permission-request') { - var allow = function allow() { - ipcRenderer.send("ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE", viewInstanceId, args[0], "granted"); - }; - var deny = function deny() { - ipcRenderer.send("ATOM_SHELL_GUEST_VIEW_MANAGER_SET_PERMISSION_RESPONSE", viewInstanceId, args[0], "denied"); - }; - args = args.concat([allow, deny]); - } return dispatchEvent.apply(null, [webView, eventName, eventName].concat(slice.call(args))); }); ipcRenderer.on("ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-" + viewInstanceId, function() { diff --git a/docs/api/session.md b/docs/api/session.md index da5bac23592..c70be61de89 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -289,6 +289,29 @@ myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, c }); ``` +#### `ses.setPermissionRequestHandler(handler)` + +* `handler` Function + * `webContents` Object - [WebContents](web-contents.md) requesting the permission. + * `permission` String - Enum of 'media', 'geolocation', 'notifications', 'midiSysex'. + * `callback` Function - Allow or deny the permission. + +Sets the handler which can be used to respond to permission requests for the `session`. +Calling `callback('granted')` will allow the permission and `callback('denied')` will reject it. + +```javascript +session.fromPartition(partition).setPermissionRequestHandler(function(webContents, permission, callback) { + if (webContents.getURL() === host) { + if (permission == "notifications") { + callback(); // denied. + return; + } + } + + callback('granted'); +}); +``` + #### `ses.webRequest` The `webRequest` API set allows to intercept and modify contents of a request at diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 229ee12f1a5..9cb8f49af35 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -736,22 +736,4 @@ Emitted when DevTools is closed. Emitted when DevTools is focused / opened. -### Event: 'permission-request' - -Returns: - -* `permission` String - The type of permission being requested. Enum of 'media', 'notifications', 'midiSysex', 'geolocation'. -* `allow` Function - Allows the permission. -* `deny` Function - Deny the permission. This is the default behaviour if `allow` is not called. - -Emitted when guest page requires special permission. - -```javascript -// This will deny guest page access to the webkitGetUserMedia API. -webview.addEventListener('permission-request', function(e) { - if (e.permission === 'media') - e.deny(); -}); -``` - [blink-feature-string]: https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/platform/RuntimeEnabledFeatures.cpp&sq=package:chromium&type=cs&l=527 diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 190a3266090..6a386604676 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -634,19 +634,27 @@ describe(' tag', function() { }); }); describe('permission-request event', function() { + function setUpRequestHandler(webview, requested_permission) { + const session = require('electron').remote.session; + var listener = function(webContents, permission, callback) { + if (webContents.getId() === webview.getId() ) { + assert.equal(permission, requested_permission); + callback("denied"); + } + }; + session.fromPartition(webview.partition).setPermissionRequestHandler(listener); + } + it ('emits when using navigator.getUserMedia api', function(done) { webview.addEventListener('ipc-message', function(e) { assert(e.channel, 'message'); assert(e.args, ['PermissionDeniedError']); done(); }); - webview.addEventListener('permission-request', function(e) { - if (e.permission === 'media') { - e.deny(); - } - }); webview.src = "file://" + fixtures + "/pages/permissions/media.html"; + webview.partition = "permissionTest"; webview.setAttribute('nodeintegration', 'on'); + setUpRequestHandler(webview, "media"); document.body.appendChild(webview); }); @@ -656,13 +664,10 @@ describe(' tag', function() { assert(e.args, ['ERROR(1): User denied Geolocation']); done(); }); - webview.addEventListener('permission-request', function(e) { - if (e.permission === 'geolocation') { - e.deny(); - } - }); webview.src = "file://" + fixtures + "/pages/permissions/geolocation.html"; + webview.partition = "permissionTest"; webview.setAttribute('nodeintegration', 'on'); + setUpRequestHandler(webview, "geolocation"); document.body.appendChild(webview); }); @@ -672,13 +677,10 @@ describe(' tag', function() { assert(e.args, ['SecurityError']); done(); }); - webview.addEventListener('permission-request', function(e) { - if (e.permission === 'midiSysex') { - e.deny(); - } - }); webview.src = "file://" + fixtures + "/pages/permissions/midi.html"; + webview.partition = "permissionTest"; webview.setAttribute('nodeintegration', 'on'); + setUpRequestHandler(webview, "midiSysex"); document.body.appendChild(webview); }); }); From d2ec311c557412f1be20b79c6a902415b63e90c9 Mon Sep 17 00:00:00 2001 From: ragingwind Date: Mon, 1 Feb 2016 17:06:09 +0900 Subject: [PATCH 111/688] Fix type cast of sharedApplication --- atom/browser/browser_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 1eb7fabdab0..34763435335 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -103,7 +103,7 @@ void Browser::DockSetMenu(ui::MenuModel* model) { } void Browser::DockSetIcon(const gfx::Image& image) { - [[NSApplication sharedApplication] + [[AtomApplication sharedApplication] setApplicationIconImage:image.AsNSImage()]; } From d8086b6532e48e27424e787576a69c7b12553c38 Mon Sep 17 00:00:00 2001 From: Prayag Verma Date: Mon, 1 Feb 2016 14:40:36 +0530 Subject: [PATCH 112/688] docs: fix minor typo Replace `an` with `a` --- docs/development/source-code-directory-structure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/source-code-directory-structure.md b/docs/development/source-code-directory-structure.md index cbca7108526..146edae822d 100644 --- a/docs/development/source-code-directory-structure.md +++ b/docs/development/source-code-directory-structure.md @@ -58,6 +58,6 @@ Electron * **node_modules** - Third party node modules used for building. * **out** - Temporary output directory of `ninja`. * **dist** - Temporary directory created by `script/create-dist.py` script - when creating an distribution. + when creating a distribution. * **external_binaries** - Downloaded binaries of third-party frameworks which do not support building with `gyp`. From 45eada306f84f7974f85b1a8e1ecdf1f88f28f4d Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 1 Feb 2016 15:13:49 +0530 Subject: [PATCH 113/688] add pointerlock permission type --- atom/browser/api/atom_api_web_contents.cc | 9 ++++ atom/browser/api/atom_api_web_contents.h | 4 ++ atom/browser/atom_permission_manager.cc | 41 +++++++++++++++---- atom/browser/atom_permission_manager.h | 7 +++- .../browser/web_contents_permission_helper.cc | 16 +++++++- atom/browser/web_contents_permission_helper.h | 9 +++- .../content_converter.cc | 22 ++++++---- 7 files changed, 89 insertions(+), 19 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 0a9e6c3ad6f..67af2022dbc 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -457,6 +457,15 @@ void WebContents::RequestMediaAccessPermission( permission_helper->RequestMediaAccessPermission(request, callback); } +void WebContents::RequestToLockMouse( + content::WebContents* web_contents, + bool user_gesture, + bool last_unlocked_by_target) { + auto permission_helper = + WebContentsPermissionHelper::FromWebContents(web_contents); + permission_helper->RequestPointerLockPermission(user_gesture); +} + void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) { // Do nothing, we override this method just to avoid compilation error since // there are two virtual functions named BeforeUnloadFired. diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 6587759efb9..cd6d0e7b608 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -199,6 +199,10 @@ class WebContents : public mate::TrackableObject, content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) override; + void RequestToLockMouse( + content::WebContents* web_contents, + bool user_gesture, + bool last_unlocked_by_target) override; // content::WebContentsObserver: void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; diff --git a/atom/browser/atom_permission_manager.cc b/atom/browser/atom_permission_manager.cc index c245a278c3b..e7fdaaffea7 100644 --- a/atom/browser/atom_permission_manager.cc +++ b/atom/browser/atom_permission_manager.cc @@ -8,10 +8,28 @@ #include "content/public/browser/permission_type.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" namespace atom { +namespace { + +// Must be kept in sync with atom_browser_client.cc +int kDefaultRoutingID = 2; + +bool WebContentsDestroyed(int process_id) { + auto rvh = content::RenderViewHost::FromID(process_id, kDefaultRoutingID); + if (rvh) { + auto contents = content::WebContents::FromRenderViewHost(rvh); + return contents->IsBeingDestroyed(); + } + + return true; +} + +} // namespace + AtomPermissionManager::AtomPermissionManager() : request_id_(0) { } @@ -22,8 +40,10 @@ AtomPermissionManager::~AtomPermissionManager() { void AtomPermissionManager::SetPermissionRequestHandler( const RequestHandler& handler) { if (handler.is_null() && !pending_requests_.empty()) { - for (const auto& request : pending_requests_) - request.second.Run(content::PERMISSION_STATUS_DENIED); + for (const auto& request : pending_requests_) { + if (!WebContentsDestroyed(request.second.render_process_id)) + request.second.callback.Run(content::PERMISSION_STATUS_DENIED); + } pending_requests_.clear(); } request_handler_ = handler; @@ -35,9 +55,11 @@ int AtomPermissionManager::RequestPermission( const GURL& requesting_origin, bool user_gesture, const ResponseCallback& response_callback) { + int process_id = render_frame_host->GetProcess()->GetID(); + if (permission == content::PermissionType::MIDI_SYSEX) { content::ChildProcessSecurityPolicy::GetInstance()-> - GrantSendMidiSysExMessage(render_frame_host->GetProcess()->GetID()); + GrantSendMidiSysExMessage(process_id); } if (!request_handler_.is_null()) { @@ -49,7 +71,7 @@ int AtomPermissionManager::RequestPermission( request_id_, requesting_origin, response_callback); - pending_requests_[request_id_] = callback; + pending_requests_[request_id_] = { process_id, callback }; request_handler_.Run(web_contents, permission, callback); return request_id_; } @@ -63,14 +85,19 @@ void AtomPermissionManager::OnPermissionResponse( const GURL& origin, const ResponseCallback& callback, content::PermissionStatus status) { - callback.Run(status); - pending_requests_.erase(request_id); + auto request = pending_requests_.find(request_id); + if (request != pending_requests_.end()) { + if (!WebContentsDestroyed(request->second.render_process_id)) + callback.Run(status); + pending_requests_.erase(request); + } } void AtomPermissionManager::CancelPermissionRequest(int request_id) { auto request = pending_requests_.find(request_id); if (request != pending_requests_.end()) { - request->second.Run(content::PERMISSION_STATUS_DENIED); + if (!WebContentsDestroyed(request->second.render_process_id)) + request->second.callback.Run(content::PERMISSION_STATUS_DENIED); pending_requests_.erase(request); } } diff --git a/atom/browser/atom_permission_manager.h b/atom/browser/atom_permission_manager.h index 8d8729acc66..4bebbbc84f2 100644 --- a/atom/browser/atom_permission_manager.h +++ b/atom/browser/atom_permission_manager.h @@ -65,9 +65,14 @@ class AtomPermissionManager : public content::PermissionManager { void UnsubscribePermissionStatusChange(int subscription_id) override; private: + struct RequestInfo { + int render_process_id; + ResponseCallback callback; + }; + RequestHandler request_handler_; - std::map pending_requests_; + std::map pending_requests_; int request_id_; diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index da2ad57ad97..6b017aa1342 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -66,6 +66,11 @@ void MediaAccessAllowed( callback.Run(devices, result, scoped_ptr()); } +void OnPointerLockResponse(content::WebContents* web_contents, bool allowed) { + if (web_contents) + web_contents->GotResponseToLockMouseRequest(allowed); +} + void OnPermissionResponse(const base::Callback& callback, content::PermissionStatus status) { if (status == content::PERMISSION_STATUS_GRANTED) @@ -86,12 +91,12 @@ WebContentsPermissionHelper::~WebContentsPermissionHelper() { void WebContentsPermissionHelper::RequestPermission( content::PermissionType permission, - const base::Callback& callback) { + const base::Callback& callback, + bool user_gesture) { auto rfh = web_contents_->GetMainFrame(); auto permission_manager = static_cast( web_contents_->GetBrowserContext()->GetPermissionManager()); auto origin = web_contents_->GetLastCommittedURL(); - bool user_gesture = false; permission_manager->RequestPermission( permission, rfh, origin, user_gesture, base::Bind(&OnPermissionResponse, callback)); @@ -111,4 +116,11 @@ void WebContentsPermissionHelper::RequestWebNotificationPermission( RequestPermission(content::PermissionType::NOTIFICATIONS, callback); } +void WebContentsPermissionHelper::RequestPointerLockPermission( + bool user_gesture) { + RequestPermission((content::PermissionType)(PermissionType::POINTER_LOCK), + base::Bind(&OnPointerLockResponse, web_contents_), + user_gesture); +} + } // namespace atom diff --git a/atom/browser/web_contents_permission_helper.h b/atom/browser/web_contents_permission_helper.h index 6bd2bb2559e..68682340ceb 100644 --- a/atom/browser/web_contents_permission_helper.h +++ b/atom/browser/web_contents_permission_helper.h @@ -17,11 +17,17 @@ class WebContentsPermissionHelper public: ~WebContentsPermissionHelper() override; + enum class PermissionType { + POINTER_LOCK = static_cast(content::PermissionType::NUM) + 1, + FULLSCREEN + }; + void RequestMediaAccessPermission( const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback); void RequestWebNotificationPermission( const base::Callback& callback); + void RequestPointerLockPermission(bool user_gesture); private: explicit WebContentsPermissionHelper(content::WebContents* web_contents); @@ -29,7 +35,8 @@ class WebContentsPermissionHelper void RequestPermission( content::PermissionType permission, - const base::Callback& callback); + const base::Callback& callback, + bool user_gesture = false); content::WebContents* web_contents_; diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index 15066085af0..699f101d0e4 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -8,6 +8,7 @@ #include #include "atom/browser/api/atom_api_web_contents.h" +#include "atom/browser/web_contents_permission_helper.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "content/public/browser/web_contents.h" @@ -104,16 +105,14 @@ bool Converter::FromV8( v8::Isolate* isolate, v8::Local val, content::PermissionStatus* out) { - std::string status; - if (!ConvertFromV8(isolate, val, &status)) + bool result; + if (!ConvertFromV8(isolate, val, &result)) return false; - if (status == "granted") + if (result) *out = content::PERMISSION_STATUS_GRANTED; - else if (status == "denied" || status.empty()) - *out = content::PERMISSION_STATUS_DENIED; else - return false; + *out = content::PERMISSION_STATUS_DENIED; return true; } @@ -121,6 +120,7 @@ bool Converter::FromV8( // static v8::Local Converter::ToV8( v8::Isolate* isolate, const content::PermissionType& val) { + using PermissionType = atom::WebContentsPermissionHelper::PermissionType; switch (val) { case content::PermissionType::MIDI_SYSEX: return StringToV8(isolate, "midiSysex"); @@ -137,10 +137,16 @@ v8::Local Converter::ToV8( return StringToV8(isolate, "mediaKeySystem"); case content::PermissionType::MIDI: return StringToV8(isolate, "midi"); - case content::PermissionType::DURABLE_STORAGE: default: - return StringToV8(isolate, "unknown"); + break; } + + if (val == (content::PermissionType)(PermissionType::POINTER_LOCK)) + return StringToV8(isolate, "pointerLock"); + else if (val == (content::PermissionType)(PermissionType::FULLSCREEN)) + return StringToV8(isolate, "fullscreen"); + + return StringToV8(isolate, "unknown"); } // static From b575cd0ef936531b178408eef628fc3033e57cd4 Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 1 Feb 2016 15:33:38 +0530 Subject: [PATCH 114/688] add fullscreen permission type --- atom/browser/api/atom_api_web_contents.cc | 12 ++++++++++++ atom/browser/api/atom_api_web_contents.h | 5 +++++ atom/browser/web_contents_permission_helper.cc | 6 ++++++ atom/browser/web_contents_permission_helper.h | 2 ++ docs/api/session.md | 8 ++++---- spec/webview-spec.js | 2 +- 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 67af2022dbc..d26a3593cb0 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -390,6 +390,18 @@ void WebContents::HandleKeyboardEvent( void WebContents::EnterFullscreenModeForTab(content::WebContents* source, const GURL& origin) { + auto permission_helper = + WebContentsPermissionHelper::FromWebContents(source); + auto callback = base::Bind(&WebContents::OnEnterFullscreenModeForTab, + base::Unretained(this), source, origin); + permission_helper->RequestFullscreenPermission(callback); +} + +void WebContents::OnEnterFullscreenModeForTab(content::WebContents* source, + const GURL& origin, + bool allowed) { + if (!allowed) + return; CommonWebContentsDelegate::EnterFullscreenModeForTab(source, origin); Emit("enter-html-full-screen"); } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index cd6d0e7b608..3e31d26efdf 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -133,6 +133,11 @@ class WebContents : public mate::TrackableObject, void SetAllowTransparency(bool allow); bool IsGuest() const; + // Callback triggered on permission response. + void OnEnterFullscreenModeForTab(content::WebContents* source, + const GURL& origin, + bool allowed); + // Returns the web preferences of current WebContents. v8::Local GetWebPreferences(v8::Isolate* isolate); diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index 6b017aa1342..6cade6aa352 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -102,6 +102,12 @@ void WebContentsPermissionHelper::RequestPermission( base::Bind(&OnPermissionResponse, callback)); } +void WebContentsPermissionHelper::RequestFullscreenPermission( + const base::Callback& callback) { + RequestPermission((content::PermissionType)(PermissionType::FULLSCREEN), + callback); +} + void WebContentsPermissionHelper::RequestMediaAccessPermission( const content::MediaStreamRequest& request, const content::MediaResponseCallback& response_callback) { diff --git a/atom/browser/web_contents_permission_helper.h b/atom/browser/web_contents_permission_helper.h index 68682340ceb..90ae6dff56f 100644 --- a/atom/browser/web_contents_permission_helper.h +++ b/atom/browser/web_contents_permission_helper.h @@ -22,6 +22,8 @@ class WebContentsPermissionHelper FULLSCREEN }; + void RequestFullscreenPermission( + const base::Callback& callback); void RequestMediaAccessPermission( const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback); diff --git a/docs/api/session.md b/docs/api/session.md index c70be61de89..724dab390d2 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -293,22 +293,22 @@ myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, c * `handler` Function * `webContents` Object - [WebContents](web-contents.md) requesting the permission. - * `permission` String - Enum of 'media', 'geolocation', 'notifications', 'midiSysex'. + * `permission` String - Enum of 'media', 'geolocation', 'notifications', 'midiSysex', 'pointerLock', 'fullscreen'. * `callback` Function - Allow or deny the permission. Sets the handler which can be used to respond to permission requests for the `session`. -Calling `callback('granted')` will allow the permission and `callback('denied')` will reject it. +Calling `callback(true)` will allow the permission and `callback(false)` will reject it. ```javascript session.fromPartition(partition).setPermissionRequestHandler(function(webContents, permission, callback) { if (webContents.getURL() === host) { if (permission == "notifications") { - callback(); // denied. + callback(false); // denied. return; } } - callback('granted'); + callback(true); }); ``` diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 6a386604676..cac5fb56b44 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -639,7 +639,7 @@ describe(' tag', function() { var listener = function(webContents, permission, callback) { if (webContents.getId() === webview.getId() ) { assert.equal(permission, requested_permission); - callback("denied"); + callback(false); } }; session.fromPartition(webview.partition).setPermissionRequestHandler(listener); From ff5fb512b885b4e5ac4dfb16e1a54c82318a8329 Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 1 Feb 2016 17:45:53 +0530 Subject: [PATCH 115/688] use mediastreamdevicescontroller from brightray to enumerate available devices --- atom/browser/api/atom_api_session.cc | 2 +- .../browser/web_contents_permission_helper.cc | 50 +++---------------- 2 files changed, 7 insertions(+), 45 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index b0c99141f75..b9032409e46 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -400,7 +400,7 @@ void Session::SetCertVerifyProc(v8::Local val, } void Session::SetPermissionRequestHandler(v8::Local val, - mate::Arguments* args) { + mate::Arguments* args) { AtomPermissionManager::RequestHandler handler; if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) { args->ThrowError("Must pass null or function"); diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index 6cade6aa352..f5ce414dd2c 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -7,8 +7,8 @@ #include #include "atom/browser/atom_permission_manager.h" +#include "brightray/browser/media/media_stream_devices_controller.h" #include "content/public/browser/browser_context.h" -#include "content/public/browser/media_capture_devices.h" #include "content/public/browser/render_process_host.h" DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::WebContentsPermissionHelper); @@ -17,53 +17,15 @@ namespace atom { namespace { -const content::MediaStreamDevice* FindDeviceWithId( - const content::MediaStreamDevices& devices, - const std::string& device_id) { - if (device_id.empty()) - return &(*devices.begin()); - for (const auto& iter : devices) - if (iter.id == device_id) - return &(iter); - return nullptr; -} - void MediaAccessAllowed( const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback, bool allowed) { - if (!allowed) { - callback.Run(content::MediaStreamDevices(), - content::MEDIA_DEVICE_PERMISSION_DENIED, - scoped_ptr()); - return; - } - - content::MediaStreamDevices devices; - content::MediaStreamRequestResult result = content::MEDIA_DEVICE_NO_HARDWARE; - - if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) { - const content::MediaStreamDevices& audio_devices = - content::MediaCaptureDevices::GetInstance()->GetAudioCaptureDevices(); - const content::MediaStreamDevice* audio_device = - FindDeviceWithId(audio_devices, request.requested_audio_device_id); - if (audio_device) - devices.push_back(*audio_device); - } - - if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) { - const content::MediaStreamDevices& video_devices = - content::MediaCaptureDevices::GetInstance()->GetVideoCaptureDevices(); - const content::MediaStreamDevice* video_device = - FindDeviceWithId(video_devices, request.requested_video_device_id); - if (video_device) - devices.push_back(*video_device); - } - - if (!devices.empty()) - result = content::MEDIA_DEVICE_OK; - - callback.Run(devices, result, scoped_ptr()); + brightray::MediaStreamDevicesController controller(request, callback); + if (allowed) + controller.Accept(); + else + controller.Deny(content::MEDIA_DEVICE_PERMISSION_DENIED); } void OnPointerLockResponse(content::WebContents* web_contents, bool allowed) { From 159fb857f4f4c660d2fbdb25db70a6573c1eb957 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 1 Feb 2016 21:05:29 +0800 Subject: [PATCH 116/688] No need to override RequestToLockMouse in CommonWebContentsDelegate --- atom/browser/common_web_contents_delegate.cc | 7 ------- atom/browser/common_web_contents_delegate.h | 3 --- 2 files changed, 10 deletions(-) diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index 72a664f8cd0..1fd6f782de5 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -181,13 +181,6 @@ content::WebContents* CommonWebContentsDelegate::OpenURLFromTab( return source; } -void CommonWebContentsDelegate::RequestToLockMouse( - content::WebContents* web_contents, - bool user_gesture, - bool last_unlocked_by_target) { - GetWebContents()->GotResponseToLockMouseRequest(true); -} - bool CommonWebContentsDelegate::CanOverscrollContent() const { return false; } diff --git a/atom/browser/common_web_contents_delegate.h b/atom/browser/common_web_contents_delegate.h index ee18f36660e..828729d795d 100644 --- a/atom/browser/common_web_contents_delegate.h +++ b/atom/browser/common_web_contents_delegate.h @@ -59,9 +59,6 @@ class CommonWebContentsDelegate content::WebContents* OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) override; - void RequestToLockMouse(content::WebContents* web_contents, - bool user_gesture, - bool last_unlocked_by_target) override; bool CanOverscrollContent() const override; content::JavaScriptDialogManager* GetJavaScriptDialogManager( content::WebContents* source) override; From 7d68ca21c8453c3a523432a22ec0d01cf39f4743 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 1 Feb 2016 21:09:12 +0800 Subject: [PATCH 117/688] No need of DefaultWebContentsDelegate --- atom/browser/common_web_contents_delegate.h | 4 ++-- vendor/brightray | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/browser/common_web_contents_delegate.h b/atom/browser/common_web_contents_delegate.h index 828729d795d..83ef2850bd9 100644 --- a/atom/browser/common_web_contents_delegate.h +++ b/atom/browser/common_web_contents_delegate.h @@ -9,10 +9,10 @@ #include #include -#include "brightray/browser/default_web_contents_delegate.h" #include "brightray/browser/inspectable_web_contents_impl.h" #include "brightray/browser/inspectable_web_contents_delegate.h" #include "brightray/browser/inspectable_web_contents_view_delegate.h" +#include "content/public/browser/web_contents_delegate.h" namespace atom { @@ -21,7 +21,7 @@ class NativeWindow; class WebDialogHelper; class CommonWebContentsDelegate - : public brightray::DefaultWebContentsDelegate, + : public content::WebContentsDelegate, public brightray::InspectableWebContentsDelegate, public brightray::InspectableWebContentsViewDelegate { public: diff --git a/vendor/brightray b/vendor/brightray index ea6011bc960..2a5cd7178b6 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit ea6011bc9607f321258bf93e510f56f031973230 +Subproject commit 2a5cd7178b641de91ca6eb0bca826fea588f923a From 045e42a10c976c410d7ed194c59bb49917fbfe49 Mon Sep 17 00:00:00 2001 From: Robo Date: Tue, 2 Feb 2016 00:26:37 +0530 Subject: [PATCH 118/688] fix crash when default download is canceled --- atom/browser/api/atom_api_session.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index b9032409e46..37909c580ea 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -296,10 +296,8 @@ void Session::OnDownloadCreated(content::DownloadManager* manager, "will-download", DownloadItem::Create(isolate(), item), api::WebContents::CreateFrom(isolate(), web_contents)); - if (prevent_default) { + if (prevent_default) item->Cancel(true); - item->Remove(); - } } void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) { From 035c1dd5a1651a162e7f2d5533ba2b503efaa7ec Mon Sep 17 00:00:00 2001 From: yan Date: Mon, 1 Feb 2016 11:46:02 -0800 Subject: [PATCH 119/688] Fix 'user strict' typo --- atom/renderer/lib/init.js | 2 +- atom/renderer/lib/web-view/web-view.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/renderer/lib/init.js b/atom/renderer/lib/init.js index d25dbfbbbb8..18be7b08011 100644 --- a/atom/renderer/lib/init.js +++ b/atom/renderer/lib/init.js @@ -1,4 +1,4 @@ -'user strict'; +'use strict'; const events = require('events'); const path = require('path'); diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 4aa4632d35e..5257f0c12f9 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -1,4 +1,4 @@ -'user strict'; +'use strict'; const deprecate = require('electron').deprecate; const webFrame = require('electron').webFrame; From ce2ea963b9f1da94fbbd167d907704d7417756e6 Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 1 Feb 2016 19:03:23 +0530 Subject: [PATCH 120/688] session: api to clear host resolver cache --- atom/browser/api/atom_api_session.cc | 25 +++++++++++++++++++++++++ atom/browser/api/atom_api_session.h | 1 + docs/api/session.md | 6 ++++++ 3 files changed, 32 insertions(+) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index b9032409e46..e5c5198f034 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -36,6 +36,7 @@ #include "native_mate/object_template_builder.h" #include "net/base/load_flags.h" #include "net/disk_cache/disk_cache.h" +#include "net/dns/host_cache.h" #include "net/proxy/proxy_service.h" #include "net/proxy/proxy_config_service_fixed.h" #include "net/url_request/url_request_context.h" @@ -271,6 +272,19 @@ void SetProxyInIO(net::URLRequestContextGetter* getter, RunCallbackInUI(callback); } +void ClearHostResolverCacheInIO( + const scoped_refptr& context_getter, + const base::Closure& callback) { + auto request_context = context_getter->GetURLRequestContext(); + auto cache = request_context->host_resolver()->GetHostCache(); + if (cache) { + cache->clear(); + DCHECK_EQ(0u, cache->size()); + if (!callback.is_null()) + RunCallbackInUI(callback); + } +} + } // namespace Session::Session(AtomBrowserContext* browser_context) @@ -411,6 +425,16 @@ void Session::SetPermissionRequestHandler(v8::Local val, permission_manager->SetPermissionRequestHandler(handler); } +void Session::ClearHostResolverCache(mate::Arguments* args) { + base::Closure callback; + args->GetNext(&callback); + + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&ClearHostResolverCacheInIO, + make_scoped_refptr(browser_context_->GetRequestContext()), + callback)); +} + v8::Local Session::Cookies(v8::Isolate* isolate) { if (cookies_.IsEmpty()) { auto handle = atom::api::Cookies::Create(isolate, browser_context()); @@ -464,6 +488,7 @@ void Session::BuildPrototype(v8::Isolate* isolate, .SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc) .SetMethod("setPermissionRequestHandler", &Session::SetPermissionRequestHandler) + .SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache) .SetProperty("cookies", &Session::Cookies) .SetProperty("webRequest", &Session::WebRequest); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index efcafbfe5e3..02d8ba5cdec 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -78,6 +78,7 @@ class Session: public mate::TrackableObject, void SetCertVerifyProc(v8::Local proc, mate::Arguments* args); void SetPermissionRequestHandler(v8::Local val, mate::Arguments* args); + void ClearHostResolverCache(mate::Arguments* args); v8::Local Cookies(v8::Isolate* isolate); v8::Local WebRequest(v8::Isolate* isolate); diff --git a/docs/api/session.md b/docs/api/session.md index 8b0fa4ed550..ded94a1c696 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -313,6 +313,12 @@ session.fromPartition(partition).setPermissionRequestHandler(function(webContent }); ``` +#### `ses.clearHostResolverCache([callback])` + +* `callback` Function (optional) - Called when operation is done. + +Clears the host resolver cache. + #### `ses.webRequest` The `webRequest` API set allows to intercept and modify contents of a request at From 1a3c01efca7d2d98238a4d45c0356773ba0b745a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 2 Feb 2016 10:11:04 +0800 Subject: [PATCH 121/688] Update native-mate for #4307 --- vendor/native_mate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/native_mate b/vendor/native_mate index a3dcf8ced66..26520c5cf4b 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit a3dcf8ced663e974ac94ad5e50a1d25a43995a9d +Subproject commit 26520c5cf4b6a60da2c5cba971393f94b82f5939 From 683f9745ad2a2ac0de7b401d9fa0d412b79322d6 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Tue, 2 Feb 2016 03:58:51 +0900 Subject: [PATCH 122/688] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 8 +++++++ docs-translations/ko-KR/api/menu.md | 6 ++++++ docs-translations/ko-KR/api/session.md | 24 +++++++++++++++++++++ docs-translations/ko-KR/api/web-contents.md | 22 +++++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index cfcd4ee3aab..ec4cb74c253 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -252,6 +252,14 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입 `beforeunload` 이벤트 핸들러에서 `false`를 반환했을 때 윈도우 종료가 취소 될 수 있습니다. +### `app.hide()` _OS X_ + +최소화를 하지 않고 어플리케이션의 모든 윈도우들을 숨깁니다. + +### `app.show()` _OS X_ + +숨긴 어플리케이션 윈도우들을 다시 보이게 만듭니다. 자동으로 포커스되지 않습니다. + ### `app.exit(exitCode)` * `exitCode` Integer diff --git a/docs-translations/ko-KR/api/menu.md b/docs-translations/ko-KR/api/menu.md index a2d5b8d7a63..347ea880dce 100644 --- a/docs-translations/ko-KR/api/menu.md +++ b/docs-translations/ko-KR/api/menu.md @@ -293,6 +293,11 @@ OS X에선 지정한 어플리케이션 메뉴에 상관없이 메뉴의 첫번 이름이 됩니다. 어플리케이션 이름을 변경하려면 앱 번들내의 `Info.plist` 파일을 수정해야 합니다. 자세한 내용은 [About Information Property List Files][AboutInformationPropertyListFiles] 문서를 참고하세요. +## 지정한 브라우저 윈도우에 메뉴 설정 (*Linux* *Windows*) + +브라우저 윈도우의 [`setMenu` 메서드][setMenu]는 어떤 브라우저 윈도우의 메뉴를 설정할 +수 있습니다. + ## 메뉴 아이템 위치 `Menu.buildFromTemplate`로 메뉴를 만들 때 `position`과 `id`를 사용해서 아이템의 @@ -367,3 +372,4 @@ OS X에선 지정한 어플리케이션 메뉴에 상관없이 메뉴의 첫번 ``` [AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html +[setMenu]: https://github.com/atom/electron/blob/master/docs/api/browser-window.md#winsetmenumenu-linux-windows diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index de5c08848cf..59eceb05a7a 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -288,6 +288,30 @@ myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, c callback(false); }); ``` +#### `ses.setPermissionRequestHandler(handler)` + +* `handler` Function + * `webContents` Object - [WebContents](web-contents.md) 권한을 요청. + * `permission` String - 'media', 'geolocation', 'notifications', + 'midiSysex'의 나열. + * `callback` Function - 권한 허용 및 거부. + +`session`의 권한 요청에 응답을 하는데 사용하는 핸들러를 설정합니다. +`callback('granted')`를 호출하면 권한 제공을 허용하고 `callback('denied')`를 +호출하면 권한 제공을 거부합니다. + +```javascript +session.fromPartition(partition).setPermissionRequestHandler(function(webContents, permission, callback) { + if (webContents.getURL() === host) { + if (permission == "notifications") { + callback(); // 거부됨. + return; + } + } + + callback('granted'); +}); +``` #### `ses.webRequest` diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 4d688a40944..3f9a7daaaa7 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -278,6 +278,28 @@ Returns: ``` +### Event: 'cursor-changed' + +Returns: + +* `event` Event +* `type` String +* `image` NativeImage (optional) +* `scale` Float (optional) + +커서 타입이 변경될 때 발생하는 이벤트입니다. `type` 매개변수는 다음 값이 될 수 있습니다: +`default`, `crosshair`, `pointer`, `text`, `wait`, `help`, `e-resize`, `n-resize`, +`ne-resize`, `nw-resize`, `s-resize`, `se-resize`, `sw-resize`, `w-resize`, +`ns-resize`, `ew-resize`, `nesw-resize`, `nwse-resize`, `col-resize`, +`row-resize`, `m-panning`, `e-panning`, `n-panning`, `ne-panning`, `nw-panning`, +`s-panning`, `se-panning`, `sw-panning`, `w-panning`, `move`, `vertical-text`, +`cell`, `context-menu`, `alias`, `progress`, `nodrop`, `copy`, `none`, +`not-allowed`, `zoom-in`, `zoom-out`, `grab`, `grabbing`, `custom`. + +만약 `type` 매개변수가 `custom` 이고 `image` 매개변수가 `NativeImage`를 통한 커스텀 +커서를 지정했을 때, 해당 이미지로 커서가 변경됩니다. 또한 `scale` 매개변수는 이미지의 +크기를 조정합니다. + ## Instance Methods `webContents`객체는 다음과 같은 인스턴스 메서드들을 가지고 있습니다. From aadb131bc7150e61dea1b76245fdee67e409ccc5 Mon Sep 17 00:00:00 2001 From: Rafael Dantas Date: Mon, 1 Feb 2016 22:43:28 -0200 Subject: [PATCH 123/688] Update Portuguse docs translation --- docs-translations/pt-BR/README.md | 9 +++++++- .../pt-BR/tutorial/supported-platforms.md | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 docs-translations/pt-BR/tutorial/supported-platforms.md diff --git a/docs-translations/pt-BR/README.md b/docs-translations/pt-BR/README.md index f458e51da8f..05fedfeb438 100644 --- a/docs-translations/pt-BR/README.md +++ b/docs-translations/pt-BR/README.md @@ -6,9 +6,14 @@ documentação na lista de [versões disponíveis](http://electron.atom.io/docs/ ou se você estiver usando a interface do GitHub, abra o *dropdown* "Switch branches/tags" e selecione a *tag* que corresponde à sua versão. +## FAQ + +Existem muitas perguntas comuns que são feitas, verifique antes de criar uma issue. +* [Electron FAQ](../../docs/faq/electron-faq.md) + ## Guias -* [Platformas Suportadas](../../tutorial/supported-platforms.md) +* [Plataformas Suportadas](tutorial/supported-platforms.md) * [Distribuição de Aplicações](tutorial/application-distribution.md) * [Guia de Submissão da Mac App Store](../../tutorial/mac-app-store-submission-guide.md) * [Empacotamento da Aplicação](tutorial/application-packaging.md) @@ -17,6 +22,7 @@ selecione a *tag* que corresponde à sua versão. * [Usando Selenium e WebDriver](../../docs/tutorial/using-selenium-and-webdriver.md) * [Extensão DevTools](../../docs/tutorial/devtools-extension.md) * [Usando o Plugin Pepper Flash](tutorial/using-pepper-flash-plugin.md) +* [Usando o Plugin Widevine CDM](../../tutorial/using-widevine-cdm-plugin.md) ## Tutoriais @@ -58,6 +64,7 @@ selecione a *tag* que corresponde à sua versão. ### Módulos para o Processo Renderizador: +* [DesktopCapturer](../../docs/api/desktop-capturer) * [ipcRenderer](../../docs/api/ipc-renderer.md) * [remote](../../docs/api/remote.md) * [webFrame](../../docs/api/web-frame.md) diff --git a/docs-translations/pt-BR/tutorial/supported-platforms.md b/docs-translations/pt-BR/tutorial/supported-platforms.md new file mode 100644 index 00000000000..0fc42179bb9 --- /dev/null +++ b/docs-translations/pt-BR/tutorial/supported-platforms.md @@ -0,0 +1,22 @@ +# Plataformas Suportadas + +As plataformas suportadas por Electron são: + +### OS X + +Somente binarios em 64bit são construidos para OS X e a versão mínima suportada é OS X 10.9. + +### Windows +Suporte para Windows 7 ou superior, versões anteriores não são suportados (e não ira funcionar) + + Binarios em `x86` e `amd64` (x64) são construidos para Windows. Atencão: Versão `ARM` do Windows não é suportada agora. + +### Linux +Binario pré-construido `ia32`(`i686`) e binario `x64`(`amd64`) são construidas no Ubuntu 12.04, binario `arm` está construido contra ARM v7 com hard-float ABI e NEION para Debian Wheezy. + +Se o pré-compilador poderá ser executado por uma distribuição, depende se a distruibuicão inclui as blibliotecas que o Eletron está vinculando na plataforma de construcão, por este motivo apenas Ubuntu 12.04 é garantido para funcionar corretamente, mas as seguintes distribuições foram verificados com o pre-compilador: + + +* Ubuntu 12.04 ou superior +* Fedora 21 +* Debian 8 From c69971c381412e7ffc44d317c5a7b483556e2820 Mon Sep 17 00:00:00 2001 From: ZhangYu Date: Tue, 2 Feb 2016 13:59:02 +0800 Subject: [PATCH 124/688] Update app.md --- docs-translations/zh-CN/api/app.md | 229 +++++++++++++++++++++++++---- 1 file changed, 200 insertions(+), 29 deletions(-) diff --git a/docs-translations/zh-CN/api/app.md b/docs-translations/zh-CN/api/app.md index 03eb083dfa6..448a5a373e9 100644 --- a/docs-translations/zh-CN/api/app.md +++ b/docs-translations/zh-CN/api/app.md @@ -58,10 +58,14 @@ app.on('window-all-closed', function() { 和 `window-all-closed` 事件的区别。 ### 事件: 'quit' +返回: + +* `event` 事件 +* `exitCode` 整数 当应用程序正在退出时触发。 -### 事件: 'open-file' +### 事件: 'open-file' _OS X_ 返回: @@ -73,8 +77,8 @@ app.on('window-all-closed', function() { 请确认在应用启动的时候(甚至在 `ready` 事件被触发前)就对 `open-file` 事件进行监听,以处理这种情况。 如果你想处理这个事件,你应该调用 `event.preventDefault()` 。 - -### 事件: 'open-url' +在 Windows系统中, 你需要通过解析 process.argv 来获取文件路径。 +### 事件: 'open-url' _OS X_ 返回: @@ -121,32 +125,89 @@ app.on('window-all-closed', function() { 当一个 [浏览器窗口](browser-window.md) 被创建的时候触发。 -### 事件: 'select-certificate' - -当一个客户端认证被请求的时候被触发。 +### 事件: 'certificate-error' 返回: * `event` 事件 -* `webContents` [web组件](browser-window.md#class-webcontents) +* `webContents` [web组件](web-contents.md) * `url` 字符串 * `certificateList` 对象 * `data` PEM 编码数据 * `issuerName` 发行者的公有名称 * `callback` 函数 +Emitted when failed to verify the `certificate` for `url`, to trust the +certificate you should prevent the default behavior with +`event.preventDefault()` and call `callback(true)`. + +```javascript +session.on('certificate-error', function(event, webContents, url, error, certificate, callback) { + if (url == "https://github.com") { + // Verification logic. + event.preventDefault(); + callback(true); + } else { + callback(false); + } +}); +``` + +### 事件: 'select-client-certificate' + + +返回: + +* `event` 事件 +* `webContents` [web组件](web-contents.md) +* `url` 字符串 +* `certificateList` 对象 + * `data` PEM 编码数据 + * `issuerName` 发行者的公有名称 +* `callback` 函数 + +当一个客户端认证被请求的时候被触发。 + +The `url` corresponds to the navigation entry requesting the client certificate +and `callback` needs to be called with an entry filtered from the list. +Using `event.preventDefault()` prevents the application from using the first +certificate from the store. ```javascript app.on('select-certificate', function(event, host, url, list, callback) { event.preventDefault(); callback(list[0]); }) ``` +### Event: 'login' -The `url` corresponds to the navigation entry requesting the client certificate -and `callback` needs to be called with an entry filtered from the list. -Using `event.preventDefault()` prevents the application from using the first -certificate from the store. +Returns: +* `event` Event +* `webContents` [Web组件](web-contents.md) +* `request` Object + * `method` String + * `url` URL + * `referrer` URL +* `authInfo` Object + * `isProxy` Boolean + * `scheme` String + * `host` String + * `port` Integer + * `realm` String +* `callback` Function + +当 `webContents` 要做验证时被触发。 + +The default behavior is to cancel all authentications, to override this you +should prevent the default behavior with `event.preventDefault()` and call +`callback(username, password)` with the credentials. + +```javascript +app.on('login', function(event, webContents, request, authInfo, callback) { + event.preventDefault(); + callback('username', 'secret'); +}) +``` ### 事件: 'gpu-process-crashed' 当GPU进程崩溃时触发。 @@ -164,6 +225,23 @@ certificate from the store. 这个方法保证了所有的 `beforeunload` 和 `unload` 事件处理器被正确执行。会存在一个窗口被 `beforeunload` 事件处理器返回 `false` 取消退出的可能性。 +### `app.hide()` _OS X_ + +隐藏所有的应用窗口,不是最小化. + +### `app.show()` _OS X_ + +隐藏后重新显示所有的窗口,不会自动选中他们。 + +### `app.exit(exitCode)` + +* `exitCode` 整数 + +带着`exitCode`退出应用. + +所有的窗口会被立刻关闭,不会询问用户。`before-quit` 和 `will-quit` 这2个事件不会被触发 + + ### `app.getAppPath()` 返回当前应用所在的文件路径。 @@ -182,15 +260,15 @@ certificate from the store. * `$XDG_CONFIG_HOME` or `~/.config` Linux 中 * `~/Library/Application Support` OS X 中 * `userData` 储存你应用程序设置文件的文件夹,默认是 `appData` 文件夹附加应用的名称。 -* `cache` 所有用户应用程序缓存的文件夹,默认对应: - * `%APPDATA%` Windows 中 (没有一个通用的缓存位置) - * `$XDG_CACHE_HOME` 或 `~/.cache` Linux 中 - * `~/Library/Caches` OS X 中 -* `userCache` 用于存放应用程序缓存的文件夹,默认是 `cache` 文件夹附加应用的名称。 * `temp` 临时文件夹。 -* `userDesktop` 当前用户的桌面文件夹。 -* `exe` 当前的可执行文件。 -* `module` `libchromiumcontent` 库。 +* `exe` 当前的可执行文件 +* `module` `libchromiumcontent` 库. +* `desktop` 当前用户的桌面文件夹。 +* `documents` "我的文件夹"的路径. +* `downloads` 用户下载目录的路径. +* `music` 用户音乐目录的路径. +* `pictures` 用户图片目录的路径. +* `videos` 用户视频目录的路径. ### `app.setPath(name, path)` @@ -201,7 +279,7 @@ certificate from the store. 如果这个路径指向的文件夹不存在,这个文件夹将会被这个方法创建。 如果错误则抛出 `Error` 。 -你只可以指向 `app.getPath` 中定义过 `name` 的路径。You can only override paths of a `name` defined in `app.getPath`. +你只可以指向 `app.getPath` 中定义过 `name` 的路径。 默认情况下,网页的 cookie 和缓存都会储存在 `userData` 文件夹。 如果你想要改变这个位置,你需要在 `app` 模块中的 `ready` 事件被触发之前重写 `userData` 的路径。 @@ -220,16 +298,11 @@ certificate from the store. ### `app.getLocale()` -返回当前应用程序的位置。 +返回当前应用程序的语言种类。 -### `app.resolveProxy(url, callback)` -* `url` URL -* `callback` 函数 -为 `url` 解析代理信息。 `callback` 在请求被执行之后将会被 `callback(proxy)` 调用。 - -### `app.addRecentDocument(path)` +### `app.addRecentDocument(path)` _OS X_ _Windows_ * `path` 字符串 @@ -237,7 +310,7 @@ certificate from the store. 这个列表由操作系统进行管理。在 Windows 中您可以通过任务条进行访问,在 OS X 中你可以通过dock 菜单进行访问。 -### `app.clearRecentDocuments()` +### `app.clearRecentDocuments()` _OS X_ _Windows_ 清除最近访问的文档列表。 @@ -257,6 +330,103 @@ certificate from the store. * `iconPath` 字符串 - JumpList 中显示的 icon 的绝对路径,可以是一个任意包含一个icon的资源文件。你通常可以通过指明 `process.execPath` 来显示程序中的icon。 * `iconIndex` 整数 - icon文件中的icon目录。如果一个icon文件包括了两个或多个icon,就需要设置这个值以确定icon。如果一个文件仅包含一个icon,那么这个值为0。 +### `app.allowNTLMCredentialsForAllDomains(allow)` + +* `allow` Boolean + +Dynamically sets whether to always send credentials for HTTP NTLM or Negotiate +authentication - normally, Electron will only send NTLM/Kerberos credentials for +URLs that fall under "Local Intranet" sites (i.e. are in the same domain as you). +However, this detection often fails when corporate networks are badly configured, +so this lets you co-opt this behavior and enable it for all URLs. +### `app.makeSingleInstance(callback)` + +* `callback` Function + +This method makes your application a Single Instance Application - instead of +allowing multiple instances of your app to run, this will ensure that only a +single instance of your app is running, and other instances signal this +instance and exit. + +`callback` will be called with `callback(argv, workingDirectory)` when a second +instance has been executed. `argv` is an Array of the second instance's command +line arguments, and `workingDirectory` is its current working directory. Usually +applications respond to this by making their primary window focused and +non-minimized. + +The `callback` is guaranteed to be executed after the `ready` event of `app` +gets emitted. + +This method returns `false` if your process is the primary instance of the +application and your app should continue loading. And returns `true` if your +process has sent its parameters to another instance, and you should immediately +quit. + +On OS X the system enforces single instance automatically when users try to open +a second instance of your app in Finder, and the `open-file` and `open-url` +events will be emitted for that. However when users start your app in command +line the system's single instance machanism will be bypassed and you have to +use this method to ensure single instance. + +An example of activating the window of primary instance when a second instance +starts: + +```js +var myWindow = null; + +var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) { + // Someone tried to run a second instance, we should focus our window. + if (myWindow) { + if (myWindow.isMinimized()) myWindow.restore(); + myWindow.focus(); + } + return true; +}); + +if (shouldQuit) { + app.quit(); + return; +} + +// Create myWindow, load the rest of the app, etc... +app.on('ready', function() { +}); +``` +### `app.setAppUserModelId(id)` _Windows_ + +* `id` String + +改变 [Application User Model ID][app-user-model-id] 的 `id`. + +### `app.isAeroGlassEnabled()` _Windows_ + +This method returns `true` if [DWM composition](https://msdn.microsoft.com/en-us/library/windows/desktop/aa969540.aspx) +(Aero Glass) is enabled, and `false` otherwise. You can use it to determine if +you should create a transparent window or not (transparent windows won't work +correctly when DWM composition is disabled). + +Usage example: + +```js +let browserOptions = {width: 1000, height: 800}; + +// Make the window transparent only if the platform supports it. +if (process.platform !== 'win32' || app.isAeroGlassEnabled()) { + browserOptions.transparent = true; + browserOptions.frame = false; +} + +// Create the window. +win = new BrowserWindow(browserOptions); + +// Navigate. +if (browserOptions.transparent) { + win.loadURL('file://' + __dirname + '/index.html'); +} else { + // No transparency, so we load a fallback that uses basic styles. + win.loadURL('file://' + __dirname + '/fallback.html'); +} +``` ### `app.commandLine.appendSwitch(switch[, value])` 通过可选的参数 `value` 给 Chromium 命令行中添加一个开关。 @@ -312,4 +482,5 @@ Append a switch (with optional `value`) to Chromium's command line. 设置应用的 [dock 菜单][dock-menu]. [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 -[tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks \ No newline at end of file +[tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx From 2819af9586197e592bda2cfb192ad7150839aed9 Mon Sep 17 00:00:00 2001 From: Robo Date: Tue, 2 Feb 2016 15:54:51 +0530 Subject: [PATCH 125/688] fix lifetime of downloadItem class when defaultdownload canceled --- atom/browser/api/atom_api_download_item.cc | 18 ++++++-- atom/browser/api/atom_api_download_item.h | 2 + atom/browser/api/atom_api_session.cc | 8 +++- docs/api/session.md | 3 +- spec/api-session-spec.js | 52 ++++++++++++++++++++-- spec/static/main.js | 44 +++++++++++------- 6 files changed, 100 insertions(+), 27 deletions(-) diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index f186821e7d3..c3beee5bb09 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -12,6 +12,7 @@ #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/node_includes.h" #include "base/memory/linked_ptr.h" +#include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" #include "native_mate/dictionary.h" #include "net/base/filename_util.h" @@ -70,8 +71,17 @@ DownloadItem::DownloadItem(content::DownloadItem* download_item) : } DownloadItem::~DownloadItem() { - if (download_item_) - OnDownloadDestroyed(download_item_); + Destroy(download_item_); +} + +void DownloadItem::Destroy(content::DownloadItem* item) { + if (item) { + OnDownloadDestroyed(item); + MarkDestroyed(); + + // Destroy the native class in next tick. + base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure()); + } } void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) { @@ -79,8 +89,8 @@ void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) { } void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download_item) { - download_item_->RemoveObserver(this); - auto iter = g_download_item_objects.find(download_item_->GetId()); + download_item->RemoveObserver(this); + auto iter = g_download_item_objects.find(download_item->GetId()); if (iter != g_download_item_objects.end()) g_download_item_objects.erase(iter); download_item_ = nullptr; diff --git a/atom/browser/api/atom_api_download_item.h b/atom/browser/api/atom_api_download_item.h index 471913c2266..af388a56751 100644 --- a/atom/browser/api/atom_api_download_item.h +++ b/atom/browser/api/atom_api_download_item.h @@ -36,6 +36,8 @@ class DownloadItem : public mate::TrackableObject, static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); + void Destroy(content::DownloadItem* download_item); + protected: explicit DownloadItem(content::DownloadItem* download_item); ~DownloadItem(); diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 37909c580ea..f0bd739168f 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -292,12 +292,16 @@ void Session::OnDownloadCreated(content::DownloadManager* manager, auto web_contents = item->GetWebContents(); if (SavePageHandler::IsSavePageTypes(item->GetMimeType())) return; + auto download_item_handle = DownloadItem::Create(isolate(), item); bool prevent_default = Emit( "will-download", - DownloadItem::Create(isolate(), item), + download_item_handle, api::WebContents::CreateFrom(isolate(), web_contents)); - if (prevent_default) + if (prevent_default) { item->Cancel(true); + download_item_handle->Destroy(item); + item->Remove(); + } } void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) { diff --git a/docs/api/session.md b/docs/api/session.md index 8b0fa4ed550..255f6a06604 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -60,7 +60,8 @@ The following events are available on instances of `Session`: Emitted when Electron is about to download `item` in `webContents`. -Calling `event.preventDefault()` will cancel the download. +Calling `event.preventDefault()` will cancel the download and `item` will not be +available from next tick of the process. ```javascript session.defaultSession.on('will-download', function(event, item, webContents) { diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index 93402047390..fe27f932cee 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -144,6 +144,50 @@ describe('session module', function() { }); }); }); + + describe('session will-download event', function() { + var w = null; + + beforeEach(function() { + w = new BrowserWindow({ + show: false, + width: 400, + height: 400 + }); + }); + afterEach(function() { + return w.destroy(); + }); + + it('can cancel default download behavior', function(done) { + const mockFile = new Buffer(1024); + const contentDisposition = 'inline; filename="mockFile.txt"'; + const downloadServer = http.createServer(function(req, res) { + res.writeHead(200, { + 'Content-Length': mockFile.length, + 'Content-Type': 'application/plain', + 'Content-Disposition': contentDisposition + }); + res.end(mockFile); + downloadServer.close(); + }); + + downloadServer.listen(0, '127.0.0.1', function() { + const port = downloadServer.address().port; + const url = "http://127.0.0.1:" + port + '/'; + + ipcRenderer.sendSync('set-download-option', false, true); + w.loadURL(url); + ipcRenderer.once('download-error', function(event, downloadUrl, filename, error) { + assert.equal(downloadUrl, url); + assert.equal(filename, 'mockFile.txt'); + assert.equal(error, 'Object has been destroyed'); + done(); + }); + }); + }); + }); + return describe('DownloadItem', function() { var assertDownload, contentDisposition, downloadFilePath, downloadServer, mockPDF; mockPDF = new Buffer(1024 * 1024 * 5); @@ -173,7 +217,7 @@ describe('session module', function() { return downloadServer.listen(0, '127.0.0.1', function() { var port; port = downloadServer.address().port; - ipcRenderer.sendSync('set-download-option', false); + ipcRenderer.sendSync('set-download-option', false, false); w.loadURL(url + ":" + port); return ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { assertDownload(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port); @@ -185,7 +229,7 @@ describe('session module', function() { return downloadServer.listen(0, '127.0.0.1', function() { var port, webview; port = downloadServer.address().port; - ipcRenderer.sendSync('set-download-option', false); + ipcRenderer.sendSync('set-download-option', false, false); webview = new WebView; webview.src = "file://" + fixtures + "/api/blank.html"; webview.addEventListener('did-finish-load', function() { @@ -199,11 +243,11 @@ describe('session module', function() { return document.body.appendChild(webview); }); }); - return it('can cancel download', function(done) { + it('can cancel download', function(done) { return downloadServer.listen(0, '127.0.0.1', function() { var port; port = downloadServer.address().port; - ipcRenderer.sendSync('set-download-option', true); + ipcRenderer.sendSync('set-download-option', true, false); w.loadURL(url + ":" + port + "/"); return ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { assert.equal(state, 'cancelled'); diff --git a/spec/static/main.js b/spec/static/main.js index 4419a2219b0..13d2dd6a6e1 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -102,23 +102,35 @@ app.on('ready', function() { // For session's download test, listen 'will-download' event in browser, and // reply the result to renderer for verifying var downloadFilePath = path.join(__dirname, '..', 'fixtures', 'mock.pdf'); - ipcMain.on('set-download-option', function(event, need_cancel) { - window.webContents.session.once('will-download', - function(e, item, webContents) { - item.setSavePath(downloadFilePath); - item.on('done', function(e, state) { - window.webContents.send('download-done', - state, - item.getURL(), - item.getMimeType(), - item.getReceivedBytes(), - item.getTotalBytes(), - item.getContentDisposition(), - item.getFilename()); - }); - if (need_cancel) - item.cancel(); + ipcMain.on('set-download-option', function(event, need_cancel, prevent_default) { + window.webContents.session.once('will-download', function(e, item, webContents) { + if (prevent_default) { + e.preventDefault(); + const url = item.getURL(); + const filename = item.getFilename(); + setImmediate(function() { + try { + item.getURL(); + } catch(err) { + window.webContents.send('download-error', url, filename, err.message); + } }); + } else { + item.setSavePath(downloadFilePath); + item.on('done', function(e, state) { + window.webContents.send('download-done', + state, + item.getURL(), + item.getMimeType(), + item.getReceivedBytes(), + item.getTotalBytes(), + item.getContentDisposition(), + item.getFilename()); + }); + if (need_cancel) + item.cancel(); + } + }); event.returnValue = "done"; }); }); From f1f91828ba051c1548b7d67ac55fd3fac3a33231 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 2 Feb 2016 18:49:43 +0800 Subject: [PATCH 126/688] Rely on OnDownloadDestroyed to destroy downloadItem --- atom/browser/api/atom_api_download_item.cc | 16 +++------------- atom/browser/api/atom_api_download_item.h | 2 -- atom/browser/api/atom_api_session.cc | 4 +--- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index c3beee5bb09..bb1c58f49b8 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -12,7 +12,6 @@ #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/node_includes.h" #include "base/memory/linked_ptr.h" -#include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" #include "native_mate/dictionary.h" #include "net/base/filename_util.h" @@ -71,17 +70,6 @@ DownloadItem::DownloadItem(content::DownloadItem* download_item) : } DownloadItem::~DownloadItem() { - Destroy(download_item_); -} - -void DownloadItem::Destroy(content::DownloadItem* item) { - if (item) { - OnDownloadDestroyed(item); - MarkDestroyed(); - - // Destroy the native class in next tick. - base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure()); - } } void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) { @@ -93,7 +81,9 @@ void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download_item) { auto iter = g_download_item_objects.find(download_item->GetId()); if (iter != g_download_item_objects.end()) g_download_item_objects.erase(iter); - download_item_ = nullptr; + + // Destroy the wrapper once the download_item is destroyed. + delete this; } int64 DownloadItem::GetReceivedBytes() { diff --git a/atom/browser/api/atom_api_download_item.h b/atom/browser/api/atom_api_download_item.h index af388a56751..471913c2266 100644 --- a/atom/browser/api/atom_api_download_item.h +++ b/atom/browser/api/atom_api_download_item.h @@ -36,8 +36,6 @@ class DownloadItem : public mate::TrackableObject, static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); - void Destroy(content::DownloadItem* download_item); - protected: explicit DownloadItem(content::DownloadItem* download_item); ~DownloadItem(); diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 04ab7a9f510..e5c5198f034 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -306,14 +306,12 @@ void Session::OnDownloadCreated(content::DownloadManager* manager, auto web_contents = item->GetWebContents(); if (SavePageHandler::IsSavePageTypes(item->GetMimeType())) return; - auto download_item_handle = DownloadItem::Create(isolate(), item); bool prevent_default = Emit( "will-download", - download_item_handle, + DownloadItem::Create(isolate(), item), api::WebContents::CreateFrom(isolate(), web_contents)); if (prevent_default) { item->Cancel(true); - download_item_handle->Destroy(item); item->Remove(); } } From 65cf85808f071aaa3a91285100dc6f1f87a72770 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 2 Feb 2016 19:05:58 +0800 Subject: [PATCH 127/688] Calling cancel() should destroy the downloadItem --- atom/browser/api/atom_api_download_item.cc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index bb1c58f49b8..b0bcd5ef1a1 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -12,6 +12,7 @@ #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/node_includes.h" #include "base/memory/linked_ptr.h" +#include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" #include "native_mate/dictionary.h" #include "net/base/filename_util.h" @@ -64,12 +65,14 @@ const base::FilePath& DownloadItem::SavePathData::path() { return path_; } -DownloadItem::DownloadItem(content::DownloadItem* download_item) : - download_item_(download_item) { +DownloadItem::DownloadItem(content::DownloadItem* download_item) + : download_item_(download_item) { download_item_->AddObserver(this); + AttachAsUserData(download_item); } DownloadItem::~DownloadItem() { + LOG(ERROR) << "~DownloadItem"; } void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) { @@ -82,8 +85,8 @@ void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download_item) { if (iter != g_download_item_objects.end()) g_download_item_objects.erase(iter); - // Destroy the wrapper once the download_item is destroyed. - delete this; + // Destroy the native class in next tick. + base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure()); } int64 DownloadItem::GetReceivedBytes() { @@ -132,7 +135,9 @@ void DownloadItem::Resume() { } void DownloadItem::Cancel() { + MarkDestroyed(); download_item_->Cancel(true); + download_item_->Remove(); } // static @@ -156,6 +161,10 @@ void DownloadItem::BuildPrototype(v8::Isolate* isolate, // static mate::Handle DownloadItem::Create( v8::Isolate* isolate, content::DownloadItem* item) { + auto existing = TrackableObject::FromWrappedClass(isolate, item); + if (existing) + return mate::CreateHandle(isolate, static_cast(existing)); + auto handle = mate::CreateHandle(isolate, new DownloadItem(item)); g_wrap_download_item.Run(handle.ToV8()); g_download_item_objects[item->GetId()] = make_linked_ptr( From 12d311fd29d3551b754fcbd2c023637baf5488f7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 2 Feb 2016 19:51:15 +0800 Subject: [PATCH 128/688] Gracefully destroy downloadItem --- atom/browser/api/atom_api_download_item.cc | 27 ++++++++++++++-------- vendor/native_mate | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index b0bcd5ef1a1..d8e87f2cfeb 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -48,6 +48,7 @@ namespace atom { namespace api { namespace { + // The wrapDownloadItem funtion which is implemented in JavaScript using WrapDownloadItemCallback = base::Callback)>; WrapDownloadItemCallback g_wrap_download_item; @@ -55,6 +56,7 @@ WrapDownloadItemCallback g_wrap_download_item; char kDownloadItemSavePathKey[] = "DownloadItemSavePathKey"; std::map>> g_download_item_objects; + } // namespace DownloadItem::SavePathData::SavePathData(const base::FilePath& path) : @@ -73,6 +75,16 @@ DownloadItem::DownloadItem(content::DownloadItem* download_item) DownloadItem::~DownloadItem() { LOG(ERROR) << "~DownloadItem"; + if (download_item_) { + // Destroyed by either garbage collection or destroy(). + download_item_->RemoveObserver(this); + download_item_->Remove(); + } + + // Remove from the global map. + auto iter = g_download_item_objects.find(weak_map_id()); + if (iter != g_download_item_objects.end()) + g_download_item_objects.erase(iter); } void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) { @@ -80,13 +92,9 @@ void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) { } void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download_item) { - download_item->RemoveObserver(this); - auto iter = g_download_item_objects.find(download_item->GetId()); - if (iter != g_download_item_objects.end()) - g_download_item_objects.erase(iter); - - // Destroy the native class in next tick. - base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure()); + download_item_ = nullptr; + // Destroy the native class immediately when downloadItem is destroyed. + delete this; } int64 DownloadItem::GetReceivedBytes() { @@ -135,7 +143,6 @@ void DownloadItem::Resume() { } void DownloadItem::Cancel() { - MarkDestroyed(); download_item_->Cancel(true); download_item_->Remove(); } @@ -167,7 +174,9 @@ mate::Handle DownloadItem::Create( auto handle = mate::CreateHandle(isolate, new DownloadItem(item)); g_wrap_download_item.Run(handle.ToV8()); - g_download_item_objects[item->GetId()] = make_linked_ptr( + + // Reference this object in case it got garbage collected. + g_download_item_objects[handle->weak_map_id()] = make_linked_ptr( new v8::Global(isolate, handle.ToV8())); return handle; } diff --git a/vendor/native_mate b/vendor/native_mate index 26520c5cf4b..e719eab878c 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 26520c5cf4b6a60da2c5cba971393f94b82f5939 +Subproject commit e719eab878c264bb03188d0cd6eb9ad6882bc13a From eaa60e9c171c536e68a20e892dc5d6cee6364609 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 2 Feb 2016 19:54:41 +0800 Subject: [PATCH 129/688] Destroy the item once item is downloaded --- atom/browser/api/atom_api_download_item.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index d8e87f2cfeb..da95b67af1f 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -88,7 +88,14 @@ DownloadItem::~DownloadItem() { } void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) { - download_item_->IsDone() ? Emit("done", item->GetState()) : Emit("updated"); + if (download_item_->IsDone()) { + Emit("done", item->GetState()); + + // Destroy the item once item is downloaded. + base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure()); + } else { + Emit("updated"); + } } void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download_item) { From 50d69fd9bbacf33e69bb489d9d16ee936c06f9f9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 2 Feb 2016 20:11:39 +0800 Subject: [PATCH 130/688] Get rid of SavePathData --- atom/browser/api/atom_api_download_item.cc | 99 +++++++++---------- atom/browser/api/atom_api_download_item.h | 35 +++---- .../browser/atom_download_manager_delegate.cc | 28 ++++-- 3 files changed, 76 insertions(+), 86 deletions(-) diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index da95b67af1f..5a8befc9d1d 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -53,20 +53,10 @@ namespace { using WrapDownloadItemCallback = base::Callback)>; WrapDownloadItemCallback g_wrap_download_item; -char kDownloadItemSavePathKey[] = "DownloadItemSavePathKey"; - std::map>> g_download_item_objects; } // namespace -DownloadItem::SavePathData::SavePathData(const base::FilePath& path) : - path_(path) { -} - -const base::FilePath& DownloadItem::SavePathData::path() { - return path_; -} - DownloadItem::DownloadItem(content::DownloadItem* download_item) : download_item_(download_item) { download_item_->AddObserver(this); @@ -74,7 +64,6 @@ DownloadItem::DownloadItem(content::DownloadItem* download_item) } DownloadItem::~DownloadItem() { - LOG(ERROR) << "~DownloadItem"; if (download_item_) { // Destroyed by either garbage collection or destroy(). download_item_->RemoveObserver(this); @@ -104,43 +93,6 @@ void DownloadItem::OnDownloadDestroyed(content::DownloadItem* download_item) { delete this; } -int64 DownloadItem::GetReceivedBytes() { - return download_item_->GetReceivedBytes(); -} - -int64 DownloadItem::GetTotalBytes() { - return download_item_->GetTotalBytes(); -} - -const GURL& DownloadItem::GetURL() { - return download_item_->GetURL(); -} - -std::string DownloadItem::GetMimeType() { - return download_item_->GetMimeType(); -} - -bool DownloadItem::HasUserGesture() { - return download_item_->HasUserGesture(); -} - -std::string DownloadItem::GetFilename() { - return base::UTF16ToUTF8(net::GenerateFileName(GetURL(), - GetContentDisposition(), - std::string(), - download_item_->GetSuggestedFilename(), - GetMimeType(), - std::string()).LossyDisplayName()); -} - -std::string DownloadItem::GetContentDisposition() { - return download_item_->GetContentDisposition(); -} - -void DownloadItem::SetSavePath(const base::FilePath& path) { - download_item_->SetUserData(UserDataKey(), new SavePathData(path)); -} - void DownloadItem::Pause() { download_item_->Pause(); } @@ -154,6 +106,47 @@ void DownloadItem::Cancel() { download_item_->Remove(); } +int64 DownloadItem::GetReceivedBytes() const { + return download_item_->GetReceivedBytes(); +} + +int64 DownloadItem::GetTotalBytes() const { + return download_item_->GetTotalBytes(); +} + +std::string DownloadItem::GetMimeType() const { + return download_item_->GetMimeType(); +} + +bool DownloadItem::HasUserGesture() const { + return download_item_->HasUserGesture(); +} + +std::string DownloadItem::GetFilename() const { + return base::UTF16ToUTF8(net::GenerateFileName(GetURL(), + GetContentDisposition(), + std::string(), + download_item_->GetSuggestedFilename(), + GetMimeType(), + std::string()).LossyDisplayName()); +} + +std::string DownloadItem::GetContentDisposition() const { + return download_item_->GetContentDisposition(); +} + +const GURL& DownloadItem::GetURL() const { + return download_item_->GetURL(); +} + +void DownloadItem::SetSavePath(const base::FilePath& path) { + save_path_ = path; +} + +base::FilePath DownloadItem::GetSavePath() const { + return save_path_; +} + // static void DownloadItem::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { @@ -164,12 +157,13 @@ void DownloadItem::BuildPrototype(v8::Isolate* isolate, .SetMethod("cancel", &DownloadItem::Cancel) .SetMethod("getReceivedBytes", &DownloadItem::GetReceivedBytes) .SetMethod("getTotalBytes", &DownloadItem::GetTotalBytes) - .SetMethod("getURL", &DownloadItem::GetURL) .SetMethod("getMimeType", &DownloadItem::GetMimeType) .SetMethod("hasUserGesture", &DownloadItem::HasUserGesture) .SetMethod("getFilename", &DownloadItem::GetFilename) .SetMethod("getContentDisposition", &DownloadItem::GetContentDisposition) - .SetMethod("setSavePath", &DownloadItem::SetSavePath); + .SetMethod("getURL", &DownloadItem::GetURL) + .SetMethod("setSavePath", &DownloadItem::SetSavePath) + .SetMethod("getSavePath", &DownloadItem::GetSavePath); } // static @@ -188,11 +182,6 @@ mate::Handle DownloadItem::Create( return handle; } -// static -void* DownloadItem::UserDataKey() { - return &kDownloadItemSavePathKey; -} - void ClearWrapDownloadItem() { g_wrap_download_item.Reset(); } diff --git a/atom/browser/api/atom_api_download_item.h b/atom/browser/api/atom_api_download_item.h index 471913c2266..5806c018176 100644 --- a/atom/browser/api/atom_api_download_item.h +++ b/atom/browser/api/atom_api_download_item.h @@ -20,22 +20,26 @@ namespace api { class DownloadItem : public mate::TrackableObject, public content::DownloadItem::Observer { public: - class SavePathData : public base::SupportsUserData::Data { - public: - explicit SavePathData(const base::FilePath& path); - const base::FilePath& path(); - private: - base::FilePath path_; - }; - static mate::Handle Create(v8::Isolate* isolate, content::DownloadItem* item); - static void* UserDataKey(); // mate::TrackableObject: static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); + void Pause(); + void Resume(); + void Cancel(); + int64 GetReceivedBytes() const; + int64 GetTotalBytes() const; + std::string GetMimeType() const; + bool HasUserGesture() const; + std::string GetFilename() const; + std::string GetContentDisposition() const; + const GURL& GetURL() const; + void SetSavePath(const base::FilePath& path); + base::FilePath GetSavePath() const; + protected: explicit DownloadItem(content::DownloadItem* download_item); ~DownloadItem(); @@ -44,19 +48,8 @@ class DownloadItem : public mate::TrackableObject, void OnDownloadUpdated(content::DownloadItem* download) override; void OnDownloadDestroyed(content::DownloadItem* download) override; - void Pause(); - void Resume(); - void Cancel(); - int64 GetReceivedBytes(); - int64 GetTotalBytes(); - std::string GetMimeType(); - bool HasUserGesture(); - std::string GetFilename(); - std::string GetContentDisposition(); - const GURL& GetURL(); - void SetSavePath(const base::FilePath& path); - private: + base::FilePath save_path_; content::DownloadItem* download_item_; DISALLOW_COPY_AND_ASSIGN(DownloadItem); diff --git a/atom/browser/atom_download_manager_delegate.cc b/atom/browser/atom_download_manager_delegate.cc index a5f5cc6d8e4..f5bdbbd8598 100644 --- a/atom/browser/atom_download_manager_delegate.cc +++ b/atom/browser/atom_download_manager_delegate.cc @@ -109,16 +109,24 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget( download->GetForcedFilePath()); return true; } - base::SupportsUserData::Data* save_path = download->GetUserData( - atom::api::DownloadItem::UserDataKey()); - if (save_path) { - const base::FilePath& default_download_path = - static_cast(save_path)->path(); - callback.Run(default_download_path, - content::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, - default_download_path); - return true; + + // Try to get the save path from JS wrapper. + { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + api::DownloadItem* download_item = api::DownloadItem::FromWrappedClass( + isolate, download); + if (download_item) { + base::FilePath save_path = download_item->GetSavePath(); + if (!save_path.empty()) { + callback.Run(save_path, + content::DownloadItem::TARGET_DISPOSITION_OVERWRITE, + content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + save_path); + return true; + } + } } AtomBrowserContext* browser_context = static_cast( From 4b67ff9534663df5936661ffddae649c142e5d6a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 2 Feb 2016 23:38:49 +0800 Subject: [PATCH 131/688] Override WillReleaseScriptContext --- atom/renderer/atom_renderer_client.cc | 11 ++++++++++- atom/renderer/atom_renderer_client.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 3c97db4b978..925088e3de3 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -52,11 +52,16 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver { // content::RenderFrameObserver: void DidCreateScriptContext(v8::Handle context, int extension_group, - int world_id) { + int world_id) override { renderer_client_->DidCreateScriptContext( render_frame()->GetWebFrame(), context); } + void WillReleaseScriptContext(v8::Local context, + int world_id) override { + renderer_client_->WillReleaseScriptContext(context); + } + private: AtomRendererClient* renderer_client_; @@ -162,6 +167,10 @@ void AtomRendererClient::DidCreateScriptContext( node_bindings_->LoadEnvironment(env); } +void AtomRendererClient::WillReleaseScriptContext( + v8::Handle context) { +} + bool AtomRendererClient::ShouldFork(blink::WebLocalFrame* frame, const GURL& url, const std::string& http_method, diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index beeeb9d530b..a8d404ea8c8 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -24,6 +24,7 @@ class AtomRendererClient : public content::ContentRendererClient, void DidCreateScriptContext(blink::WebFrame* frame, v8::Handle context); + void WillReleaseScriptContext(v8::Handle context); private: enum NodeIntegration { From ffcf609de1369b053c8bd077e2e33f5f021b4e4f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 2 Feb 2016 23:44:33 +0800 Subject: [PATCH 132/688] Ensure only main frame get notifications --- atom/renderer/atom_renderer_client.cc | 27 ++++++++++++++++----------- atom/renderer/atom_renderer_client.h | 3 +-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 925088e3de3..00ac245070b 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -47,22 +47,27 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver { AtomRenderFrameObserver(content::RenderFrame* frame, AtomRendererClient* renderer_client) : content::RenderFrameObserver(frame), + world_id_(-1), renderer_client_(renderer_client) {} // content::RenderFrameObserver: void DidCreateScriptContext(v8::Handle context, int extension_group, int world_id) override { - renderer_client_->DidCreateScriptContext( - render_frame()->GetWebFrame(), context); + if (world_id_ != -1) + return; + world_id_ = world_id; + renderer_client_->DidCreateScriptContext(context); } - void WillReleaseScriptContext(v8::Local context, int world_id) override { + if (world_id_ != world_id) + return; renderer_client_->WillReleaseScriptContext(context); } private: + int world_id_; AtomRendererClient* renderer_client_; DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver); @@ -82,6 +87,9 @@ void AtomRendererClient::WebKitInitialized() { blink::WebCustomElement::addEmbedderCustomElementName("webview"); blink::WebCustomElement::addEmbedderCustomElementName("browserplugin"); + // Allow file scheme to handle service worker by default. + blink::WebSecurityPolicy::registerURLSchemeAsAllowingServiceWorkers("file"); + OverrideNodeArrayBuffer(); node_bindings_->Initialize(); @@ -113,10 +121,12 @@ void AtomRendererClient::RenderThreadStarted() { void AtomRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { new PepperHelper(render_frame); - new AtomRenderFrameObserver(render_frame, this); - // Allow file scheme to handle service worker by default. - blink::WebSecurityPolicy::registerURLSchemeAsAllowingServiceWorkers("file"); + // Only insert node integration for the main frame. + if (!render_frame->IsMainFrame()) + return; + + new AtomRenderFrameObserver(render_frame, this); } void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) { @@ -144,12 +154,7 @@ bool AtomRendererClient::OverrideCreatePlugin( } void AtomRendererClient::DidCreateScriptContext( - blink::WebFrame* frame, v8::Handle context) { - // Only insert node integration for the main frame. - if (frame->parent()) - return; - // Give the node loop a run to make sure everything is ready. node_bindings_->RunMessageLoop(); diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index a8d404ea8c8..59b407ba1ef 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -22,8 +22,7 @@ class AtomRendererClient : public content::ContentRendererClient, AtomRendererClient(); virtual ~AtomRendererClient(); - void DidCreateScriptContext(blink::WebFrame* frame, - v8::Handle context); + void DidCreateScriptContext(v8::Handle context); void WillReleaseScriptContext(v8::Handle context); private: From bc196c016b9e801fd4c8459f51a70a263a06a1b8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 2 Feb 2016 23:47:19 +0800 Subject: [PATCH 133/688] Do process.emit('exit') in WillReleaseScriptContext --- atom/renderer/atom_renderer_client.cc | 3 +++ atom/renderer/lib/init.js | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 00ac245070b..7ff87a582a2 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -9,6 +9,7 @@ #include "atom/common/api/api_messages.h" #include "atom/common/api/atom_bindings.h" +#include "atom/common/api/event_emitter_caller.h" #include "atom/common/node_bindings.h" #include "atom/common/node_includes.h" #include "atom/common/options_switches.h" @@ -174,6 +175,8 @@ void AtomRendererClient::DidCreateScriptContext( void AtomRendererClient::WillReleaseScriptContext( v8::Handle context) { + node::Environment* env = node::Environment::GetCurrent(context); + mate::EmitEvent(env->isolate(), env->process_object(), "exit"); } bool AtomRendererClient::ShouldFork(blink::WebLocalFrame* frame, diff --git a/atom/renderer/lib/init.js b/atom/renderer/lib/init.js index 18be7b08011..340a1ef5053 100644 --- a/atom/renderer/lib/init.js +++ b/atom/renderer/lib/init.js @@ -106,11 +106,6 @@ if (nodeIntegration === 'true' || nodeIntegration === 'all' || nodeIntegration = return false; } }; - - // Emit the 'exit' event when page is unloading. - window.addEventListener('unload', function() { - return process.emit('exit'); - }); } else { // Delete Node's symbols after the Environment has been loaded. process.once('loaded', function() { From 47de3f3f24a7a78a8881e477e0d83a2bc9d30e11 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 3 Feb 2016 00:05:27 +0800 Subject: [PATCH 134/688] Fix failing specs --- atom/renderer/atom_renderer_client.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 7ff87a582a2..a996bd0efb2 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -55,7 +55,7 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver { void DidCreateScriptContext(v8::Handle context, int extension_group, int world_id) override { - if (world_id_ != -1) + if (world_id_ != -1 && world_id_ != world_id) return; world_id_ = world_id; renderer_client_->DidCreateScriptContext(context); @@ -88,9 +88,6 @@ void AtomRendererClient::WebKitInitialized() { blink::WebCustomElement::addEmbedderCustomElementName("webview"); blink::WebCustomElement::addEmbedderCustomElementName("browserplugin"); - // Allow file scheme to handle service worker by default. - blink::WebSecurityPolicy::registerURLSchemeAsAllowingServiceWorkers("file"); - OverrideNodeArrayBuffer(); node_bindings_->Initialize(); @@ -123,6 +120,9 @@ void AtomRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { new PepperHelper(render_frame); + // Allow file scheme to handle service worker by default. + blink::WebSecurityPolicy::registerURLSchemeAsAllowingServiceWorkers("file"); + // Only insert node integration for the main frame. if (!render_frame->IsMainFrame()) return; From 77d005c5c8d5c95eb74dd9738a751f6462078b61 Mon Sep 17 00:00:00 2001 From: Rafael Firmino Date: Tue, 2 Feb 2016 17:01:55 -0200 Subject: [PATCH 135/688] translation for pt_BR --- .../source-code-directory-structure.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docs-translations/pt-BR/development/source-code-directory-structure.md diff --git a/docs-translations/pt-BR/development/source-code-directory-structure.md b/docs-translations/pt-BR/development/source-code-directory-structure.md new file mode 100644 index 00000000000..77c01d79113 --- /dev/null +++ b/docs-translations/pt-BR/development/source-code-directory-structure.md @@ -0,0 +1,53 @@ +# Estrutura de Diretórios do Código-Fonte + +O código-fonte do Electron é separado em algumas partes, seguindo principalmente as convenções de separação do chromium. + +Você pode se familiarizar com a [arquitetura de multiprocessamento ](http://dev.chromium.org/developers/design-documents/multi-process-architecture) do Chromium para entender melhor o código-fonte. + + +## Estrutura do Código-Fonte + +``` +Electron +├──atom - Código fonte do Electron. +| ├── app - Código de inicialização. +| ├── browser - A interface incluíndo a janela principal, UI, e todas as coisas do processo principal. Ele se comunica com o renderizador para gerenciar as páginas web. +| |   ├── lib - Código Javascript para inicializar o processo principal. +| | ├── ui - Implementação da UI para plataformas distintas. +| | | ├── cocoa - Código-fonte específico do cocoa . +| | | ├── gtk - Código-font específico do GTK+. +| | | └── win - Código-fonte específico do Windows GUI. +| | ├── default_app - A página padrão é mostrada quando +| | | Electron inicializa sem fornecer um app. +| | ├── api - Implementação do processo principal das APIs +| | | └── lib - Código Javascript, parte da implementação da API. +| | ├── net - Código relacionado a rede. +| | ├── mac - Código fonte em Object-c, específico para Mac. +| | └── resources - Icones, arquivos dependentes da plataforma, etc. +| ├── renderer - Código que é executado no processo de renderização. +| | ├── lib - Parte do código Javascript de inicialização do renderizador. +| | └── api - Implementação das APIs para o processo de renderizaçãp. +| | └── lib - Código Javascript, parte da implementação da API. +| └── common - Código que utiliza ambos os processos, o principal e o de rendezição, +| ele inclui algumas funções utilitárias e códigos para integrar com ciclo de mensagens do node no ciclo de mensagens do Chromium. +| ├── lib - Código Javascript comum para a inicialização. +| └── api - A implementação de APIs comuns e fundamentação dos +| módulos integrados com Electron's. +| └── lib - Código Javascript, parte da implementação da API. +├── chromium_src - Código-fonte copiado do Chromium. +├── docs - Documentação. +├── spec - Testes Automáticos. +├── atom.gyp - Regras de compilação do Electron. +└── common.gypi - Configuração específica do compilador e regras de construção para outros componentes + como `node` e `breakpad`. +``` + +## Estrutura de Outros Diretórios. + +* **script** - Scripts utilizado para fins de desenvolvimento como building, packaging, testes, etc. +* **tools** - Scripts auxiliares, utilizados pelos arquivos gyp, ao contrário do`script`, os scripts colocados aqui nunca devem ser invocados diretamente pelos usuários. +* **vendor** - Dependências de código-fonte de terceiros, nós não utilizamos `third_party` como nome porque ele poderia ser confundido com o diretório homônimo existente no código-fonte do Chromium. +* **node_modules** - Módulos de terceiros em node usados para compilação +* **out** - Diretório temporário saída do `ninja`. +* **dist** - Diretório temporário do `script/create-dist.py` ao criar uma distribuição +* **external_binaries** - Binários baixados de Frameworks de terceiros que não suportam a compilação com `gyp`. From 86ed7ca725a95f1633fd100e638d4766fc23d7a0 Mon Sep 17 00:00:00 2001 From: ShiningRay Date: Wed, 3 Feb 2016 11:37:20 +0800 Subject: [PATCH 136/688] fix typo Broswer -> Browser --- docs-translations/zh-CN/tutorial/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/zh-CN/tutorial/quick-start.md b/docs-translations/zh-CN/tutorial/quick-start.md index d54dddbfc93..5e9c752d1d4 100644 --- a/docs-translations/zh-CN/tutorial/quick-start.md +++ b/docs-translations/zh-CN/tutorial/quick-start.md @@ -14,7 +14,7 @@ Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造 在一般浏览器中,网页通常会在沙盒环境下运行,并且不允许访问原生资源。然而,Electron 用户拥有在网页中调用 io.js 的 APIs 的能力,可以与底层操作系统直接交互。 ## 主进程与渲染进程的区别 -主进程使用 BroswerWindow 实例创建网页。每个 BroswerWindow 实例都在自己的渲染进程里运行着一个网页。当一个 BroswerWindow 实例被销毁后,相应的渲染进程也会被终止。 +主进程使用 BrowserWindow 实例创建网页。每个 BrowserWindow 实例都在自己的渲染进程里运行着一个网页。当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。 主进程管理所有页面和与之对应的渲染进程。每个渲染进程都是相互独立的,并且只关心他们自己的网页。 From b9e2806042beb0b91da6ca9b4d724752ebe6e70c Mon Sep 17 00:00:00 2001 From: Mark Potnick Date: Wed, 3 Feb 2016 15:15:13 -0500 Subject: [PATCH 137/688] Fixing typo --- docs/api/ipc-renderer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index 090fd1a9119..96936632563 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -37,9 +37,9 @@ channel. This removes *all* handlers to this ipc channel. -### `ipcMain.once(channel, callback)` +### `ipcRenderer.once(channel, callback)` -Use this in place of `ipcMain.on()` to fire handlers meant to occur only once, +Use this in place of `ipcRenderer.on()` to fire handlers meant to occur only once, as in, they won't be activated after one call of `callback` ## Sending Messages From 8bd07af5e579da36140191fbea59f561964fbda3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 16:22:16 -0800 Subject: [PATCH 138/688] Correct typo in comment --- atom/browser/lib/chrome-extension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/lib/chrome-extension.js b/atom/browser/lib/chrome-extension.js index fbb537d052c..eaed9b655a6 100644 --- a/atom/browser/lib/chrome-extension.js +++ b/atom/browser/lib/chrome-extension.js @@ -70,7 +70,7 @@ app.once('ready', function() { var BrowserWindow, chromeExtensionHandler, i, init, len, protocol, srcDirectory; protocol = electron.protocol, BrowserWindow = electron.BrowserWindow; - // Load persistented extensions. + // Load persisted extensions. loadedExtensionsPath = path.join(app.getPath('userData'), 'DevTools Extensions'); try { loadedExtensions = JSON.parse(fs.readFileSync(loadedExtensionsPath)); From 5714ae0b73c722d2a57bbac182d671384b705314 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 17:08:46 -0800 Subject: [PATCH 139/688] Add failing spec for dev tools extensions file --- spec/api-browser-window-spec.js | 17 +++++++++++++++++ .../devtools-extensions/foo/manifest.json | 3 +++ 2 files changed, 20 insertions(+) create mode 100644 spec/fixtures/devtools-extensions/foo/manifest.json diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index fc8d3523c8f..328325a376a 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -8,6 +8,7 @@ const os = require('os'); const remote = require('electron').remote; const screen = require('electron').screen; +const app = remote.require('electron').app; const ipcMain = remote.require('electron').ipcMain; const BrowserWindow = remote.require('electron').BrowserWindow; @@ -618,4 +619,20 @@ describe('browser-window module', function() { }); }); }); + + describe('dev tool extensions', function () { + it('serializes the registered extensions on quit', function () { + var extensionName = 'foo' + var extensionPath = path.join(__dirname, 'fixtures', 'devtools-extensions', extensionName); + var serializedPath = path.join(app.getPath('userData'), 'DevTools Extensions'); + + BrowserWindow.addDevToolsExtension(extensionPath); + app.emit('will-quit'); + assert.deepEqual(JSON.parse(fs.readFileSync(serializedPath)), [extensionPath]); + + BrowserWindow.removeDevToolsExtension(extensionName); + app.emit('will-quit'); + assert.equal(fs.existsSync(serializedPath), false); + }) + }) }); diff --git a/spec/fixtures/devtools-extensions/foo/manifest.json b/spec/fixtures/devtools-extensions/foo/manifest.json new file mode 100644 index 00000000000..bde99de9287 --- /dev/null +++ b/spec/fixtures/devtools-extensions/foo/manifest.json @@ -0,0 +1,3 @@ +{ + "name": "foo" +} From 6252511b7fa5505ba4f47dfad9ff16f26fe0c5e0 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 17:12:09 -0800 Subject: [PATCH 140/688] Delete extensions file when there are no loaded extensions --- atom/browser/lib/chrome-extension.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/atom/browser/lib/chrome-extension.js b/atom/browser/lib/chrome-extension.js index eaed9b655a6..e396989bcf3 100644 --- a/atom/browser/lib/chrome-extension.js +++ b/atom/browser/lib/chrome-extension.js @@ -54,12 +54,16 @@ app.on('will-quit', function() { loadedExtensions = Object.keys(extensionInfoMap).map(function(key) { return extensionInfoMap[key].srcDirectory; }); - try { - fs.mkdirSync(path.dirname(loadedExtensionsPath)); - } catch (error) { - // Ignore error + if (loadedExtensions.length > 0) { + try { + fs.mkdirSync(path.dirname(loadedExtensionsPath)); + } catch (error) { + // Ignore error + } + return fs.writeFileSync(loadedExtensionsPath, JSON.stringify(loadedExtensions)); + } else { + fs.unlinkSync(loadedExtensionsPath); } - return fs.writeFileSync(loadedExtensionsPath, JSON.stringify(loadedExtensions)); } catch (error) { // Ignore error } From adfa4844d1b1849b1b6ea7f2839fc037a5aba020 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 17:15:28 -0800 Subject: [PATCH 141/688] Don't return anything from will-quit handler --- atom/browser/lib/chrome-extension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/lib/chrome-extension.js b/atom/browser/lib/chrome-extension.js index e396989bcf3..fcbb8c7f15f 100644 --- a/atom/browser/lib/chrome-extension.js +++ b/atom/browser/lib/chrome-extension.js @@ -60,7 +60,7 @@ app.on('will-quit', function() { } catch (error) { // Ignore error } - return fs.writeFileSync(loadedExtensionsPath, JSON.stringify(loadedExtensions)); + fs.writeFileSync(loadedExtensionsPath, JSON.stringify(loadedExtensions)); } else { fs.unlinkSync(loadedExtensionsPath); } From 00261a5571d71d77850cd268e8ae8890716924bd Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 17:17:11 -0800 Subject: [PATCH 142/688] Remove lint warnings --- spec/api-browser-window-spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 328325a376a..a7d58d7feb8 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -622,7 +622,7 @@ describe('browser-window module', function() { describe('dev tool extensions', function () { it('serializes the registered extensions on quit', function () { - var extensionName = 'foo' + var extensionName = 'foo'; var extensionPath = path.join(__dirname, 'fixtures', 'devtools-extensions', extensionName); var serializedPath = path.join(app.getPath('userData'), 'DevTools Extensions'); @@ -633,6 +633,6 @@ describe('browser-window module', function() { BrowserWindow.removeDevToolsExtension(extensionName); app.emit('will-quit'); assert.equal(fs.existsSync(serializedPath), false); - }) - }) + }); + }); }); From 48c6692311ab57e575e9e2d49da438192f3f087f Mon Sep 17 00:00:00 2001 From: chris-ls Date: Thu, 4 Feb 2016 15:36:41 +1300 Subject: [PATCH 143/688] Clarify overlay description '16px' is ambiguous and not clear (4 x 4 px? or 16 x 16px) --- docs/api/browser-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index edda572e9ac..7cf684a3953 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -785,7 +785,7 @@ cleared * `description` String - a description that will be provided to Accessibility screen readers -Sets a 16px overlay onto the current taskbar icon, usually used to convey some +Sets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to convey some sort of application status or to passively notify the user. ### `win.setHasShadow(hasShadow)` _OS X_ From e9aa24e340a3dd9b6ab3794c7bee1da1d359b37d Mon Sep 17 00:00:00 2001 From: ShiningRay Date: Thu, 4 Feb 2016 18:10:26 +0800 Subject: [PATCH 144/688] fix broken link --- docs-translations/zh-CN/tutorial/quick-start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/zh-CN/tutorial/quick-start.md b/docs-translations/zh-CN/tutorial/quick-start.md index 5e9c752d1d4..c4d668417e4 100644 --- a/docs-translations/zh-CN/tutorial/quick-start.md +++ b/docs-translations/zh-CN/tutorial/quick-start.md @@ -127,7 +127,7 @@ $ ./Electron.app/Contents/MacOS/Electron your-app/ 在你完成了你的应用后,你可以按照[应用部署][4]指导发布一个版本,并且以已经打包好的形式运行应用。 - [1]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/ipc-renderer.md + [1]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/ipc-main-process.md [2]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/api/remote.md [3]: https://github.com/atom/electron/releases [4]: https://github.com/atom/electron/blob/master/docs-translations/zh-CN/tutorial/application-distribution.md From 6c8d9a5ccf2cd2970ea0aa7e627b374e38f57e45 Mon Sep 17 00:00:00 2001 From: ShiningRay Date: Thu, 4 Feb 2016 21:11:59 +0800 Subject: [PATCH 145/688] translate --- docs-translations/zh-CN/api/remote.md | 150 ++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 docs-translations/zh-CN/api/remote.md diff --git a/docs-translations/zh-CN/api/remote.md b/docs-translations/zh-CN/api/remote.md new file mode 100644 index 00000000000..049ce5fb32c --- /dev/null +++ b/docs-translations/zh-CN/api/remote.md @@ -0,0 +1,150 @@ +# remote + +`remote` 模块提供了一种在渲染进程(网页)和主进程之间进行进程间通讯(IPC)的简便途径。 + +Electron中, 与GUI相关的模块(如 `dialog`, `menu` 等)只存在于主进程,而不在渲染进程中 +。为了能从渲染进程中使用它们,需要用`ipc`模块来给主进程发送进程间消息。使用 `remote` +模块,可以调用主进程对象的方法,而无需显式地发送进程间消息,这类似于 Java 的 [RMI][rmi]。 +下面是从渲染进程创建一个浏览器窗口的例子: + +```javascript +const remote = require('electron').remote; +const BrowserWindow = remote.BrowserWindow; + +var win = new BrowserWindow({ width: 800, height: 600 }); +win.loadURL('https://github.com'); +``` + +**注意:** 反向操作(从主进程访问渲染进程),可以使用[webContents.executeJavascript](web-contents.md#webcontentsexecutejavascriptcode-usergesture). + +## 远程对象 + +`remote`模块返回的每个对象(包括函数)都代表了主进程中的一个对象(我们称之为远程对象或者远程函数)。 +当调用远程对象的方法、执行远程函数或者使用远程构造器(函数)创建新对象时,其实就是在发送同步的进程间消息。 + +在上面的例子中, `BrowserWindow` 和 `win` 都是远程对象,然而 +`new BrowserWindow` 并没有在渲染进程中创建 `BrowserWindow` 对象。 +而是在主进程中创建了 `BrowserWindow` 对象,并在渲染进程中返回了对应的远程对象,即 +`win` 对象。 + +请注意只有 [可枚举属性](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) 才能通过 remote 进行访问. + +## 远程对象的生命周期 + +Electron 确保在渲染进程中的远程对象存在(换句话说,没有被垃圾收集),那主进程中的对应对象也不会被释放。 +当远程对象被垃圾收集之后,主进程中的对应对象才会被取消关联。 + +如果远程对象在渲染进程泄露了(即,存在某个表中但永远不会释放),那么主进程中的对应对象也一样会泄露, +所以你必须小心不要泄露了远程对象。If the remote object is leaked in the renderer process (e.g. stored in a map but +never freed), the corresponding object in the main process will also be leaked, +so you should be very careful not to leak remote objects. + +不过,主要的值类型如字符串和数字,是传递的副本。 + +## 给主进程传递回调函数 + +在主进程中的代码可以从渲染进程——`remote`模块——中接受回调函数,但是使用这个功能的时候必须非常非常小心。Code in the main process can accept callbacks from the renderer - for instance +the `remote` module - but you should be extremely careful when using this +feature. + +首先,为了避免死锁,传递给主进程的回调函数会进行异步调用。所以不能期望主进程来获得传递过去的回调函数的返回值。First, in order to avoid deadlocks, the callbacks passed to the main process +are called asynchronously. You should not expect the main process to +get the return value of the passed callbacks. + +比如,在渲染进程For instance you can't use a function from the renderer process in an +`Array.map` called in the main process: + +```javascript +// 主进程 mapNumbers.js +exports.withRendererCallback = function(mapper) { + return [1,2,3].map(mapper); +} + +exports.withLocalCallback = function() { + return exports.mapNumbers(function(x) { + return x + 1; + }); +} +``` + +```javascript +// 渲染进程 +var mapNumbers = require("remote").require("./mapNumbers"); + +var withRendererCb = mapNumbers.withRendererCallback(function(x) { + return x + 1; +}) + +var withLocalCb = mapNumbers.withLocalCallback() + +console.log(withRendererCb, withLocalCb) // [true, true, true], [2, 3, 4] +``` + +As you can see, the renderer callback's synchronous return value was not as +expected, and didn't match the return value of an identical callback that lives +in the main process. + +Second, the callbacks passed to the main process will persist until the +main process garbage-collects them. + +For example, the following code seems innocent at first glance. It installs a +callback for the `close` event on a remote object: + +```javascript +remote.getCurrentWindow().on('close', function() { + // blabla... +}); +``` + +But remember the callback is referenced by the main process until you +explicitly uninstall it. If you do not, each time you reload your window the +callback will be installed again, leaking one callback for each restart. + +To make things worse, since the context of previously installed callbacks has +been released, exceptions will be raised in the main process when the `close` +event is emitted. + +To avoid this problem, ensure you clean up any references to renderer callbacks +passed to the main process. This involves cleaning up event handlers, or +ensuring the main process is explicitly told to deference callbacks that came +from a renderer process that is exiting. + +## Accessing built-in modules in the main process + +The built-in modules in the main process are added as getters in the `remote` +module, so you can use them directly like the `electron` module. + +```javascript +const app = remote.app; +``` + +## 方法 + +`remote` 模块有以下方法: + +### `remote.require(module)` + +* `module` String + +返回在主进程中执行 `require(module)` 所返回的对象。 + +### `remote.getCurrentWindow()` + +返回该网页所属的 [`BrowserWindow`](browser-window.md) 对象。 + +### `remote.getCurrentWebContents()` + +返回该网页的 [`WebContents`](web-contents.md) 对象 + +### `remote.getGlobal(name)` + +* `name` String + +返回在主进程中名为 `name` 的全局变量(即 `global[name]`) 。 + +### `remote.process` + +返回主进程中的 `process` 对象。等同于 +`remote.getGlobal('process')` 但是有缓存。 + +[rmi]: http://en.wikipedia.org/wiki/Java_remote_method_invocation From 55950281e8b0eccafe72372a8e668382c1bb21a4 Mon Sep 17 00:00:00 2001 From: ShiningRay Date: Thu, 4 Feb 2016 22:55:30 +0800 Subject: [PATCH 146/688] translate --- docs-translations/zh-CN/api/remote.md | 31 ++++++++------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/docs-translations/zh-CN/api/remote.md b/docs-translations/zh-CN/api/remote.md index 049ce5fb32c..a686abf2f61 100644 --- a/docs-translations/zh-CN/api/remote.md +++ b/docs-translations/zh-CN/api/remote.md @@ -51,8 +51,7 @@ feature. are called asynchronously. You should not expect the main process to get the return value of the passed callbacks. -比如,在渲染进程For instance you can't use a function from the renderer process in an -`Array.map` called in the main process: +比如,你不能主进程中给`Array.map`传递来自渲染进程的函数。 ```javascript // 主进程 mapNumbers.js @@ -80,15 +79,11 @@ var withLocalCb = mapNumbers.withLocalCallback() console.log(withRendererCb, withLocalCb) // [true, true, true], [2, 3, 4] ``` -As you can see, the renderer callback's synchronous return value was not as -expected, and didn't match the return value of an identical callback that lives -in the main process. +如你所见,渲染器回调函数的同步返回值没有按预期产生,与主进程中的一模一样的回调函数的返回值不同。 -Second, the callbacks passed to the main process will persist until the -main process garbage-collects them. +其次,传递给主进程的函数会持续到主进程对他们进行垃圾回收。 -For example, the following code seems innocent at first glance. It installs a -callback for the `close` event on a remote object: +例如,下面的代码第一眼看上去毫无问题。给远程对象的`close`事件绑定了一个回调函数: ```javascript remote.getCurrentWindow().on('close', function() { @@ -96,23 +91,15 @@ remote.getCurrentWindow().on('close', function() { }); ``` -But remember the callback is referenced by the main process until you -explicitly uninstall it. If you do not, each time you reload your window the -callback will be installed again, leaking one callback for each restart. +但记住主进程会一直保持对这个回调函数的引用,除非明确的卸载它。如果不卸载,每次重新载入窗口都会再次绑定,这样每次重启就会泄露一个回调函数。 -To make things worse, since the context of previously installed callbacks has -been released, exceptions will be raised in the main process when the `close` -event is emitted. +更严重的是,由于前面安装了回调函数的上下文已经被释放,所以当主进程的 `close` 事件触发的时候,会抛出异常。 -To avoid this problem, ensure you clean up any references to renderer callbacks -passed to the main process. This involves cleaning up event handlers, or -ensuring the main process is explicitly told to deference callbacks that came -from a renderer process that is exiting. +为了避免这个问题,要确保对传递给主进程的渲染器的回调函数进行清理。可以清理事件处理器,或者明确告诉主进行取消来自已经退出的渲染器进程中的回调函数。 -## Accessing built-in modules in the main process +## 访问主进程中的内置模块 -The built-in modules in the main process are added as getters in the `remote` -module, so you can use them directly like the `electron` module. +在主进程中的内置模块已经被添加为`remote`模块中的属性,所以可以直接像使用`electron`模块一样直接使用它们。 ```javascript const app = remote.app; From 8df3856c8f26ed3f1e9ece48850a26fc4466eced Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 09:16:40 -0800 Subject: [PATCH 147/688] Use const for fs/path requires --- atom/browser/default_app/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 895e3df6366..c24fc12ac3c 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -4,8 +4,8 @@ const dialog = electron.dialog; const shell = electron.shell; const Menu = electron.Menu; -var fs = require('fs'); -var path = require('path'); +const fs = require('fs'); +const path = require('path'); // Quit when all windows are closed and no other one is listening to this. app.on('window-all-closed', function() { From 2e96cab6aa82fd9e77778699a761f19112181463 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:07:19 -0800 Subject: [PATCH 148/688] Extract helper function to load specified app --- atom/browser/default_app/main.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index c24fc12ac3c..c562824daff 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -234,12 +234,10 @@ if (option.modules.length > 0) { require('module')._preloadModules(option.modules); } -// Start the specified app if there is one specified in command line, otherwise -// start the default app. -if (option.file && !option.webdriver) { +function loadPackagePath(packagePath) { try { // Override app name and version. - var packagePath = path.resolve(option.file); + packagePath = path.resolve(packagePath); var packageJsonPath = path.join(packagePath, 'package.json'); if (fs.existsSync(packageJsonPath)) { var packageJson = JSON.parse(fs.readFileSync(packageJsonPath)); @@ -270,6 +268,12 @@ if (option.file && !option.webdriver) { throw e; } } +} + +// Start the specified app if there is one specified in command line, otherwise +// start the default app. +if (option.file && !option.webdriver) { + loadPackagePath(option.file); } else if (option.version) { console.log('v' + process.versions.electron); process.exit(0); From 69687c92e96cf59a5a66ff029cfd18d6ad62ad00 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:26:11 -0800 Subject: [PATCH 149/688] Add support for launching http URL directly --- atom/browser/default_app/default_app.js | 20 +++++++++++--------- atom/browser/default_app/main.js | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/atom/browser/default_app/default_app.js b/atom/browser/default_app/default_app.js index 2ec765d0d69..ebcca2a5d9a 100644 --- a/atom/browser/default_app/default_app.js +++ b/atom/browser/default_app/default_app.js @@ -9,13 +9,15 @@ app.on('window-all-closed', function() { app.quit(); }); -app.on('ready', function() { - mainWindow = new BrowserWindow({ - width: 800, - height: 600, - autoHideMenuBar: true, - useContentSize: true, +exports.load = function(appUrl) { + app.on('ready', function() { + mainWindow = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + useContentSize: true, + }); + mainWindow.loadURL(appUrl); + mainWindow.focus(); }); - mainWindow.loadURL('file://' + __dirname + '/index.html'); - mainWindow.focus(); -}); +}; diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index c562824daff..2b5c916749d 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -6,6 +6,7 @@ const Menu = electron.Menu; const fs = require('fs'); const path = require('path'); +const url = require('url'); // Quit when all windows are closed and no other one is listening to this. app.on('window-all-closed', function() { @@ -270,10 +271,19 @@ function loadPackagePath(packagePath) { } } +function loadApplicationByUrl(appUrl) { + require('./default_app').load(appUrl); +} + // Start the specified app if there is one specified in command line, otherwise // start the default app. if (option.file && !option.webdriver) { - loadPackagePath(option.file); + var protocol = url.parse(option.file).protocol; + if (protocol === 'http:' || protocol === 'https:') { + loadApplicationByUrl(option.file); + } else { + loadPackagePath(option.file); + } } else if (option.version) { console.log('v' + process.versions.electron); process.exit(0); @@ -289,5 +299,5 @@ if (option.file && !option.webdriver) { console.log(helpMessage); process.exit(0); } else { - require('./default_app'); + loadApplicationByUrl('file://' + __dirname + '/index.html'); } From 312182e0bdd8d71cf7a26ffaa54daf825ad7fbb8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:33:22 -0800 Subject: [PATCH 150/688] Add support for launching HTML files directly --- atom/browser/default_app/main.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 2b5c916749d..09082804b3c 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -278,11 +278,15 @@ function loadApplicationByUrl(appUrl) { // Start the specified app if there is one specified in command line, otherwise // start the default app. if (option.file && !option.webdriver) { - var protocol = url.parse(option.file).protocol; + var file = option.file; + var protocol = url.parse(file).protocol; + var extension = path.extname(file); if (protocol === 'http:' || protocol === 'https:') { - loadApplicationByUrl(option.file); + loadApplicationByUrl(file); + } else if (extension === '.html' || extension === '.htm') { + loadApplicationByUrl('file://' + path.resolve(file)); } else { - loadPackagePath(option.file); + loadPackagePath(file); } } else if (option.version) { console.log('v' + process.versions.electron); From b74dd43ff564430a54b261688f9cd78dfb46b0b4 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:34:36 -0800 Subject: [PATCH 151/688] Support opening file: URLs directly --- atom/browser/default_app/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 09082804b3c..3ec80a6975f 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -281,7 +281,7 @@ if (option.file && !option.webdriver) { var file = option.file; var protocol = url.parse(file).protocol; var extension = path.extname(file); - if (protocol === 'http:' || protocol === 'https:') { + if (protocol === 'http:' || protocol === 'https:' || protocol === 'file:') { loadApplicationByUrl(file); } else if (extension === '.html' || extension === '.htm') { loadApplicationByUrl('file://' + path.resolve(file)); From f482ea4902738e3135a732b24daa50ef2a494383 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:35:17 -0800 Subject: [PATCH 152/688] loadPackagePath -> loadApplicationPackage --- atom/browser/default_app/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 3ec80a6975f..855d2463d25 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -235,7 +235,7 @@ if (option.modules.length > 0) { require('module')._preloadModules(option.modules); } -function loadPackagePath(packagePath) { +function loadApplicationPackage(packagePath) { try { // Override app name and version. packagePath = path.resolve(packagePath); @@ -286,7 +286,7 @@ if (option.file && !option.webdriver) { } else if (extension === '.html' || extension === '.htm') { loadApplicationByUrl('file://' + path.resolve(file)); } else { - loadPackagePath(file); + loadApplicationPackage(file); } } else if (option.version) { console.log('v' + process.versions.electron); From acd5d40ab088d6d88a77d21c6027ff464528d79a Mon Sep 17 00:00:00 2001 From: Vjekoslav Ratkajec Date: Thu, 4 Feb 2016 19:38:47 +0100 Subject: [PATCH 153/688] Adding support to write RTF to clipboard. --- atom/common/api/atom_api_clipboard.cc | 11 +++++++++++ docs/api/clipboard.md | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/atom/common/api/atom_api_clipboard.cc b/atom/common/api/atom_api_clipboard.cc index 0837a3dc93f..5060db17e9a 100644 --- a/atom/common/api/atom_api_clipboard.cc +++ b/atom/common/api/atom_api_clipboard.cc @@ -60,6 +60,11 @@ void Write(const mate::Dictionary& data, if (data.Get("text", &text)) writer.WriteText(text); + if (data.Get("rtf", &text)) { + std::string rtf = base::UTF16ToUTF8(text); + writer.WriteRTF(rtf); + } + if (data.Get("html", &html)) writer.WriteHTML(html, std::string()); @@ -88,6 +93,11 @@ void WriteText(const base::string16& text, mate::Arguments* args) { writer.WriteText(text); } +void WriteRtf(const std::string& text, mate::Arguments* args) { + ui::ScopedClipboardWriter writer(GetClipboardType(args)); + writer.WriteRTF(text); +} + base::string16 ReadHtml(mate::Arguments* args) { base::string16 data; base::string16 html; @@ -129,6 +139,7 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("write", &Write); dict.SetMethod("readText", &ReadText); dict.SetMethod("writeText", &WriteText); + dict.SetMethod("writeRtf", &WriteRtf); dict.SetMethod("readHtml", &ReadHtml); dict.SetMethod("writeHtml", &WriteHtml); dict.SetMethod("readImage", &ReadImage); diff --git a/docs/api/clipboard.md b/docs/api/clipboard.md index 7cb5b840bc1..a655977a0e6 100644 --- a/docs/api/clipboard.md +++ b/docs/api/clipboard.md @@ -61,6 +61,12 @@ Returns the content in the clipboard as a [NativeImage](native-image.md). Writes `image` to the clipboard. +### `clipboard.writeRtf(text)` + +* `text` String + +Writes the `text` into the clipboard in RTF. + ### `clipboard.clear([type])` * `type` String (optional) From fa4ad9d95f6ad7243783a6e7de24ce0b0f9e819d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 10:45:52 -0800 Subject: [PATCH 154/688] Tweak help message for new path options --- atom/browser/default_app/main.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/atom/browser/default_app/main.js b/atom/browser/default_app/main.js index 855d2463d25..6ff26e9ea67 100644 --- a/atom/browser/default_app/main.js +++ b/atom/browser/default_app/main.js @@ -294,9 +294,14 @@ if (option.file && !option.webdriver) { } else if (option.help) { var helpMessage = "Electron v" + process.versions.electron + " - Cross Platform Desktop Application Shell\n\n"; helpMessage += "Usage: electron [options] [path]\n\n"; - helpMessage += "A path to an Electron application may be specified. The path must be to \n"; - helpMessage += "an index.js file or to a folder containing a package.json or index.js file.\n\n"; - helpMessage += "Options:\n"; + helpMessage += "A path to an Electron application may be specified.\n"; + helpMessage += "The path must be one of the following:\n\n"; + helpMessage += " - index.js file.\n"; + helpMessage += " - Folder containing a package.json file.\n"; + helpMessage += " - Folder containing an index.js file.\n"; + helpMessage += " - .html/.htm file.\n"; + helpMessage += " - http://, https://, or file:// URL.\n"; + helpMessage += "\nOptions:\n"; helpMessage += " -r, --require Module to preload (option can be repeated)\n"; helpMessage += " -h, --help Print this usage message.\n"; helpMessage += " -v, --version Print the version."; From 45ce16b73f9daf7a87ca3982d4a9f87ad0109762 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 13:29:32 -0800 Subject: [PATCH 155/688] Remove ResEdit --- docs/tutorial/application-distribution.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/tutorial/application-distribution.md b/docs/tutorial/application-distribution.md index e8b944e7f6b..313c924e881 100644 --- a/docs/tutorial/application-distribution.md +++ b/docs/tutorial/application-distribution.md @@ -61,8 +61,7 @@ before distributing it to users. ### Windows You can rename `electron.exe` to any name you like, and edit its icon and other -information with tools like [rcedit](https://github.com/atom/rcedit) or -[ResEdit](http://www.resedit.net). +information with tools like [rcedit](https://github.com/atom/rcedit). ### OS X From bf03be35415cf308e495670545f5ac0c89c7bc6c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 4 Feb 2016 13:32:13 -0800 Subject: [PATCH 156/688] Remove ResEdit links from translations --- .../es/tutorial/application-distribution.md | 3 +-- .../jp/tutorial/application-distribution.md | 4 ++-- .../ko-KR/tutorial/application-distribution.md | 4 ++-- .../pt-BR/tutorial/application-distribution.md | 9 ++++----- .../zh-CN/tutorial/application-distribution.md | 4 ++-- .../zh-TW/tutorial/application-distribution.md | 6 +++--- 6 files changed, 14 insertions(+), 16 deletions(-) diff --git a/docs-translations/es/tutorial/application-distribution.md b/docs-translations/es/tutorial/application-distribution.md index c957332dd86..5966cdad7ec 100644 --- a/docs-translations/es/tutorial/application-distribution.md +++ b/docs-translations/es/tutorial/application-distribution.md @@ -61,8 +61,7 @@ de distribuirlo a los usuarios. ### Windows Puedes renombrar `electron.exe` a cualquier nombre que desees, y editar su ícono -y otra información con herramientas como [rcedit](https://github.com/atom/rcedit) -o [ResEdit](http://www.resedit.net). +y otra información con herramientas como [rcedit](https://github.com/atom/rcedit). ### OSX diff --git a/docs-translations/jp/tutorial/application-distribution.md b/docs-translations/jp/tutorial/application-distribution.md index 96dce25134a..f05b098514b 100644 --- a/docs-translations/jp/tutorial/application-distribution.md +++ b/docs-translations/jp/tutorial/application-distribution.md @@ -51,8 +51,8 @@ Electronにバンドルした後、ユーザーに配布する前に、 Electron ### Windows -`electron.exe`を任意の名前に変更でき、[rcedit](https://github.com/atom/rcedit) または -[ResEdit](http://www.resedit.net)のようなツールでアイコンやその他の情報を編集できます。 +`electron.exe`を任意の名前に変更でき、[rcedit](https://github.com/atom/rcedit) +のようなツールでアイコンやその他の情報を編集できます。 ### OS X diff --git a/docs-translations/ko-KR/tutorial/application-distribution.md b/docs-translations/ko-KR/tutorial/application-distribution.md index 34eb8cee71f..63533757415 100644 --- a/docs-translations/ko-KR/tutorial/application-distribution.md +++ b/docs-translations/ko-KR/tutorial/application-distribution.md @@ -60,8 +60,8 @@ electron/resources/ ### Windows `electron.exe`을 원하는 이름으로 변경할 수 있습니다. -그리고 [rcedit](https://github.com/atom/rcedit) 또는 -[ResEdit](http://www.resedit.net)를 사용하여 아이콘을 변경할 수 있습니다. +그리고 [rcedit](https://github.com/atom/rcedit) +를 사용하여 아이콘을 변경할 수 있습니다. ### OS X diff --git a/docs-translations/pt-BR/tutorial/application-distribution.md b/docs-translations/pt-BR/tutorial/application-distribution.md index 9079ba0c50b..f5a87d532c5 100644 --- a/docs-translations/pt-BR/tutorial/application-distribution.md +++ b/docs-translations/pt-BR/tutorial/application-distribution.md @@ -1,7 +1,7 @@ # Distribuição de aplicações -Para distribuir sua aplicação com o Electron, você deve nomear o diretório que contém sua aplicação como -`app` e dentro deste diretório colocar os recursos que você está utilizando (no OSX +Para distribuir sua aplicação com o Electron, você deve nomear o diretório que contém sua aplicação como +`app` e dentro deste diretório colocar os recursos que você está utilizando (no OSX `Electron.app/Contents/Resources/`, no Linux e no Windows é em `resources/`): @@ -24,7 +24,7 @@ electron/resources/app ``` Logo após execute `Electron.app` (ou `electron` no Linux e `electron.exe` no Windows), -e o Electron iniciaria a aplicação. O diretório `electron` será utilizado para criar a distribuição para +e o Electron iniciaria a aplicação. O diretório `electron` será utilizado para criar a distribuição para usuários finais. ## Empacotando sua aplicação em um arquivo. @@ -61,8 +61,7 @@ antes de distribuí-lo aos usuários. ### Windows Você pode renomear `electron.exe` para o nome que desejar e editar o seu ícone e outras -informações com ferramentas como [rcedit](https://github.com/atom/rcedit) ou -[ResEdit](http://www.resedit.net). +informações com ferramentas como [rcedit](https://github.com/atom/rcedit). ### OS X diff --git a/docs-translations/zh-CN/tutorial/application-distribution.md b/docs-translations/zh-CN/tutorial/application-distribution.md index 22a5078c1fa..dcfe4d240ee 100644 --- a/docs-translations/zh-CN/tutorial/application-distribution.md +++ b/docs-translations/zh-CN/tutorial/application-distribution.md @@ -55,12 +55,12 @@ electron/resources/ ### Windows 你可以将 `electron.exe` 改成任意你喜欢的名字,然后可以使用像 -[rcedit](https://github.com/atom/rcedit) 或者[ResEdit](http://www.resedit.net) +[rcedit](https://github.com/atom/rcedit) 编辑它的icon和其他信息。 ### OS X -你可以将 `Electron.app` 改成任意你喜欢的名字,然后你也需要修改这些文件中的 +你可以将 `Electron.app` 改成任意你喜欢的名字,然后你也需要修改这些文件中的 `CFBundleDisplayName`, `CFBundleIdentifier` 以及 `CFBundleName` 字段。 这些文件如下: diff --git a/docs-translations/zh-TW/tutorial/application-distribution.md b/docs-translations/zh-TW/tutorial/application-distribution.md index 60d32f88be0..53561ecfda6 100644 --- a/docs-translations/zh-TW/tutorial/application-distribution.md +++ b/docs-translations/zh-TW/tutorial/application-distribution.md @@ -50,8 +50,8 @@ electron/resources/ ### Windows -你可以重新命名 `electron.exe` 為任何你喜歡的名稱,然後透過像是 [rcedit](https://github.com/atom/rcedit) 或 -[ResEdit](http://www.resedit.net) 的工具來編輯它的圖示(icon)和其他資訊。 +你可以重新命名 `electron.exe` 為任何你喜歡的名稱,然後透過像是 [rcedit](https://github.com/atom/rcedit) +的工具來編輯它的圖示(icon)和其他資訊。 ### OS X @@ -60,7 +60,7 @@ electron/resources/ * `Electron.app/Contents/Info.plist` * `Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist` -你也可以重新命名 helper 應用程式來避免在活動監視器中秀出 `Electron Helper` +你也可以重新命名 helper 應用程式來避免在活動監視器中秀出 `Electron Helper` ,但請確認你有重新命名 helper 應用程式的可執行檔名稱。 重新命名後的應用程式檔案結構可能長得相這樣: From 252b12be13d2e92a93835b2e9c99ff43fedc18cd Mon Sep 17 00:00:00 2001 From: Vjekoslav Ratkajec Date: Fri, 5 Feb 2016 09:06:21 +0100 Subject: [PATCH 157/688] Add readRtf feature with appropriate spec test. Docs updated as well. --- atom/common/api/atom_api_clipboard.cc | 8 ++++++++ docs/api/clipboard.md | 10 +++++++++- spec/api-clipboard-spec.js | 12 +++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/atom/common/api/atom_api_clipboard.cc b/atom/common/api/atom_api_clipboard.cc index 5060db17e9a..5186e22c8d9 100644 --- a/atom/common/api/atom_api_clipboard.cc +++ b/atom/common/api/atom_api_clipboard.cc @@ -93,6 +93,13 @@ void WriteText(const base::string16& text, mate::Arguments* args) { writer.WriteText(text); } +base::string16 ReadRtf(mate::Arguments* args) { + std::string data; + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + clipboard->ReadRTF(GetClipboardType(args), &data); + return base::UTF8ToUTF16(data); +} + void WriteRtf(const std::string& text, mate::Arguments* args) { ui::ScopedClipboardWriter writer(GetClipboardType(args)); writer.WriteRTF(text); @@ -139,6 +146,7 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("write", &Write); dict.SetMethod("readText", &ReadText); dict.SetMethod("writeText", &WriteText); + dict.SetMethod("readRtf", &ReadRtf); dict.SetMethod("writeRtf", &WriteRtf); dict.SetMethod("readHtml", &ReadHtml); dict.SetMethod("writeHtml", &WriteHtml); diff --git a/docs/api/clipboard.md b/docs/api/clipboard.md index a655977a0e6..dcb9fa398a9 100644 --- a/docs/api/clipboard.md +++ b/docs/api/clipboard.md @@ -61,9 +61,17 @@ Returns the content in the clipboard as a [NativeImage](native-image.md). Writes `image` to the clipboard. -### `clipboard.writeRtf(text)` +### `clipboard.readRtf([type])` + +* `type` String (optional) + +Returns the content in the clipboard as RTF. + + +### `clipboard.writeRtf(text[, type])` * `text` String +* `type` String (optional) Writes the `text` into the clipboard in RTF. diff --git a/spec/api-clipboard-spec.js b/spec/api-clipboard-spec.js index 6154181f092..fe94e330d41 100644 --- a/spec/api-clipboard-spec.js +++ b/spec/api-clipboard-spec.js @@ -35,20 +35,30 @@ describe('clipboard module', function() { return assert.equal(clipboard.readHtml(), markup); }); }); + describe('clipboard.readRtf', function() { + return it('returns rtf text correctly', function() { + var rtf = "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}"; + clipboard.writeRtf(rtf); + return assert.equal(clipboard.readRtf(), rtf); + }); + }); return describe('clipboard.write()', function() { return it('returns data correctly', function() { - var i, markup, p, text; + var i, markup, p, text, rtf; text = 'test'; + rtf = '{\\rtf1\\utf8 text}'; p = path.join(fixtures, 'assets', 'logo.png'); i = nativeImage.createFromPath(p); markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; clipboard.write({ text: "test", html: 'Hi', + rtf: '{\\rtf1\\utf8 text}', image: p }); assert.equal(clipboard.readText(), text); assert.equal(clipboard.readHtml(), markup); + assert.equal(clipboard.readRtf(), rtf); return assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); }); }); From fa734d7824ae9bf1bae7fe0fad2e35fde40b1406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Aur=C3=A8le=20DARCHE?= Date: Sat, 6 Feb 2016 19:57:21 +0100 Subject: [PATCH 158/688] Document different techniques to share objects This has been discussed in --- docs/faq/electron-faq.md | 34 ++++++++++++++++++++++++++++++++++ docs/tutorial/quick-start.md | 3 +++ 2 files changed, 37 insertions(+) diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index 643bde7409b..d5470f70173 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -18,6 +18,40 @@ New features of Node.js are usually brought by V8 upgrades, since Electron is using the V8 shipped by Chrome browser, the shiny new JavaScript feature of a new Node.js version is usually already in Electron. +## What are the different techniques to share objects between web pages? + +To share objects between web pages (that is on the renderer side) the simplest +and more natural technique is to use a web standard API already available in all +browsers. A good candidate is the +[Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Storage), +through either the +[`window.localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) property or the +[`window.sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) property. +Note that the Storage API allows only to store strings, so objects must be +serialized as JSON. +Another candidate is +[IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API). + +Another technique, but this time specific to Electron, is to store objects in +the main process as a global variable and then to access them from the renderers +through the `remote` module: + +```javascript +// In main.js of browser process +global.sharedObject = {}; +``` + +```javascript +// js in page-1.html +require('remote').getGlobal('sharedObject').someProperty = 'some value'; +``` + +```javascript +// js in page-2.html +console.log(require('remote').getGlobal('sharedObject').someProperty); +``` + + ## My app's window/tray disappeared after a few minutes. This happens when the variable which is used to store the window/tray gets diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index ebf907e070f..ccb3836ba1f 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -47,6 +47,9 @@ In Electron, we have provided the [ipc](../api/ipc-renderer.md) module for communication between the main process and renderer process. There is also a [remote](../api/remote.md) module for RPC style communication. +And finally there are different techniques [to share objects between web +pages](../faq/electron-faq.md#) of the same window or of different windows. + ## Write your First Electron App Generally, an Electron app is structured like this: From 702455674bbf721f2191bf294b54a2107eb2dfd2 Mon Sep 17 00:00:00 2001 From: Michael Vasseur Date: Sun, 7 Feb 2016 10:20:38 +0100 Subject: [PATCH 159/688] Using node::Buffer::Copy() instead of node::Buffer::New() to copy the handle bytes to buffer make the buffer really contains the data. --- atom/browser/api/atom_api_window.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index bcf6ccc5a33..ea1d95b79ca 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -109,7 +109,7 @@ void TranslateOldOptions(v8::Isolate* isolate, v8::Local options) { // Converts binary data to Buffer. v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { - auto buffer = node::Buffer::New(isolate, static_cast(val), size); + auto buffer = node::Buffer::Copy(isolate, static_cast(val), size); if (buffer.IsEmpty()) return v8::Null(isolate); else From 5911c45b54e30804f2989a895a974e8588c592f5 Mon Sep 17 00:00:00 2001 From: Adam Lynch Date: Sun, 7 Feb 2016 17:31:37 +0000 Subject: [PATCH 160/688] Docs: app: small process.argv clarification --- docs/api/app.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/app.md b/docs/api/app.md index 4b5c6ee2a6a..adba230b0e2 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -87,7 +87,7 @@ handle this case (even before the `ready` event is emitted). You should call `event.preventDefault()` if you want to handle this event. -On Windows, you have to parse `process.argv` to get the filepath. +On Windows, you have to parse `process.argv` (in the main process) to get the filepath. ### Event: 'open-url' _OS X_ From 756aeffe03fabb7939a1fd156217f67dabeebc88 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 8 Feb 2016 15:18:05 -0800 Subject: [PATCH 161/688] Set icon on NSAlert when specified --- atom/browser/ui/message_box_mac.mm | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/atom/browser/ui/message_box_mac.mm b/atom/browser/ui/message_box_mac.mm index f9e9718ebf5..9380f01e384 100644 --- a/atom/browser/ui/message_box_mac.mm +++ b/atom/browser/ui/message_box_mac.mm @@ -8,7 +8,9 @@ #include "atom/browser/native_window.h" #include "base/callback.h" +#include "base/mac/mac_util.h" #include "base/strings/sys_string_conversions.h" +#include "skia/ext/skia_utils_mac.h" @interface ModalDelegate : NSObject { @private @@ -57,7 +59,8 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window, int default_id, const std::string& title, const std::string& message, - const std::string& detail) { + const std::string& detail, + const gfx::ImageSkia& icon) { // Ignore the title; it's the window title on other platforms and ignorable. NSAlert* alert = [[NSAlert alloc] init]; [alert setMessageText:base::SysUTF8ToNSString(message)]; @@ -92,6 +95,12 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window, [[ns_buttons objectAtIndex:default_id] setKeyEquivalent:@"\r"]; } + if (!icon.isNull()) { + NSImage* image = gfx::SkBitmapToNSImageWithColorSpace( + *icon.bitmap(), base::mac::GetGenericRGBColorSpace()); + [alert setIcon:image]; + } + return alert; } @@ -113,7 +122,7 @@ int ShowMessageBox(NativeWindow* parent_window, const gfx::ImageSkia& icon) { NSAlert* alert = CreateNSAlert( parent_window, type, buttons, default_id, title, message, - detail); + detail, icon); // Use runModal for synchronous alert without parent, since we don't have a // window to wait for. @@ -149,7 +158,7 @@ void ShowMessageBox(NativeWindow* parent_window, const MessageBoxCallback& callback) { NSAlert* alert = CreateNSAlert( parent_window, type, buttons, default_id, title, message, - detail); + detail, icon); ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback andAlert:alert callEndModal:false]; From a8ae14e94f10e86ed8105ab6c8d0dabf79f40218 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Tue, 9 Feb 2016 01:17:05 +0100 Subject: [PATCH 162/688] Introducing a will-enter-full-screen event that's cancellable --- atom/browser/api/atom_api_window.cc | 4 ++++ atom/browser/api/atom_api_window.h | 1 + atom/browser/native_window.cc | 7 +++++++ atom/browser/native_window.h | 3 +++ atom/browser/native_window_mac.mm | 3 +++ atom/browser/native_window_observer.h | 1 + atom/browser/native_window_views.cc | 25 +++++++++++++++++-------- 7 files changed, 36 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index bcf6ccc5a33..3a3b3c6efc8 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -219,6 +219,10 @@ void Window::OnWindowMoved() { Emit("moved"); } +void Window::OnWindowWillEnterFullScreen(bool* prevent_default) { + *prevent_default = Emit("will-enter-full-screen"); +} + void Window::OnWindowEnterFullScreen() { Emit("enter-full-screen"); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 641124f4dfd..2d1e6d71ec3 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -67,6 +67,7 @@ class Window : public mate::TrackableObject, void OnWindowMoved() override; void OnWindowScrollTouchBegin() override; void OnWindowScrollTouchEnd() override; + void OnWindowWillEnterFullScreen(bool* prevent_default) override; void OnWindowEnterFullScreen() override; void OnWindowLeaveFullScreen() override; void OnWindowEnterHtmlFullScreen() override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c25534f7f18..a09705fbd96 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -445,6 +445,13 @@ void NativeWindow::NotifyWindowMoved() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowMoved()); } +bool NativeWindow::RequestEnterFullScreen() { + bool prevent_default = false; + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnWindowWillEnterFullScreen(&prevent_default)); + return prevent_default; +} + void NativeWindow::NotifyWindowEnterFullScreen() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowEnterFullScreen()); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 09fae6c6bcf..4cc04e790e1 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -197,6 +197,9 @@ class NativeWindow : public base::SupportsUserData, // Requests the WebContents to close, can be cancelled by the page. virtual void RequestToClosePage(); + // Request the WebContents to go fullscreen, can be cancelled by the page. + virtual bool RequestEnterFullScreen(); + // Methods called by the WebContents. virtual void CloseContents(content::WebContents* source); virtual void RendererUnresponsive(content::WebContents* source); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 7967a177173..aa0dde4c486 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -602,6 +602,9 @@ void NativeWindowMac::SetFullScreen(bool fullscreen) { if (fullscreen == IsFullscreen()) return; + if (fullscreen && shell_->RequestEnterFullScreen()) + return; + if (!base::mac::IsOSLionOrLater()) { LOG(ERROR) << "Fullscreen mode is only supported above Lion"; return; diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 4af181085a0..1f66bac5b63 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -52,6 +52,7 @@ class NativeWindowObserver { virtual void OnWindowMoved() {} virtual void OnWindowScrollTouchBegin() {} virtual void OnWindowScrollTouchEnd() {} + virtual void OnWindowWillEnterFullScreen(bool* prevent_default) {} virtual void OnWindowEnterFullScreen() {} virtual void OnWindowLeaveFullScreen() {} virtual void OnWindowEnterHtmlFullScreen() {} diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 44df87da9fb..101c57515af 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -347,24 +347,33 @@ bool NativeWindowViews::IsMinimized() { } void NativeWindowViews::SetFullScreen(bool fullscreen) { + bool prevent_default = false; + if (fullscreen) + prevent_default = RequestEnterFullScreen(); + #if defined(OS_WIN) // There is no native fullscreen state on Windows. if (fullscreen) { - last_window_state_ = ui::SHOW_STATE_FULLSCREEN; - NotifyWindowEnterFullScreen(); + if (!prevent_default) { + last_window_state_ = ui::SHOW_STATE_FULLSCREEN; + NotifyWindowEnterFullScreen(); + } } else { last_window_state_ = ui::SHOW_STATE_NORMAL; NotifyWindowLeaveFullScreen(); } // We set the new value after notifying, so we can handle the size event // correctly. - window_->SetFullscreen(fullscreen); -#else - if (IsVisible()) + if (!prevent_default) window_->SetFullscreen(fullscreen); - else - window_->native_widget_private()->ShowWithWindowState( - ui::SHOW_STATE_FULLSCREEN); +#else + if (!(fullscreen && prevent_default)) { + if (IsVisible()) + window_->SetFullscreen(fullscreen); + else + window_->native_widget_private()->ShowWithWindowState( + ui::SHOW_STATE_FULLSCREEN); + } #endif } From 664f95a7b4e8bb5b2850fa19e841805b2ebb055a Mon Sep 17 00:00:00 2001 From: gellert Date: Tue, 9 Feb 2016 01:39:27 +0100 Subject: [PATCH 163/688] fixes osx request call --- atom/browser/native_window_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index aa0dde4c486..f4f5a8c9789 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -602,7 +602,7 @@ void NativeWindowMac::SetFullScreen(bool fullscreen) { if (fullscreen == IsFullscreen()) return; - if (fullscreen && shell_->RequestEnterFullScreen()) + if (fullscreen && RequestEnterFullScreen()) return; if (!base::mac::IsOSLionOrLater()) { From 157a290e38ecd8416ffcaf558b1d734c276b8de4 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Tue, 9 Feb 2016 02:41:19 +0100 Subject: [PATCH 164/688] :memo: Adding documentation for will-enter-full-screen event --- docs/api/browser-window.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 7cf684a3953..827bb84db81 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -276,6 +276,11 @@ __Note__: On OS X this event is just an alias of `moved`. Emitted once when the window is moved to a new position. +### Event: 'will-enter-full-screen' + +Emitted when the window is about to enter full screen state. Calling `event.preventDefault()` +will cancel the state change. + ### Event: 'enter-full-screen' Emitted when the window enters full screen state. From c842ca1f127cb6e9b1850929c7b6a319c323536b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 09:52:04 -0800 Subject: [PATCH 165/688] Don't use ES6 class for AutoUpdater windows class --- .../api/lib/auto-updater/auto-updater-win.js | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/atom/browser/api/lib/auto-updater/auto-updater-win.js b/atom/browser/api/lib/auto-updater/auto-updater-win.js index f8a07902f21..1c81763f35e 100644 --- a/atom/browser/api/lib/auto-updater/auto-updater-win.js +++ b/atom/browser/api/lib/auto-updater/auto-updater-win.js @@ -4,59 +4,59 @@ const app = require('electron').app; const EventEmitter = require('events').EventEmitter; const squirrelUpdate = require('./squirrel-update-win'); -class AutoUpdater extends EventEmitter { - constructor() { - super(); - } +function AutoUpdater() { + EventEmitter.call(this) +} - quitAndInstall() { - squirrelUpdate.processStart(); - return app.quit(); - } +require('util').inherits(AutoUpdater, EventEmitter); - setFeedURL(updateURL) { - return this.updateURL = updateURL; - } +AutoUpdater.prototype.quitAndInstall = function() { + squirrelUpdate.processStart(); + return app.quit(); +} - checkForUpdates() { - if (!this.updateURL) { - return this.emitError('Update URL is not set'); - } - if (!squirrelUpdate.supported()) { - return this.emitError('Can not find Squirrel'); - } - this.emit('checking-for-update'); - return squirrelUpdate.download(this.updateURL, (function(_this) { - return function(error, update) { +AutoUpdater.prototype.setFeedURL = function(updateURL) { + return this.updateURL = updateURL; +} + +AutoUpdater.prototype.checkForUpdates = function() { + if (!this.updateURL) { + return this.emitError('Update URL is not set'); + } + if (!squirrelUpdate.supported()) { + return this.emitError('Can not find Squirrel'); + } + this.emit('checking-for-update'); + return squirrelUpdate.download(this.updateURL, (function(_this) { + return function(error, update) { + if (error != null) { + return _this.emitError(error); + } + if (update == null) { + return _this.emit('update-not-available'); + } + _this.emit('update-available'); + return squirrelUpdate.update(_this.updateURL, function(error) { + var date, releaseNotes, version; if (error != null) { return _this.emitError(error); } - if (update == null) { - return _this.emit('update-not-available'); - } - _this.emit('update-available'); - return squirrelUpdate.update(_this.updateURL, function(error) { - var date, releaseNotes, version; - if (error != null) { - return _this.emitError(error); - } - releaseNotes = update.releaseNotes, version = update.version; + releaseNotes = update.releaseNotes, version = update.version; - // Following information is not available on Windows, so fake them. - date = new Date; - return _this.emit('update-downloaded', {}, releaseNotes, version, date, _this.updateURL, function() { - return _this.quitAndInstall(); - }); + // Following information is not available on Windows, so fake them. + date = new Date; + return _this.emit('update-downloaded', {}, releaseNotes, version, date, _this.updateURL, function() { + return _this.quitAndInstall(); }); - }; - })(this)); - } + }); + }; + })(this)); +} - // Private: Emit both error object and message, this is to keep compatibility - // with Old APIs. - emitError(message) { - return this.emit('error', new Error(message), message); - } +// Private: Emit both error object and message, this is to keep compatibility +// with Old APIs. +AutoUpdater.prototype.emitError = (message) { + return this.emit('error', new Error(message), message); } module.exports = new AutoUpdater; From 6617592224a9e57e0513e9e05ed59e8a235d67d6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 10:01:01 -0800 Subject: [PATCH 166/688] Remove lint errors --- .../browser/api/lib/auto-updater/auto-updater-win.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/atom/browser/api/lib/auto-updater/auto-updater-win.js b/atom/browser/api/lib/auto-updater/auto-updater-win.js index 1c81763f35e..f5f2202f58d 100644 --- a/atom/browser/api/lib/auto-updater/auto-updater-win.js +++ b/atom/browser/api/lib/auto-updater/auto-updater-win.js @@ -5,7 +5,7 @@ const EventEmitter = require('events').EventEmitter; const squirrelUpdate = require('./squirrel-update-win'); function AutoUpdater() { - EventEmitter.call(this) + EventEmitter.call(this); } require('util').inherits(AutoUpdater, EventEmitter); @@ -13,11 +13,11 @@ require('util').inherits(AutoUpdater, EventEmitter); AutoUpdater.prototype.quitAndInstall = function() { squirrelUpdate.processStart(); return app.quit(); -} +}; AutoUpdater.prototype.setFeedURL = function(updateURL) { return this.updateURL = updateURL; -} +}; AutoUpdater.prototype.checkForUpdates = function() { if (!this.updateURL) { @@ -51,12 +51,12 @@ AutoUpdater.prototype.checkForUpdates = function() { }); }; })(this)); -} +}; // Private: Emit both error object and message, this is to keep compatibility // with Old APIs. -AutoUpdater.prototype.emitError = (message) { +AutoUpdater.prototype.emitError = function(message) { return this.emit('error', new Error(message), message); -} +}; module.exports = new AutoUpdater; From 7da4c3acf7b2ac901ef5c5ff2828cec55e434c09 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 11:00:34 -0800 Subject: [PATCH 167/688] Use const for util require --- atom/browser/api/lib/auto-updater/auto-updater-win.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/lib/auto-updater/auto-updater-win.js b/atom/browser/api/lib/auto-updater/auto-updater-win.js index f5f2202f58d..1270f8f2bdb 100644 --- a/atom/browser/api/lib/auto-updater/auto-updater-win.js +++ b/atom/browser/api/lib/auto-updater/auto-updater-win.js @@ -3,12 +3,13 @@ const app = require('electron').app; const EventEmitter = require('events').EventEmitter; const squirrelUpdate = require('./squirrel-update-win'); +const util = require('util'); function AutoUpdater() { EventEmitter.call(this); } -require('util').inherits(AutoUpdater, EventEmitter); +util.inherits(AutoUpdater, EventEmitter); AutoUpdater.prototype.quitAndInstall = function() { squirrelUpdate.processStart(); From 3ab14e14e9fae0a78ff7f9e88ac7087b87ef1182 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 3 Feb 2016 12:53:56 -0800 Subject: [PATCH 168/688] Add initial auto updater specs --- spec/api-auto-updater-spec.js | 34 ++++++++++++++++++++++++++++++++++ spec/static/main.js | 5 +++++ 2 files changed, 39 insertions(+) create mode 100644 spec/api-auto-updater-spec.js diff --git a/spec/api-auto-updater-spec.js b/spec/api-auto-updater-spec.js new file mode 100644 index 00000000000..72a1d90a7fe --- /dev/null +++ b/spec/api-auto-updater-spec.js @@ -0,0 +1,34 @@ +const assert = require('assert'); +const autoUpdater = require('electron').remote.autoUpdater; +const ipcRenderer = require('electron').ipcRenderer; + +describe('autoUpdater module', function() { + describe('checkForUpdates', function() { + it('emits an error on Windows when called the feed URL is not set', function (done) { + if (process.platform !== 'win32') { + return done(); + } + + ipcRenderer.once('auto-updater-error', function(event, message) { + assert.equal(message, 'Update URL is not set'); + done(); + }); + autoUpdater.setFeedURL(''); + autoUpdater.checkForUpdates(); + }); + }); + + describe('setFeedURL', function() { + it('emits an error on Mac OS X when the application is unsigned', function (done) { + if (process.platform !== 'darwin') { + return done(); + } + + ipcRenderer.once('auto-updater-error', function(event, message) { + assert.equal(message, 'Could not get code signature for running application'); + done(); + }); + autoUpdater.setFeedURL(''); + }); + }); +}); diff --git a/spec/static/main.js b/spec/static/main.js index 13d2dd6a6e1..125ef72f609 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -72,6 +72,11 @@ app.on('ready', function() { // Test if using protocol module would crash. electron.protocol.registerStringProtocol('test-if-crashes', function() {}); + // Send auto updater errors to window to be verified in specs + electron.autoUpdater.on('error', function (error) { + window.send('auto-updater-error', error.message) + }); + window = new BrowserWindow({ title: 'Electron Tests', show: false, From 16594d6ed08240cf4c26b00c3e779095957bd541 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 10 Feb 2016 09:37:44 -0800 Subject: [PATCH 169/688] Add bootstrap script --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 3f0983bc441..218454372fb 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "lint": "python ./script/eslint.py && python ./script/cpplint.py", "preinstall": "node -e 'process.exit(0)'", "start": "python ./script/start.py", - "test": "python ./script/test.py" + "test": "python ./script/test.py", + "bootstrap": "python ./script/bootstrap.py" } } From 03482a442728c7222a6fb38a0346b0395e690461 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 10 Feb 2016 09:39:22 -0800 Subject: [PATCH 170/688] Add build script --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 218454372fb..2060e54a1e3 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "preinstall": "node -e 'process.exit(0)'", "start": "python ./script/start.py", "test": "python ./script/test.py", - "bootstrap": "python ./script/bootstrap.py" + "bootstrap": "python ./script/bootstrap.py", + "build": "python ./script/build.py -c D" } } From a8e6e24e58f7bdcd2fecd6e70379aa23baeedeca Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 10 Feb 2016 09:43:29 -0800 Subject: [PATCH 171/688] Sort scripts keys --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2060e54a1e3..6d812087199 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,11 @@ }, "private": true, "scripts": { + "bootstrap": "python ./script/bootstrap.py", + "build": "python ./script/build.py -c D", "lint": "python ./script/eslint.py && python ./script/cpplint.py", "preinstall": "node -e 'process.exit(0)'", "start": "python ./script/start.py", - "test": "python ./script/test.py", - "bootstrap": "python ./script/bootstrap.py", - "build": "python ./script/build.py -c D" + "test": "python ./script/test.py" } } From 5a8bebc2f8faf6a84073e7dd27fd519a14e5ce67 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 11 Feb 2016 08:24:50 +0530 Subject: [PATCH 172/688] browser: emit did-fail-load for invalid url --- atom/browser/api/atom_api_web_contents.cc | 8 ++++++++ spec/api-browser-window-spec.js | 17 +++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 80e5b606ef8..a7946786c51 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -710,6 +710,14 @@ bool WebContents::Equal(const WebContents* web_contents) const { } void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { + if (!url.is_valid()) { + Emit("did-fail-load", + static_cast(net::ERR_INVALID_URL), + net::ErrorToShortString(net::ERR_INVALID_URL), + url.possibly_invalid_spec()); + return; + } + content::NavigationController::LoadURLParams params(url); GURL http_referrer; diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index fc8d3523c8f..72d28bcb6ed 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -94,11 +94,20 @@ describe('browser-window module', function() { }); return w.loadURL('about:blank'); }); - return it('should emit did-fail-load event', function(done) { - w.webContents.on('did-fail-load', function() { - return done(); + it('should emit did-fail-load event for files that do not exist', function(done) { + w.webContents.on('did-fail-load', function(event, code) { + assert.equal(code, -6); + done(); }); - return w.loadURL('file://a.txt'); + w.loadURL('file://a.txt'); + }); + it('should emit did-fail-load event for invalid URL', function(done) { + w.webContents.on('did-fail-load', function(event, code, desc) { + assert.equal(desc, 'ERR_INVALID_URL'); + assert.equal(code, -300); + done(); + }); + w.loadURL('http://example:port'); }); }); describe('BrowserWindow.show()', function() { From 6d2ad5ae5881c2d4af9b41a69eef3e5e83814b60 Mon Sep 17 00:00:00 2001 From: Kevin Jose Martin Date: Thu, 11 Feb 2016 15:34:19 -0500 Subject: [PATCH 173/688] Add ability to specify command line switches in package.json --- atom/browser/lib/init.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/atom/browser/lib/init.js b/atom/browser/lib/init.js index 272cebbf875..df0f1b6685a 100644 --- a/atom/browser/lib/init.js +++ b/atom/browser/lib/init.js @@ -132,6 +132,19 @@ if (packageJson.desktopName != null) { // Chrome 42 disables NPAPI plugins by default, reenable them here app.commandLine.appendSwitch('enable-npapi'); +// Add othercommand line switches +if (packageJson.commandLineSwitches) { + for (let i = 0; i < packageJson.commandLineSwitches.length; ++i) { + const option = packageJson.commandLineSwitches[i]; + + if (typeof option === 'string') { + app.commandLine.appendSwitch(option); + } else { + app.commandLine.appendSwitch(option[0], option[1]); + } + } +} + // Set the user path according to application's name. app.setPath('userData', path.join(app.getPath('appData'), app.getName())); From dbb4e21684a37ce20553c4b04672937d2e6ff887 Mon Sep 17 00:00:00 2001 From: Kevin Jose Martin Date: Thu, 11 Feb 2016 15:41:36 -0500 Subject: [PATCH 174/688] Fix index increment --- atom/browser/lib/init.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/lib/init.js b/atom/browser/lib/init.js index df0f1b6685a..b687aa6eeda 100644 --- a/atom/browser/lib/init.js +++ b/atom/browser/lib/init.js @@ -132,9 +132,9 @@ if (packageJson.desktopName != null) { // Chrome 42 disables NPAPI plugins by default, reenable them here app.commandLine.appendSwitch('enable-npapi'); -// Add othercommand line switches +// Add other command line switches if (packageJson.commandLineSwitches) { - for (let i = 0; i < packageJson.commandLineSwitches.length; ++i) { + for (let i = 0; i < packageJson.commandLineSwitches.length; i++) { const option = packageJson.commandLineSwitches[i]; if (typeof option === 'string') { From 55d4db1387c4f97dc72b00d8524d64dbfa8feeb8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Feb 2016 10:03:49 -0800 Subject: [PATCH 175/688] :art: --- atom/browser/api/lib/web-contents.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index 709694bcf72..08252923fc2 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -76,8 +76,8 @@ let wrapWebContents = function(webContents) { // WebContents::send(channel, args..) webContents.send = function() { - var args, channel; - channel = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + var args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + var channel = arguments[0]; return this._send(channel, slice.call(args)); }; From 4828835998f05e2b59d2ff48a17768472de6636a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Feb 2016 10:12:45 -0800 Subject: [PATCH 176/688] Clean up returns after CoffeeScript migration --- spec/api-browser-window-spec.js | 240 +++++++++++++++++++------------- 1 file changed, 140 insertions(+), 100 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index fc8d3523c8f..69b895c366d 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -14,29 +14,31 @@ const BrowserWindow = remote.require('electron').BrowserWindow; const isCI = remote.getGlobal('isCi'); describe('browser-window module', function() { - var fixtures, w; - fixtures = path.resolve(__dirname, 'fixtures'); - w = null; + var fixtures = path.resolve(__dirname, 'fixtures'); + var w = null; + beforeEach(function() { if (w != null) { w.destroy(); } - return w = new BrowserWindow({ + w = new BrowserWindow({ show: false, width: 400, height: 400 }); }); + afterEach(function() { if (w != null) { w.destroy(); } - return w = null; + w = null; }); + describe('BrowserWindow.close()', function() { it('should emit unload handler', function(done) { w.webContents.on('did-finish-load', function() { - return w.close(); + w.close(); }); w.on('closed', function() { var content, test; @@ -44,20 +46,22 @@ describe('browser-window module', function() { content = fs.readFileSync(test); fs.unlinkSync(test); assert.equal(String(content), 'unload'); - return done(); + done(); }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'unload.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'unload.html')); }); - return it('should emit beforeunload handler', function(done) { + + it('should emit beforeunload handler', function(done) { w.on('onbeforeunload', function() { - return done(); + done(); }); w.webContents.on('did-finish-load', function() { - return w.close(); + w.close(); }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'beforeunload-false.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'beforeunload-false.html')); }); }); + describe('window.close()', function() { it('should emit unload handler', function(done) { w.on('closed', function() { @@ -66,104 +70,113 @@ describe('browser-window module', function() { content = fs.readFileSync(test); fs.unlinkSync(test); assert.equal(String(content), 'close'); - return done(); + done(); }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'close.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'close.html')); }); - return it('should emit beforeunload handler', function(done) { + + it('should emit beforeunload handler', function(done) { w.on('onbeforeunload', function() { - return done(); + done(); }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html')); }); }); + describe('BrowserWindow.destroy()', function() { - return it('prevents users to access methods of webContents', function() { + it('prevents users to access methods of webContents', function() { var webContents; webContents = w.webContents; w.destroy(); - return assert.throws((function() { - return webContents.getId(); + assert.throws((function() { + webContents.getId(); }), /Object has been destroyed/); }); }); + describe('BrowserWindow.loadURL(url)', function() { it('should emit did-start-loading event', function(done) { w.webContents.on('did-start-loading', function() { - return done(); + done(); }); - return w.loadURL('about:blank'); + w.loadURL('about:blank'); }); - return it('should emit did-fail-load event', function(done) { + + it('should emit did-fail-load event', function(done) { w.webContents.on('did-fail-load', function() { - return done(); + done(); }); - return w.loadURL('file://a.txt'); + w.loadURL('file://a.txt'); }); }); + describe('BrowserWindow.show()', function() { - return it('should focus on window', function() { + it('should focus on window', function() { if (isCI) { return; } + w.show(); - return assert(w.isFocused()); + assert(w.isFocused()); }); }); + describe('BrowserWindow.showInactive()', function() { - return it('should not focus on window', function() { + it('should not focus on window', function() { w.showInactive(); - return assert(!w.isFocused()); + assert(!w.isFocused()); }); }); + describe('BrowserWindow.focus()', function() { - return it('does not make the window become visible', function() { + it('does not make the window become visible', function() { assert.equal(w.isVisible(), false); w.focus(); - return assert.equal(w.isVisible(), false); + assert.equal(w.isVisible(), false); }); }); + describe('BrowserWindow.capturePage(rect, callback)', function() { - return it('calls the callback with a Buffer', function(done) { - return w.capturePage({ + it('calls the callback with a Buffer', function(done) { + w.capturePage({ x: 0, y: 0, width: 100, height: 100 }, function(image) { assert.equal(image.isEmpty(), true); - return done(); + done(); }); }); }); + describe('BrowserWindow.setSize(width, height)', function() { - return it('sets the window size', function(done) { - var size; - size = [300, 400]; + it('sets the window size', function(done) { + var size = [300, 400]; w.once('resize', function() { - var newSize; - newSize = w.getSize(); + var newSize = w.getSize(); assert.equal(newSize[0], size[0]); assert.equal(newSize[1], size[1]); - return done(); + done(); }); - return w.setSize(size[0], size[1]); + w.setSize(size[0], size[1]); }); }); + describe('BrowserWindow.setPosition(x, y)', function() { - return it('sets the window position', function(done) { - var pos; - pos = [10, 10]; + it('sets the window position', function(done) { + var pos = [10, 10]; w.once('move', function() { var newPos; newPos = w.getPosition(); assert.equal(newPos[0], pos[0]); assert.equal(newPos[1], pos[1]); - return done(); + done(); }); - return w.setPosition(pos[0], pos[1]); + w.setPosition(pos[0], pos[1]); }); }); + describe('BrowserWindow.setContentSize(width, height)', function() { it('sets the content size', function() { var after, size; @@ -171,9 +184,10 @@ describe('browser-window module', function() { w.setContentSize(size[0], size[1]); after = w.getContentSize(); assert.equal(after[0], size[0]); - return assert.equal(after[1], size[1]); + assert.equal(after[1], size[1]); }); - return it('works for framless window', function() { + + it('works for framless window', function() { var after, size; w.destroy(); w = new BrowserWindow({ @@ -186,14 +200,16 @@ describe('browser-window module', function() { w.setContentSize(size[0], size[1]); after = w.getContentSize(); assert.equal(after[0], size[0]); - return assert.equal(after[1], size[1]); + assert.equal(after[1], size[1]); }); }); + describe('BrowserWindow.fromId(id)', function() { - return it('returns the window with id', function() { - return assert.equal(w.id, BrowserWindow.fromId(w.id).id); + it('returns the window with id', function() { + assert.equal(w.id, BrowserWindow.fromId(w.id).id); }); }); + describe('"useContentSize" option', function() { it('make window created with content size when used', function() { var contentSize; @@ -206,15 +222,16 @@ describe('browser-window module', function() { }); contentSize = w.getContentSize(); assert.equal(contentSize[0], 400); - return assert.equal(contentSize[1], 400); + assert.equal(contentSize[1], 400); }); + it('make window created with window size when not used', function() { - var size; - size = w.getSize(); + var size = w.getSize(); assert.equal(size[0], 400); - return assert.equal(size[1], 400); + assert.equal(size[1], 400); }); - return it('works for framless window', function() { + + it('works for framless window', function() { var contentSize, size; w.destroy(); w = new BrowserWindow({ @@ -229,9 +246,10 @@ describe('browser-window module', function() { assert.equal(contentSize[1], 400); size = w.getSize(); assert.equal(size[0], 400); - return assert.equal(size[1], 400); + assert.equal(size[1], 400); }); }); + describe('"title-bar-style" option', function() { if (process.platform !== 'darwin') { return; @@ -239,6 +257,7 @@ describe('browser-window module', function() { if (parseInt(os.release().split('.')[0]) < 14) { return; } + it('creates browser window with hidden title bar', function() { var contentSize; w.destroy(); @@ -249,9 +268,10 @@ describe('browser-window module', function() { titleBarStyle: 'hidden' }); contentSize = w.getContentSize(); - return assert.equal(contentSize[1], 400); + assert.equal(contentSize[1], 400); }); - return it('creates browser window with hidden inset title bar', function() { + + it('creates browser window with hidden inset title bar', function() { var contentSize; w.destroy(); w = new BrowserWindow({ @@ -261,30 +281,34 @@ describe('browser-window module', function() { titleBarStyle: 'hidden-inset' }); contentSize = w.getContentSize(); - return assert.equal(contentSize[1], 400); + assert.equal(contentSize[1], 400); }); }); + describe('"enableLargerThanScreen" option', function() { if (process.platform === 'linux') { return; } + beforeEach(function() { w.destroy(); - return w = new BrowserWindow({ + w = new BrowserWindow({ show: true, width: 400, height: 400, enableLargerThanScreen: true }); }); + it('can move the window out of screen', function() { var after; w.setPosition(-10, -10); after = w.getPosition(); assert.equal(after[0], -10); - return assert.equal(after[1], -10); + assert.equal(after[1], -10); }); - return it('can set the window larger than screen', function() { + + it('can set the window larger than screen', function() { var after, size; size = screen.getPrimaryDisplay().size; size.width += 100; @@ -292,21 +316,22 @@ describe('browser-window module', function() { w.setSize(size.width, size.height); after = w.getSize(); assert.equal(after[0], size.width); - return assert.equal(after[1], size.height); + assert.equal(after[1], size.height); }); }); describe('"web-preferences" option', function() { afterEach(function() { - return ipcMain.removeAllListeners('answer'); + ipcMain.removeAllListeners('answer'); }); + describe('"preload" option', function() { - return it('loads the script before other scripts in window', function(done) { + it('loads the script before other scripts in window', function(done) { var preload; preload = path.join(fixtures, 'module', 'set-global.js'); ipcMain.once('answer', function(event, test) { assert.equal(test, 'preload'); - return done(); + done(); }); w.destroy(); w = new BrowserWindow({ @@ -315,16 +340,17 @@ describe('browser-window module', function() { preload: preload } }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'preload.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'preload.html')); }); }); - return describe('"node-integration" option', function() { - return it('disables node integration when specified to false', function(done) { + + describe('"node-integration" option', function() { + it('disables node integration when specified to false', function(done) { var preload; preload = path.join(fixtures, 'module', 'send-later.js'); ipcMain.once('answer', function(event, test) { assert.equal(test, 'undefined'); - return done(); + done(); }); w.destroy(); w = new BrowserWindow({ @@ -334,107 +360,121 @@ describe('browser-window module', function() { nodeIntegration: false } }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'blank.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'blank.html')); }); }); }); + describe('beforeunload handler', function() { it('returning true would not prevent close', function(done) { w.on('closed', function() { - return done(); + done(); }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-true.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-true.html')); }); + it('returning non-empty string would not prevent close', function(done) { w.on('closed', function() { - return done(); + done(); }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-string.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-string.html')); }); + it('returning false would prevent close', function(done) { w.on('onbeforeunload', function() { - return done(); + done(); }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html')); }); - return it('returning empty string would prevent close', function(done) { + + it('returning empty string would prevent close', function(done) { w.on('onbeforeunload', function() { - return done(); + done(); }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-empty-string.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-empty-string.html')); }); }); + describe('new-window event', function() { if (isCI && process.platform === 'darwin') { return; } + it('emits when window.open is called', function(done) { w.webContents.once('new-window', function(e, url, frameName) { e.preventDefault(); assert.equal(url, 'http://host/'); assert.equal(frameName, 'host'); - return done(); + done(); }); - return w.loadURL("file://" + fixtures + "/pages/window-open.html"); + w.loadURL("file://" + fixtures + "/pages/window-open.html"); }); - return it('emits when link with target is called', function(done) { + + it('emits when link with target is called', function(done) { this.timeout(10000); w.webContents.once('new-window', function(e, url, frameName) { e.preventDefault(); assert.equal(url, 'http://host/'); assert.equal(frameName, 'target'); - return done(); + done(); }); - return w.loadURL("file://" + fixtures + "/pages/target-name.html"); + w.loadURL("file://" + fixtures + "/pages/target-name.html"); }); }); + describe('maximize event', function() { if (isCI) { return; } - return it('emits when window is maximized', function(done) { + + it('emits when window is maximized', function(done) { this.timeout(10000); w.once('maximize', function() { - return done(); + done(); }); w.show(); - return w.maximize(); + w.maximize(); }); }); + describe('unmaximize event', function() { if (isCI) { return; } - return it('emits when window is unmaximized', function(done) { + + it('emits when window is unmaximized', function(done) { this.timeout(10000); w.once('unmaximize', function() { - return done(); + done(); }); w.show(); w.maximize(); - return w.unmaximize(); + w.unmaximize(); }); }); + describe('minimize event', function() { if (isCI) { return; } - return it('emits when window is minimized', function(done) { + + it('emits when window is minimized', function(done) { this.timeout(10000); w.once('minimize', function() { - return done(); + done(); }); w.show(); - return w.minimize(); + w.minimize(); }); }); + xdescribe('beginFrameSubscription method', function() { - return it('subscribes frame updates', function(done) { + it('subscribes frame updates', function(done) { w.loadURL("file://" + fixtures + "/api/blank.html"); - return w.webContents.beginFrameSubscription(function(data) { + w.webContents.beginFrameSubscription(function(data) { assert.notEqual(data.length, 0); w.webContents.endFrameSubscription(); - return done(); + done(); }); }); }); @@ -472,13 +512,13 @@ describe('browser-window module', function() { }); describe('BrowserWindow options argument is optional', function() { - return it('should create a window with default size (800x600)', function() { + it('should create a window with default size (800x600)', function() { var size; w.destroy(); w = new BrowserWindow(); size = w.getSize(); assert.equal(size[0], 800); - return assert.equal(size[1], 600); + assert.equal(size[1], 600); }); }); From cead84d5d118bfc6b6a8d5418474959fd3021c54 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Feb 2016 10:18:01 -0800 Subject: [PATCH 177/688] Add failing spec --- spec/api-browser-window-spec.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 69b895c366d..d91e9d410e0 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -658,4 +658,12 @@ describe('browser-window module', function() { }); }); }); + + describe('window.webContents.send(channel, args...)', function() { + it('throws an error when the channel is missing', function() { + assert.throws(function () { + w.webContents.send(); + }, 'channel must be specified'); + }); + }); }); From c94f1fc857e0c07303e60d8df0e89e48808f207c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Feb 2016 10:20:55 -0800 Subject: [PATCH 178/688] Throw error when IPC channel is missing --- atom/browser/api/lib/web-contents.js | 3 +++ spec/api-browser-window-spec.js | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index 08252923fc2..8dde10df4d1 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -78,6 +78,9 @@ let wrapWebContents = function(webContents) { webContents.send = function() { var args = 2 <= arguments.length ? slice.call(arguments, 1) : []; var channel = arguments[0]; + if (channel == null) { + throw new Error('channel must be specified'); + } return this._send(channel, slice.call(args)); }; diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index d91e9d410e0..ee34ba2c576 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -664,6 +664,10 @@ describe('browser-window module', function() { assert.throws(function () { w.webContents.send(); }, 'channel must be specified'); + + assert.throws(function () { + w.webContents.send(null); + }, 'channel must be specified'); }); }); }); From 3e399d09d7bdcd21154f65a233e487ca2c65c15f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Feb 2016 10:24:48 -0800 Subject: [PATCH 179/688] Match existing function style --- spec/api-browser-window-spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index ee34ba2c576..cb041a9320d 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -661,11 +661,11 @@ describe('browser-window module', function() { describe('window.webContents.send(channel, args...)', function() { it('throws an error when the channel is missing', function() { - assert.throws(function () { + assert.throws(function() { w.webContents.send(); }, 'channel must be specified'); - assert.throws(function () { + assert.throws(function() { w.webContents.send(null); }, 'channel must be specified'); }); From 704bd4d191a399107a0a3ea187628a851940adb5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Feb 2016 10:34:50 -0800 Subject: [PATCH 180/688] Improve error message --- atom/browser/api/lib/web-contents.js | 2 +- spec/api-browser-window-spec.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index 8dde10df4d1..e0c16999c72 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -79,7 +79,7 @@ let wrapWebContents = function(webContents) { var args = 2 <= arguments.length ? slice.call(arguments, 1) : []; var channel = arguments[0]; if (channel == null) { - throw new Error('channel must be specified'); + throw new Error('Missing required channel argument'); } return this._send(channel, slice.call(args)); }; diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index cb041a9320d..d59eb9a8baa 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -663,11 +663,11 @@ describe('browser-window module', function() { it('throws an error when the channel is missing', function() { assert.throws(function() { w.webContents.send(); - }, 'channel must be specified'); + }, 'Missing required channel argument'); assert.throws(function() { w.webContents.send(null); - }, 'channel must be specified'); + }, 'Missing required channel argument'); }); }); }); From a4d21cadfa3d6a7e706d1bae61b424e599301c08 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 5 Feb 2016 10:27:05 -0800 Subject: [PATCH 181/688] Format webview spec post CoffeeScript conversion --- spec/webview-spec.js | 335 ++++++++++++++++++++++++------------------- 1 file changed, 188 insertions(+), 147 deletions(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index cac5fb56b44..904dfcab6e0 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -1,166 +1,175 @@ -var assert, http, path, url; - -assert = require('assert'); - -path = require('path'); - -http = require('http'); - -url = require('url'); +const assert = require('assert'); +const path = require('path'); +const http = require('http'); +const url = require('url'); describe(' tag', function() { - var fixtures, webview; this.timeout(10000); - fixtures = path.join(__dirname, 'fixtures'); - webview = null; + + var fixtures = path.join(__dirname, 'fixtures'); + var webview = null; + beforeEach(function() { - return webview = new WebView; + webview = new WebView; }); + afterEach(function() { if (document.body.contains(webview)) { - return document.body.removeChild(webview); + document.body.removeChild(webview); } }); + describe('src attribute', function() { it('specifies the page to load', function(done) { webview.addEventListener('console-message', function(e) { assert.equal(e.message, 'a'); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/a.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); - return it('navigates to new page when changed', function(done) { + + it('navigates to new page when changed', function(done) { var listener = function() { webview.src = "file://" + fixtures + "/pages/b.html"; webview.addEventListener('console-message', function(e) { assert.equal(e.message, 'b'); - return done(); + done(); }); - return webview.removeEventListener('did-finish-load', listener); + webview.removeEventListener('did-finish-load', listener); }; webview.addEventListener('did-finish-load', listener); webview.src = "file://" + fixtures + "/pages/a.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('nodeintegration attribute', function() { it('inserts no node symbols when not set', function(done) { webview.addEventListener('console-message', function(e) { assert.equal(e.message, 'undefined undefined undefined undefined'); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/c.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); + it('inserts node symbols when set', function(done) { webview.addEventListener('console-message', function(e) { assert.equal(e.message, 'function object object'); - return done(); + done(); }); webview.setAttribute('nodeintegration', 'on'); webview.src = "file://" + fixtures + "/pages/d.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); + it('loads node symbols after POST navigation when set', function(done) { webview.addEventListener('console-message', function(e) { assert.equal(e.message, 'function object object'); - return done(); + done(); }); webview.setAttribute('nodeintegration', 'on'); webview.src = "file://" + fixtures + "/pages/post.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); + if (process.platform !== 'win32' || process.execPath.toLowerCase().indexOf('\\out\\d\\') === -1) { - return it('loads native modules when navigation happens', function(done) { + it('loads native modules when navigation happens', function(done) { var listener = function() { webview.removeEventListener('did-finish-load', listener); var listener2 = function(e) { assert.equal(e.message, 'function'); - return done(); + done(); }; webview.addEventListener('console-message', listener2); - return webview.reload(); + webview.reload(); }; webview.addEventListener('did-finish-load', listener); webview.setAttribute('nodeintegration', 'on'); webview.src = "file://" + fixtures + "/pages/native-module.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); } }); + describe('preload attribute', function() { it('loads the script before other scripts in window', function(done) { var listener; listener = function(e) { assert.equal(e.message, 'function object object'); webview.removeEventListener('console-message', listener); - return done(); + done(); }; webview.addEventListener('console-message', listener); webview.setAttribute('preload', fixtures + "/module/preload.js"); webview.src = "file://" + fixtures + "/pages/e.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); + it('preload script can still use "process" in required modules when nodeintegration is off', function(done) { webview.addEventListener('console-message', function(e) { assert.equal(e.message, 'object undefined object'); - return done(); + done(); }); webview.setAttribute('preload', fixtures + "/module/preload-node-off.js"); webview.src = "file://" + fixtures + "/api/blank.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); - return it('receives ipc message in preload script', function(done) { + + it('receives ipc message in preload script', function(done) { var listener, listener2, message; message = 'boom!'; listener = function(e) { assert.equal(e.channel, 'pong'); assert.deepEqual(e.args, [message]); webview.removeEventListener('ipc-message', listener); - return done(); + done(); }; listener2 = function() { webview.send('ping', message); - return webview.removeEventListener('did-finish-load', listener2); + webview.removeEventListener('did-finish-load', listener2); }; webview.addEventListener('ipc-message', listener); webview.addEventListener('did-finish-load', listener2); webview.setAttribute('preload', fixtures + "/module/preload-ipc.js"); webview.src = "file://" + fixtures + "/pages/e.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('httpreferrer attribute', function() { - return it('sets the referrer url', function(done) { + it('sets the referrer url', function(done) { var listener, referrer; referrer = 'http://github.com/'; listener = function(e) { assert.equal(e.message, referrer); webview.removeEventListener('console-message', listener); - return done(); + done(); }; webview.addEventListener('console-message', listener); webview.setAttribute('httpreferrer', referrer); webview.src = "file://" + fixtures + "/pages/referrer.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('useragent attribute', function() { - return it('sets the user agent', function(done) { + it('sets the user agent', function(done) { var listener, referrer; referrer = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'; listener = function(e) { assert.equal(e.message, referrer); webview.removeEventListener('console-message', listener); - return done(); + done(); }; webview.addEventListener('console-message', listener); webview.setAttribute('useragent', referrer); webview.src = "file://" + fixtures + "/pages/useragent.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('disablewebsecurity attribute', function() { it('does not disable web security when not set', function(done) { var encoded, listener, src; @@ -169,164 +178,177 @@ describe(' tag', function() { listener = function(e) { assert(/Not allowed to load local resource/.test(e.message)); webview.removeEventListener('console-message', listener); - return done(); + done(); }; webview.addEventListener('console-message', listener); webview.src = "data:text/html;base64," + encoded; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); - return it('disables web security when set', function(done) { + + it('disables web security when set', function(done) { var encoded, listener, src; src = " "; encoded = btoa(unescape(encodeURIComponent(src))); listener = function(e) { assert.equal(e.message, 'ok'); webview.removeEventListener('console-message', listener); - return done(); + done(); }; webview.addEventListener('console-message', listener); webview.setAttribute('disablewebsecurity', ''); webview.src = "data:text/html;base64," + encoded; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); describe('partition attribute', function() { it('inserts no node symbols when not set', function(done) { webview.addEventListener('console-message', function(e) { assert.equal(e.message, 'undefined undefined undefined undefined'); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/c.html"; webview.partition = 'test1'; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); + it('inserts node symbols when set', function(done) { webview.addEventListener('console-message', function(e) { assert.equal(e.message, 'function object object'); - return done(); + done(); }); webview.setAttribute('nodeintegration', 'on'); webview.src = "file://" + fixtures + "/pages/d.html"; webview.partition = 'test2'; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); + it('isolates storage for different id', function(done) { var listener; listener = function(e) { assert.equal(e.message, " 0"); webview.removeEventListener('console-message', listener); - return done(); + done(); }; window.localStorage.setItem('test', 'one'); webview.addEventListener('console-message', listener); webview.src = "file://" + fixtures + "/pages/partition/one.html"; webview.partition = 'test3'; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); - return it('uses current session storage when no id is provided', function(done) { + + it('uses current session storage when no id is provided', function(done) { var listener; listener = function(e) { assert.equal(e.message, "one 1"); webview.removeEventListener('console-message', listener); - return done(); + done(); }; window.localStorage.setItem('test', 'one'); webview.addEventListener('console-message', listener); webview.src = "file://" + fixtures + "/pages/partition/one.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('allowpopups attribute', function() { it('can not open new window when not set', function(done) { var listener; listener = function(e) { assert.equal(e.message, 'null'); webview.removeEventListener('console-message', listener); - return done(); + done(); }; webview.addEventListener('console-message', listener); webview.src = "file://" + fixtures + "/pages/window-open-hide.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); - return it('can open new window when set', function(done) { + + it('can open new window when set', function(done) { var listener; listener = function(e) { assert.equal(e.message, 'window'); webview.removeEventListener('console-message', listener); - return done(); + done(); }; webview.addEventListener('console-message', listener); webview.setAttribute('allowpopups', 'on'); webview.src = "file://" + fixtures + "/pages/window-open-hide.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('new-window event', function() { it('emits when window.open is called', function(done) { webview.addEventListener('new-window', function(e) { assert.equal(e.url, 'http://host/'); assert.equal(e.frameName, 'host'); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/window-open.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); - return it('emits when link with target is called', function(done) { + + it('emits when link with target is called', function(done) { webview.addEventListener('new-window', function(e) { assert.equal(e.url, 'http://host/'); assert.equal(e.frameName, 'target'); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/target-name.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('ipc-message event', function() { - return it('emits when guest sends a ipc message to browser', function(done) { + it('emits when guest sends a ipc message to browser', function(done) { webview.addEventListener('ipc-message', function(e) { assert.equal(e.channel, 'channel'); assert.deepEqual(e.args, ['arg1', 'arg2']); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/ipc-message.html"; webview.setAttribute('nodeintegration', 'on'); - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('page-title-set event', function() { - return it('emits when title is set', function(done) { + it('emits when title is set', function(done) { webview.addEventListener('page-title-set', function(e) { assert.equal(e.title, 'test'); assert(e.explicitSet); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/a.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('page-favicon-updated event', function() { - return it('emits when favicon urls are received', function(done) { + it('emits when favicon urls are received', function(done) { webview.addEventListener('page-favicon-updated', function(e) { var pageUrl; assert.equal(e.favicons.length, 2); pageUrl = process.platform === 'win32' ? 'file:///C:/favicon.png' : 'file:///favicon.png'; assert.equal(e.favicons[0], pageUrl); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/a.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('will-navigate event', function() { - return it('emits when a url that leads to oustide of the page is clicked', function(done) { + it('emits when a url that leads to oustide of the page is clicked', function(done) { webview.addEventListener('will-navigate', function(e) { assert.equal(e.url, "http://host/"); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/webview-will-navigate.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('did-navigate event', function() { var p, pageUrl; p = path.join(fixtures, 'pages', 'webview-will-navigate.html'); @@ -336,13 +358,14 @@ describe(' tag', function() { slashes: true, pathname: p }); - return it('emits when a url that leads to outside of the page is clicked', function(done) { + + it('emits when a url that leads to outside of the page is clicked', function(done) { webview.addEventListener('did-navigate', function(e) { assert.equal(e.url, pageUrl); - return done(); + done(); }); webview.src = pageUrl; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); describe('did-navigate-in-page event', function() { @@ -357,20 +380,22 @@ describe(' tag', function() { }); webview.addEventListener('did-navigate-in-page', function(e) { assert.equal(e.url, pageUrl + "#test_content"); - return done(); + done(); }); webview.src = pageUrl; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); + it('emits when window.history.replaceState is called', function(done) { webview.addEventListener('did-navigate-in-page', function(e) { assert.equal(e.url, "http://host/"); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/webview-did-navigate-in-page-with-history.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); - return it('emits when window.location.hash is changed', function(done) { + + it('emits when window.location.hash is changed', function(done) { var p, pageUrl; p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page-with-hash.html'); p = p.replace(/\\/g, '/'); @@ -381,94 +406,100 @@ describe(' tag', function() { }); webview.addEventListener('did-navigate-in-page', function(e) { assert.equal(e.url, pageUrl + "#test"); - return done(); + done(); }); webview.src = pageUrl; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('close event', function() { - return it('should fire when interior page calls window.close', function(done) { + it('should fire when interior page calls window.close', function(done) { webview.addEventListener('close', function() { - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/close.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('devtools-opened event', function() { - return it('should fire when webview.openDevTools() is called', function(done) { + it('should fire when webview.openDevTools() is called', function(done) { var listener; listener = function() { webview.removeEventListener('devtools-opened', listener); webview.closeDevTools(); - return done(); + done(); }; webview.addEventListener('devtools-opened', listener); webview.addEventListener('dom-ready', function() { - return webview.openDevTools(); + webview.openDevTools(); }); webview.src = "file://" + fixtures + "/pages/base-page.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('devtools-closed event', function() { - return it('should fire when webview.closeDevTools() is called', function(done) { + it('should fire when webview.closeDevTools() is called', function(done) { var listener, listener2; listener2 = function() { webview.removeEventListener('devtools-closed', listener2); - return done(); + done(); }; listener = function() { webview.removeEventListener('devtools-opened', listener); - return webview.closeDevTools(); + webview.closeDevTools(); }; webview.addEventListener('devtools-opened', listener); webview.addEventListener('devtools-closed', listener2); webview.addEventListener('dom-ready', function() { - return webview.openDevTools(); + webview.openDevTools(); }); webview.src = "file://" + fixtures + "/pages/base-page.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('devtools-focused event', function() { - return it('should fire when webview.openDevTools() is called', function(done) { + it('should fire when webview.openDevTools() is called', function(done) { var listener; listener = function() { webview.removeEventListener('devtools-focused', listener); webview.closeDevTools(); - return done(); + done(); }; webview.addEventListener('devtools-focused', listener); webview.addEventListener('dom-ready', function() { - return webview.openDevTools(); + webview.openDevTools(); }); webview.src = "file://" + fixtures + "/pages/base-page.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('.reload()', function() { - return it('should emit beforeunload handler', function(done) { + it('should emit beforeunload handler', function(done) { var listener, listener2; listener = function(e) { assert.equal(e.channel, 'onbeforeunload'); webview.removeEventListener('ipc-message', listener); - return done(); + done(); }; listener2 = function() { webview.reload(); - return webview.removeEventListener('did-finish-load', listener2); + webview.removeEventListener('did-finish-load', listener2); }; webview.addEventListener('ipc-message', listener); webview.addEventListener('did-finish-load', listener2); webview.setAttribute('nodeintegration', 'on'); webview.src = "file://" + fixtures + "/pages/beforeunload-false.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('.clearHistory()', function() { - return it('should clear the navigation history', function(done) { + it('should clear the navigation history', function(done) { var listener; listener = function(e) { assert.equal(e.channel, 'history'); @@ -477,18 +508,19 @@ describe(' tag', function() { webview.clearHistory(); assert(!webview.canGoBack()); webview.removeEventListener('ipc-message', listener); - return done(); + done(); }; webview.addEventListener('ipc-message', listener); webview.setAttribute('nodeintegration', 'on'); webview.src = "file://" + fixtures + "/pages/history.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('basic auth', function() { var auth; auth = require('basic-auth'); - return it('should authenticate with correct credentials', function(done) { + it('should authenticate with correct credentials', function(done) { var message, server; message = 'Authenticated'; server = http.createServer(function(req, res) { @@ -499,67 +531,71 @@ describe(' tag', function() { } else { res.end('failed'); } - return server.close(); + server.close(); }); - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port; port = server.address().port; webview.addEventListener('ipc-message', function(e) { assert.equal(e.channel, message); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/basic-auth.html?port=" + port; webview.setAttribute('nodeintegration', 'on'); - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); }); + describe('dom-ready event', function() { - return it('emits when document is loaded', function(done) { + it('emits when document is loaded', function(done) { var server; server = http.createServer(function() {}); - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port; port = server.address().port; webview.addEventListener('dom-ready', function() { - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/dom-ready.html?port=" + port; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); }); + describe('executeJavaScript', function() { if (process.env.TRAVIS !== 'true') { return; } - return it('should support user gesture', function(done) { + + it('should support user gesture', function(done) { var listener, listener2; listener = function() { webview.removeEventListener('enter-html-full-screen', listener); - return done(); + done(); }; listener2 = function() { var jsScript; jsScript = 'document.getElementsByTagName("video")[0].webkitRequestFullScreen()'; webview.executeJavaScript(jsScript, true); - return webview.removeEventListener('did-finish-load', listener2); + webview.removeEventListener('did-finish-load', listener2); }; webview.addEventListener('enter-html-full-screen', listener); webview.addEventListener('did-finish-load', listener2); webview.src = "file://" + fixtures + "/pages/fullscreen.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('sendInputEvent', function() { it('can send keyboard event', function(done) { webview.addEventListener('ipc-message', function(e) { assert.equal(e.channel, 'keyup'); assert.deepEqual(e.args, [67, true, false]); - return done(); + done(); }); webview.addEventListener('dom-ready', function() { - return webview.sendInputEvent({ + webview.sendInputEvent({ type: 'keyup', keyCode: 'c', modifiers: ['shift'] @@ -567,16 +603,17 @@ describe(' tag', function() { }); webview.src = "file://" + fixtures + "/pages/onkeyup.html"; webview.setAttribute('nodeintegration', 'on'); - return document.body.appendChild(webview); + document.body.appendChild(webview); }); - return it('can send mouse event', function(done) { + + it('can send mouse event', function(done) { webview.addEventListener('ipc-message', function(e) { assert.equal(e.channel, 'mouseup'); assert.deepEqual(e.args, [10, 20, false, true]); - return done(); + done(); }); webview.addEventListener('dom-ready', function() { - return webview.sendInputEvent({ + webview.sendInputEvent({ type: 'mouseup', modifiers: ['ctrl'], x: 10, @@ -585,26 +622,28 @@ describe(' tag', function() { }); webview.src = "file://" + fixtures + "/pages/onmouseup.html"; webview.setAttribute('nodeintegration', 'on'); - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('media-started-playing media-paused events', function() { - return it('emits when audio starts and stops playing', function(done) { + it('emits when audio starts and stops playing', function(done) { var audioPlayed; audioPlayed = false; webview.addEventListener('media-started-playing', function() { - return audioPlayed = true; + audioPlayed = true; }); webview.addEventListener('media-paused', function() { assert(audioPlayed); - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/audio.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('found-in-page event', function() { - return it('emits when a request is made', function(done) { + it('emits when a request is made', function(done) { var listener, listener2, requestId; requestId = null; listener = function(e) { @@ -612,27 +651,29 @@ describe(' tag', function() { if (e.result.finalUpdate) { assert.equal(e.result.matches, 3); webview.stopFindInPage("clearSelection"); - return done(); + done(); } }; listener2 = function() { - return requestId = webview.findInPage("virtual"); + requestId = webview.findInPage("virtual"); }; webview.addEventListener('found-in-page', listener); webview.addEventListener('did-finish-load', listener2); webview.src = "file://" + fixtures + "/pages/content.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + xdescribe('did-change-theme-color event', function() { - return it('emits when theme color changes', function(done) { + it('emits when theme color changes', function(done) { webview.addEventListener('did-change-theme-color', function() { - return done(); + done(); }); webview.src = "file://" + fixtures + "/pages/theme-color.html"; - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); + describe('permission-request event', function() { function setUpRequestHandler(webview, requested_permission) { const session = require('electron').remote.session; @@ -645,7 +686,7 @@ describe(' tag', function() { session.fromPartition(webview.partition).setPermissionRequestHandler(listener); } - it ('emits when using navigator.getUserMedia api', function(done) { + it('emits when using navigator.getUserMedia api', function(done) { webview.addEventListener('ipc-message', function(e) { assert(e.channel, 'message'); assert(e.args, ['PermissionDeniedError']); @@ -658,7 +699,7 @@ describe(' tag', function() { document.body.appendChild(webview); }); - it ('emits when using navigator.geolocation api', function(done) { + it('emits when using navigator.geolocation api', function(done) { webview.addEventListener('ipc-message', function(e) { assert(e.channel, 'message'); assert(e.args, ['ERROR(1): User denied Geolocation']); @@ -671,7 +712,7 @@ describe(' tag', function() { document.body.appendChild(webview); }); - it ('emits when using navigator.requestMIDIAccess api', function(done) { + it('emits when using navigator.requestMIDIAccess api', function(done) { webview.addEventListener('ipc-message', function(e) { assert(e.channel, 'message'); assert(e.args, ['SecurityError']); From 6bc48ba123f31148f9d41790447ff0c58fd16b70 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 5 Feb 2016 10:48:07 -0800 Subject: [PATCH 182/688] Add failing spec for custom error message --- spec/webview-spec.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 904dfcab6e0..faafec73db3 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -561,6 +561,17 @@ describe(' tag', function() { document.body.appendChild(webview); }); }); + + it('throws a custom error when an API method is called before the event is emitted', function() { + var readyError = null; + try { + webview.stop(); + } catch (error) { + readyError = error; + } + + assert.equal(readyError.message, 'stop can only be called after the dom-ready event is emitted'); + }); }); describe('executeJavaScript', function() { From 8cacd0b931fe842afe3c54e618344924dc3fc0f6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 5 Feb 2016 10:55:32 -0800 Subject: [PATCH 183/688] Throw custom error when WebView API is unavailable --- atom/renderer/lib/web-view/web-view.js | 11 +++++++---- spec/webview-spec.js | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 5257f0c12f9..4e34d2e5592 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -404,10 +404,13 @@ var registerWebViewElement = function() { // Forward proto.foo* method calls to WebViewImpl.foo*. createBlockHandler = function(m) { return function() { - var args, internal, ref1; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - internal = v8Util.getHiddenValue(this, 'internal'); - return (ref1 = internal.webContents)[m].apply(ref1, args); + var args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + var internal = v8Util.getHiddenValue(this, 'internal'); + if (internal.webContents) { + return internal.webContents[m].apply(internal.webContents, args); + } else { + throw new Error('Cannot call ' + m + ' before the dom-ready event is emitted') + } }; }; for (i = 0, len = methods.length; i < len; i++) { diff --git a/spec/webview-spec.js b/spec/webview-spec.js index faafec73db3..072a51f36a5 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -570,7 +570,7 @@ describe(' tag', function() { readyError = error; } - assert.equal(readyError.message, 'stop can only be called after the dom-ready event is emitted'); + assert.equal(readyError.message, 'Cannot call stop before the dom-ready event is emitted'); }); }); From 42a8674cea58ab3fe73c391e21a403ee66b40d86 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 5 Feb 2016 11:05:17 -0800 Subject: [PATCH 184/688] Add missing semicolon --- atom/renderer/lib/web-view/web-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 4e34d2e5592..29af92e9bd3 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -409,7 +409,7 @@ var registerWebViewElement = function() { if (internal.webContents) { return internal.webContents[m].apply(internal.webContents, args); } else { - throw new Error('Cannot call ' + m + ' before the dom-ready event is emitted') + throw new Error('Cannot call ' + m + ' before the dom-ready event is emitted'); } }; }; From 674af4211c403e767882781c44ba282c591b84af Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Feb 2016 13:24:58 -0800 Subject: [PATCH 185/688] Use interpolated string --- atom/renderer/lib/web-view/web-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 29af92e9bd3..49440527c40 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -409,7 +409,7 @@ var registerWebViewElement = function() { if (internal.webContents) { return internal.webContents[m].apply(internal.webContents, args); } else { - throw new Error('Cannot call ' + m + ' before the dom-ready event is emitted'); + throw new Error(`Cannot call ${m} before the dom-ready event is emitted`); } }; }; From bad48169764278154cb47e218024ed224de9ae7d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Feb 2016 13:51:35 -0800 Subject: [PATCH 186/688] Expand error message --- atom/renderer/lib/web-view/web-view.js | 2 +- spec/webview-spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 49440527c40..9cc6ac4e880 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -409,7 +409,7 @@ var registerWebViewElement = function() { if (internal.webContents) { return internal.webContents[m].apply(internal.webContents, args); } else { - throw new Error(`Cannot call ${m} before the dom-ready event is emitted`); + throw new Error(`Cannot call ${m} because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emmitted before this method can be called.`); } }; }; diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 072a51f36a5..0b6572a5084 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -570,7 +570,7 @@ describe(' tag', function() { readyError = error; } - assert.equal(readyError.message, 'Cannot call stop before the dom-ready event is emitted'); + assert.equal(readyError.message, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emmitted before this method can be called.'); }); }); From da6ebac7424e931a5789b95a5b6c70effacfffd1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Feb 2016 13:53:10 -0800 Subject: [PATCH 187/688] Use assert.throws --- spec/webview-spec.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 0b6572a5084..eb1427e0855 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -563,14 +563,9 @@ describe(' tag', function() { }); it('throws a custom error when an API method is called before the event is emitted', function() { - var readyError = null; - try { - webview.stop(); - } catch (error) { - readyError = error; - } - - assert.equal(readyError.message, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emmitted before this method can be called.'); + assert.throws(function () { + webview.stop() + }, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emmitted before this method can be called.'); }); }); From 9609b36b3cab670b5274d4c77b767ba1123db4b7 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 9 Feb 2016 13:55:49 -0800 Subject: [PATCH 188/688] Add missing semicolon --- spec/webview-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index eb1427e0855..973c1c24031 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -564,7 +564,7 @@ describe(' tag', function() { it('throws a custom error when an API method is called before the event is emitted', function() { assert.throws(function () { - webview.stop() + webview.stop(); }, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emmitted before this method can be called.'); }); }); From 042825e8fb40244c665b720266ff7112333d5eb2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 11 Feb 2016 13:32:34 -0800 Subject: [PATCH 189/688] emmitted -> emitted --- atom/renderer/lib/web-view/web-view.js | 2 +- spec/webview-spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 9cc6ac4e880..7e38bb33715 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -409,7 +409,7 @@ var registerWebViewElement = function() { if (internal.webContents) { return internal.webContents[m].apply(internal.webContents, args); } else { - throw new Error(`Cannot call ${m} because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emmitted before this method can be called.`); + throw new Error(`Cannot call ${m} because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.`); } }; }; diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 973c1c24031..a18e152ea6a 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -565,7 +565,7 @@ describe(' tag', function() { it('throws a custom error when an API method is called before the event is emitted', function() { assert.throws(function () { webview.stop(); - }, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emmitted before this method can be called.'); + }, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.'); }); }); From c09ff40916bec47b6c7a09ea8c0c8a1d0e591642 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 12 Feb 2016 05:07:06 +0530 Subject: [PATCH 190/688] browser: handle desktop capture devices in media permission request --- atom/browser/web_contents_permission_helper.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index f5ce414dd2c..d018e1d09db 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -23,7 +23,7 @@ void MediaAccessAllowed( bool allowed) { brightray::MediaStreamDevicesController controller(request, callback); if (allowed) - controller.Accept(); + controller.TakeAction(); else controller.Deny(content::MEDIA_DEVICE_PERMISSION_DENIED); } From 3adcaa7681fdff87186aa08689c2b3567aaa78cb Mon Sep 17 00:00:00 2001 From: Habib Rehman Date: Fri, 12 Feb 2016 00:11:02 +0000 Subject: [PATCH 191/688] Fix electron binary relative path The relative path for Electron's binary is Contents/MacOS/Electron --- docs/tutorial/using-selenium-and-webdriver.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/using-selenium-and-webdriver.md b/docs/tutorial/using-selenium-and-webdriver.md index 035dabdfe79..2d296548dd9 100644 --- a/docs/tutorial/using-selenium-and-webdriver.md +++ b/docs/tutorial/using-selenium-and-webdriver.md @@ -49,7 +49,7 @@ var driver = new webdriver.Builder() .withCapabilities({ chromeOptions: { // Here is the path to your Electron binary. - binary: '/Path-to-Your-App.app/Contents/MacOS/Atom', + binary: '/Path-to-Your-App.app/Contents/MacOS/Electron', } }) .forBrowser('electron') From 91c96559fa40e50e7c364bb7f0dafc594692390f Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Fri, 12 Feb 2016 02:18:13 +0100 Subject: [PATCH 192/688] Fixing the problem related to FrameSubscriber --- atom/browser/api/atom_api_web_contents.cc | 8 +++-- atom/browser/api/frame_subscriber.cc | 40 ++++++++++++++++++++--- atom/browser/api/frame_subscriber.h | 27 ++++++++++++--- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 80e5b606ef8..b04553e654b 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1064,9 +1064,11 @@ void WebContents::BeginFrameSubscription( const FrameSubscriber::FrameCaptureCallback& callback) { const auto view = web_contents()->GetRenderWidgetHostView(); if (view) { - scoped_ptr frame_subscriber(new FrameSubscriber( - isolate(), view->GetVisibleViewportSize(), callback)); - view->BeginFrameSubscription(frame_subscriber.Pass()); + FrameSubscriber* frame_subscriber = new FrameSubscriber( + isolate(), view->GetVisibleViewportSize(), callback); + scoped_ptr del_frame_subscriber( + frame_subscriber->GetSubscriber()); + view->BeginFrameSubscription(del_frame_subscriber.Pass()); } } diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 5b7241486b7..9bcf16fef85 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -13,28 +13,58 @@ namespace atom { namespace api { +using Subscriber = FrameSubscriber::Subscriber; + FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, const gfx::Size& size, const FrameCaptureCallback& callback) - : isolate_(isolate), size_(size), callback_(callback) { + : isolate_(isolate), size_(size), callback_(callback), pending_frames(0) { + subscriber_ = new Subscriber(this); } -bool FrameSubscriber::ShouldCaptureFrame( +Subscriber::Subscriber( + FrameSubscriber* frame_subscriber) : frame_subscriber_(frame_subscriber) { +} + +Subscriber::~Subscriber() { + frame_subscriber_->subscriber_ = NULL; + frame_subscriber_->RequestDestruct(); +} + +bool Subscriber::ShouldCaptureFrame( const gfx::Rect& damage_rect, base::TimeTicks present_time, scoped_refptr* storage, DeliverFrameCallback* callback) { *storage = media::VideoFrame::CreateFrame( media::PIXEL_FORMAT_YV12, - size_, gfx::Rect(size_), size_, base::TimeDelta()); + frame_subscriber_->size_, gfx::Rect(frame_subscriber_->size_), + frame_subscriber_->size_, base::TimeDelta()); *callback = base::Bind(&FrameSubscriber::OnFrameDelivered, - base::Unretained(this), *storage); + base::Unretained(frame_subscriber_), *storage); + frame_subscriber_->pending_frames++; return true; } +Subscriber* FrameSubscriber::GetSubscriber() { + return subscriber_; +} + +bool FrameSubscriber::RequestDestruct() { + bool deletable = (subscriber_ == NULL && pending_frames == 0); + // Destruct FrameSubscriber if we're not waiting for frames and the + // subscription has ended + if (deletable) + delete this; + + return deletable; +} + void FrameSubscriber::OnFrameDelivered( scoped_refptr frame, base::TimeTicks, bool result) { - if (!result) + pending_frames--; + + if (!result || RequestDestruct()) return; v8::Locker locker(isolate_); diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h index f7748aa5790..6f6d66b6be8 100644 --- a/atom/browser/api/frame_subscriber.h +++ b/atom/browser/api/frame_subscriber.h @@ -14,26 +14,43 @@ namespace atom { namespace api { -class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { +class FrameSubscriber { public: using FrameCaptureCallback = base::Callback)>; + // Inner class that is the actual subscriber sent to chromium + class Subscriber : + public content::RenderWidgetHostViewFrameSubscriber { + public: + explicit Subscriber(FrameSubscriber* frame_subscriber); + + bool ShouldCaptureFrame(const gfx::Rect& damage_rect, + base::TimeTicks present_time, + scoped_refptr* storage, + DeliverFrameCallback* callback) override; + + ~Subscriber(); + private: + FrameSubscriber* frame_subscriber_; + }; + FrameSubscriber(v8::Isolate* isolate, const gfx::Size& size, const FrameCaptureCallback& callback); - bool ShouldCaptureFrame(const gfx::Rect& damage_rect, - base::TimeTicks present_time, - scoped_refptr* storage, - DeliverFrameCallback* callback) override; + Subscriber* GetSubscriber(); private: void OnFrameDelivered( scoped_refptr frame, base::TimeTicks, bool); + bool RequestDestruct(); + v8::Isolate* isolate_; gfx::Size size_; FrameCaptureCallback callback_; + Subscriber* subscriber_; + int pending_frames; DISALLOW_COPY_AND_ASSIGN(FrameSubscriber); }; From f36e2841bff038de2f7cf7649544a589979a06a3 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Fri, 12 Feb 2016 13:30:11 +0100 Subject: [PATCH 193/688] Don't fire callbacks after we end the subscription --- atom/browser/api/frame_subscriber.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 9bcf16fef85..7d973892405 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -64,7 +64,7 @@ void FrameSubscriber::OnFrameDelivered( scoped_refptr frame, base::TimeTicks, bool result) { pending_frames--; - if (!result || RequestDestruct()) + if (RequestDestruct() || subscriber_ == NULL || !result) return; v8::Locker locker(isolate_); From 2677dc68444398f20210291dfaf7349fc17dc48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Aur=C3=A8le=20DARCHE?= Date: Fri, 12 Feb 2016 13:50:15 +0100 Subject: [PATCH 194/688] Fix: add missing fragment in FAQ section URL --- docs/tutorial/quick-start.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index ccb3836ba1f..67fe5d608a1 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -48,7 +48,8 @@ communication between the main process and renderer process. There is also a [remote](../api/remote.md) module for RPC style communication. And finally there are different techniques [to share objects between web -pages](../faq/electron-faq.md#) of the same window or of different windows. +pages](../faq/electron-faq.md#what-are-the-different-techniques-to-share-objects-between-web-pages) +of the same window or of different windows. ## Write your First Electron App From e71eeda73c5f8d8a760ce63d6976d394257a5e27 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 12 Feb 2016 22:38:08 +0900 Subject: [PATCH 195/688] Remove unnecessary line feeds [ci skip] --- docs/api/clipboard.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/api/clipboard.md b/docs/api/clipboard.md index dcb9fa398a9..7f95a1af26d 100644 --- a/docs/api/clipboard.md +++ b/docs/api/clipboard.md @@ -67,7 +67,6 @@ Writes `image` to the clipboard. Returns the content in the clipboard as RTF. - ### `clipboard.writeRtf(text[, type])` * `text` String From d76f6fe8e0d6faee5c542e79f86202a6f89245b5 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Sat, 13 Feb 2016 17:03:58 +0900 Subject: [PATCH 196/688] :memo::checkered_flag: Add icon overlays in taskbar to docs [ci skip] --- .../desktop-environment-integration.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 7d7eb44ecb6..54246a11c5c 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -271,6 +271,33 @@ var window = new BrowserWindow({...}); window.setProgressBar(0.5); ``` +## Icon Overlays in Taskbar (Windows) + +On Windows a taskbar button can use a small overlay to display application +status, as quoted from MSDN: + +> Icon overlays serve as a contextual notification of status, and are intended +> to negate the need for a separate notification area status icon to communicate +> that information to the user. For instance, the new mail status in Microsoft +> Outlook, currently shown in the notification area, can now be indicated +> through an overlay on the taskbar button. Again, you must decide during your +> development cycle which method is best for your application. Overlay icons are +> intended to supply important, long-standing status or notifications such as +> network status, messenger status, or new mail. The user should not be +> presented with constantly changing overlays or animations. + +__Overlay on taskbar button:__ + +![Overlay on taskbar button](https://i-msdn.sec.s-msft.com/dynimg/IC420441.png) + +To set the overlay icon for a window, you can use the +[BrowserWindow.setOverlayIcon][setoverlayicon] API: + +```javascript +var window = new BrowserWindow({...}); +window.setOverlayIcon('path/to/overlay.png', 'Description for overlay'); +``` + ## Represented File of Window (OS X) On OS X a window can set its represented file, so the file's icon can show in @@ -298,6 +325,7 @@ window.setDocumentEdited(true); [clearrecentdocuments]: ../api/app.md#appclearrecentdocuments [setusertaskstasks]: ../api/app.md#appsetusertaskstasks [setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress +[setoverlayicon]: ../api/browser-window.md#winsetoverlayiconoverlay-description-windows-7 [setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename [setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx From adf89a1e0eff739c9bfef7af614fbb403c982349 Mon Sep 17 00:00:00 2001 From: Remi Sezille Date: Sat, 13 Feb 2016 11:29:08 +0100 Subject: [PATCH 197/688] Translate README in french [ci skip] --- docs-translations/fr-FR/README.md | 91 +++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 docs-translations/fr-FR/README.md diff --git a/docs-translations/fr-FR/README.md b/docs-translations/fr-FR/README.md new file mode 100644 index 00000000000..04aed455612 --- /dev/null +++ b/docs-translations/fr-FR/README.md @@ -0,0 +1,91 @@ +Vérifiez que vous utilisez la bonne version de la documentation. +Le numéro de version devrait faire partie de l'URL de la page. +Si ce n'est pas le cas, vous utilisez probablement la documentation d'une branche +de développement qui peut contenir des changements API qui ne sont pas compatibles +avec votre version d'Electron. Si c'est le cas, vous pouvez changer de version sur la +liste [versions disponibles](http://electron.atom.io/docs/), ou, si vous utilisez +l'interface de GitHub, ouvrez la liste déroulante "Switch branches/tags" afin de sélectionner +le tag de votre version. + +## FAQ + +Avant de créer un ticket, vérifiez que votre problème n'a pas déjà sa réponse +dans la FAQ : + +* [Electron FAQ](faq/electron-faq.md) + +## Guides + +* [Plateformes supportées](tutorial/supported-platforms.md) +* [Distribution de l'Application](tutorial/application-distribution.md) +* [Guide de Soumission Mac App Store](tutorial/mac-app-store-submission-guide.md) +* [Créer une archive](tutorial/application-packaging.md) +* [Utiliser Modules Natifs de Node](tutorial/using-native-node-modules.md) +* [Debugger Processus Principal](tutorial/debugging-main-process.md) +* [Utiliser Selenium et WebDriver](tutorial/using-selenium-and-webdriver.md) +* [Extension DevTools](tutorial/devtools-extension.md) +* [Utiliser le Plugin Pepper Flash](tutorial/using-pepper-flash-plugin.md) +* [Utiliser le Plugin Widevine CDM](tutorial/using-widevine-cdm-plugin.md) + +## Tutoriels + +* [Démarrage Rapide](tutorial/quick-start.md) +* [Intégration Environnement de Bureau](tutorial/desktop-environment-integration.md) +* [Détection des Evènements En ligne/Hors ligne](tutorial/online-offline-events.md) + +## Références API + +* [Synopsis](api/synopsis.md) +* [L'objet Process](api/process.md) +* [Commandes Chromes Supportées](api/chrome-command-line-switches.md) +* [Variables d'Environnement](api/environment-variables.md) + +### Eléments DOM Personnalisés: + +* [Objet `File`](api/file-object.md) +* [Tag ``](api/web-view-tag.md) +* [Fonction `window.open`](api/window-open.md) + +### Modules pour le Processus Principal : + +* [app](api/app.md) +* [autoUpdater](api/auto-updater.md) +* [BrowserWindow](api/browser-window.md) +* [contentTracing](api/content-tracing.md) +* [dialog](api/dialog.md) +* [globalShortcut](api/global-shortcut.md) +* [ipcMain](api/ipc-main.md) +* [Menu](api/menu.md) +* [MenuItem](api/menu-item.md) +* [powerMonitor](api/power-monitor.md) +* [powerSaveBlocker](api/power-save-blocker.md) +* [protocol](api/protocol.md) +* [session](api/session.md) +* [webContents](api/web-contents.md) +* [Tray](api/tray.md) + +### Modules pour le Processus d'Affichage (Page Web) : + +* [desktopCapturer](api/desktop-capturer.md) +* [ipcRenderer](api/ipc-renderer.md) +* [remote](api/remote.md) +* [webFrame](api/web-frame.md) + +### Modules pour les deux Processus : + +* [clipboard](api/clipboard.md) +* [crashReporter](api/crash-reporter.md) +* [nativeImage](api/native-image.md) +* [screen](api/screen.md) +* [shell](api/shell.md) + +## Développement + +* [Style de Code](development/coding-style.md) +* [Hiérarchie du Code Source](development/source-code-directory-structure.md) +* [Différences Techniques par rapport à NW.js (anciennement node-webkit)](development/atom-shell-vs-node-webkit.md) +* [Aperçu du Système de Build](development/build-system-overview.md) +* [Instructions de Build (OS X)](development/build-instructions-osx.md) +* [Instructions de Build (Windows)](development/build-instructions-windows.md) +* [Instructions de Build (Linux)](development/build-instructions-linux.md) +* [Installer un Serveur de Symbol dans le debugger](development/setting-up-symbol-server.md) From 940c325e7f89f90e8151b9ed56734a03bea5e1d1 Mon Sep 17 00:00:00 2001 From: Remi Sezille Date: Sat, 13 Feb 2016 11:32:47 +0100 Subject: [PATCH 198/688] Add french docs link on main README [ci skip] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a7306ddabbb..ce6d483f0df 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ contains documents describing how to build and contribute to Electron. - [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW) - [Ukrainian](https://github.com/atom/electron/tree/master/docs-translations/uk-UA) - [Russian](https://github.com/atom/electron/tree/master/docs-translations/ru-RU) +- [French](https://github.com/atom/electron/tree/master/docs-translations/fr-FR) ## Quick Start From a69341f551e0078d843edab7e289f3c65b4db0d9 Mon Sep 17 00:00:00 2001 From: Remi Sezille Date: Sat, 13 Feb 2016 18:19:49 +0100 Subject: [PATCH 199/688] Fix line length wrap [ci skip] --- docs-translations/fr-FR/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs-translations/fr-FR/README.md b/docs-translations/fr-FR/README.md index 04aed455612..666a03e99a3 100644 --- a/docs-translations/fr-FR/README.md +++ b/docs-translations/fr-FR/README.md @@ -1,11 +1,11 @@ Vérifiez que vous utilisez la bonne version de la documentation. Le numéro de version devrait faire partie de l'URL de la page. -Si ce n'est pas le cas, vous utilisez probablement la documentation d'une branche -de développement qui peut contenir des changements API qui ne sont pas compatibles -avec votre version d'Electron. Si c'est le cas, vous pouvez changer de version sur la -liste [versions disponibles](http://electron.atom.io/docs/), ou, si vous utilisez -l'interface de GitHub, ouvrez la liste déroulante "Switch branches/tags" afin de sélectionner -le tag de votre version. +Si ce n'est pas le cas, vous utilisez probablement la documentation d'une +branche de développement qui peut contenir des changements API qui ne sont pas +compatibles avec votre version d'Electron. Si c'est le cas, vous pouvez changer +de version sur la liste [versions disponibles](http://electron.atom.io/docs/), +ou, si vous utilisez l'interface de GitHub, ouvrez la liste déroulante "Switch +branches/tags" afin de sélectionner le tag de votre version. ## FAQ From efd25efaf4ea00c2fac14f1d6ee4a76fab89c57f Mon Sep 17 00:00:00 2001 From: Remi Sezille Date: Sat, 13 Feb 2016 18:20:34 +0100 Subject: [PATCH 200/688] Add FAQ [ci skip] --- docs-translations/fr-FR/faq/electron-faq.md | 129 ++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 docs-translations/fr-FR/faq/electron-faq.md diff --git a/docs-translations/fr-FR/faq/electron-faq.md b/docs-translations/fr-FR/faq/electron-faq.md new file mode 100644 index 00000000000..1a82bce6800 --- /dev/null +++ b/docs-translations/fr-FR/faq/electron-faq.md @@ -0,0 +1,129 @@ +# Electron FAQ + +## Quand est mise à jour la version de Chrome utilisée par Electron ? + +La version de Chrome qu'utilise Electron est en général mise à jour une ou deux +semaines après la sortie d'une nouvelle version stable de Chrome. + +Etant donné que nous n'utilisons que les versions stables de Chrome, si un fix +important est en beta ou en dev, nous l'intégrerons à la version que nous +utilisons. + +## Quand est mise à jour la version de Node.js utilisée par Electron ? + +Quand une nouvelle version de Node.js sort, nous attendons en général un mois +avant de mettre à jour celle que nous utilisons dans Electron. Ceci afin +d'éviter les bugs introduits par les nouvelles versions, ce qui arrive très +souvent. + +Les nouvelles fonctionnalités de Node.js arrivant la plupart du temps via V8, +et Electron utilisant le V8 du navigateur Chrome, la nouvelle fonctionnalité +JavaScript de la nouvelle version de Node.js est bien souvent déjà dans +Electron. + +## La fenêtre/barre d'état de mon application disparait après quelques minutes. + +Cela se produit quand la variable qui est utilisée pour stocker la fenêtre/barre +d'état est libérée par le ramasse-miettes. + +Nous vous recommandons de lire les articles suivants quand vous rencontrez le +problème : + +* [Management de la Mémoire][memory-management] (Anglais) +* [Portée d'une Variable][variable-scope] (Anglais) + +Si vous voulez corriger rapidement le problème, vous pouvez rendre les variables +globales en changeant votre code de ça : + +```javascript +app.on('ready', function() { + var tray = new Tray('/path/to/icon.png'); +}) +``` + +à ça : + +```javascript +var tray = null; +app.on('ready', function() { + tray = new Tray('/path/to/icon.png'); +}) +``` + +## Je n'arrive pas à utiliser jQuery/RequireJS/Meteor/AngularJS dans Electron. + +A cause de l'intégration de Node.js dans Electron, certains mots-clés sont +insérés dans la DOM, comme `module`, `exports`, `require`. Ceci pose des +problèmes pour certaines bibliothèques qui utilisent les mêmes mots-clés. + +Pour résoudre ce problème, vous pouvez désactiver l'intégration de node dans +Electron : + +```javascript +// Dans le processus principal. +var mainWindow = new BrowserWindow({ + webPreferences: { + nodeIntegration: false + } +}); +``` + +Mais si vous voulez garder la possibilité d'utiliser Node.js et les APIs +Electron, vous devez renommer les mots-clés dans la page avant d'inclure +d'autres bibliothèques : + +```html + + + + +``` + +## `require('electron').xxx` is undefined. + +Lors de l'utilisation des modules d'Electron, vous pouvez avoir une erreur : + +``` +> require('electron').webFrame.setZoomFactor(1.0); +Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined +``` + +Ceci se produit quand vous avez le [module npm `electron`][electron-module] +d'installé, soit en local ou en global, ce qui a pour effet d'écraser les +modules de base d'Electron. + +Vous vérifiez que vous utilisez les bons modules, vous pouvez afficher le +chemin du module `electron` : + +```javascript +console.log(require.resolve('electron')); +``` + +et vérifier si il est de la forme : + +``` +"/path/to/Electron.app/Contents/Resources/atom.asar/renderer/api/lib/exports/electron.js" +``` + +S'il est de la forme `node_modules/electron/index.js`, vous devez supprimer le +module npm `electron`, ou le renommer. + +```bash +npm uninstall electron +npm uninstall -g electron +``` + +Si vous utilisez le module de base mais que vous continuez d'avoir +l'erreur, ça vient probablement du fait que vous utilisez le module dans le +mauvais processus. Par exemple `electron.app` peut uniquement être utilisé +dans le processus principal, tandis que `electron.webFrame` est uniquement +disponible dans le processus d'affichage. + +[memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management +[variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx +[electron-module]: https://www.npmjs.com/package/electron From ef290ffcf2c1b3fdffb1eb004f0090026150bbe6 Mon Sep 17 00:00:00 2001 From: Remi Sezille Date: Sat, 13 Feb 2016 19:28:12 +0100 Subject: [PATCH 201/688] Add styleguide in french [ci skip] --- docs-translations/fr-FR/styleguide.md | 101 ++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 docs-translations/fr-FR/styleguide.md diff --git a/docs-translations/fr-FR/styleguide.md b/docs-translations/fr-FR/styleguide.md new file mode 100644 index 00000000000..5fe781773c1 --- /dev/null +++ b/docs-translations/fr-FR/styleguide.md @@ -0,0 +1,101 @@ +# Règles de style pour la documentation d'Electron + +Choisissez la section appropriée : [lire la documentation d'Electron](#reading-electron-documentation) +ou [écrire de la documentation pour Electron](#writing-electron-documentation). + +## Ecrire de la documentation pour Electron + +La documentation d'Electron a été écrite en suivant les règles ci-dessous : + +- Maximum un titre `h1` par page. +- Utilisation de `bash` au lieu de `cmd` dans les blocs de code (à cause de la + coloration syntaxique). +- Les titres `h1` devraient reprendre le nom de l'objet (i.e. `browser-window` → + `BrowserWindow`). + - Cependant, les traits d'union sont acceptés pour les noms de fichier. +- Pas de titre directement après un autre, ajoutez au minimum une ligne de + description entre les deux. +- Les entêtes des méthodes sont entre accents graves (backquotes) `code`. +- Les entêtes des évènements sont entre des apostrophes 'quotation'. +- Les listes ne doivent pas dépasser 2 niveaux (à cause du formattage du + markdown). +- Ajouter des titres de section: Evènements, Méthodes de classe, et Méthodes + d'instance. +- Utiliser 'will' au lieu de 'would' lors de la description du retour. +- Les évènements et méthodes sont des titres `h3`. +- Les arguments optionnels sont notés `function (required[, optional])`. +- Les arguments optionnels sont indiqués quand appelés dans la liste. +- La longueur des lignes ne dépasse pas 80 caractères. +- Les méthodes spécifiques à une plateforme sont notées en italique. + - ```### `method(foo, bar)` _OS X_``` +- Préférer 'in the ___ process' au lieu de 'on' + +### Traductions de la Documentation + +Les traductions de la documentation d'Electron sont dans le dossier +`docs-translations`. + +Pour ajouter une nouvelle langue (ou commencer) : + +- Créer un sous-dossier avec comme nom le code langage. +- A l'intérieur de ce dossier, dupliquer le dossier `docs`, en gardant le même + nom de dossiers et de fichiers. +- Traduire les fichiers. +- Mettre à jour le `README.md` à l'intérieur du dossier de langue en mettant les + liens vers les fichiers traduits. +- Ajouter un lien vers le nouveau dossier de langue dans le [README](https://github.com/atom/electron#documentation-translations) + principal d'Electron. + +## Lire la documentation d'Electron + +Quelques indications pour comprendre la syntaxe de la documentation d'Electron. + +### Méthodes + +Un exemple de la documentation d'une [méthode](https://developer.mozilla.org/en-US/docs/Glossary/Method) +(Anglais) + +--- + +`methodName(required[, optional]))` + +* `require` String (**required**) +* `optional` Integer + +--- + +Le nom de la méthode est suivi des arguments de celle-ci. Les arguments +optionnels sont notés entre crochets, avec une virgule si ceux-ci suivent un +autre argument. + +En-dessous de la méthode, chaque argument est détaillé avec son type. +Celui-ci peut être un type générique : +[`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), +[`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), +[`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), +[`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) +ou un type personnalisé comme le [`webContent`](api/web-content.md) d'Electron. + +### Evènements + +Un exemple d'une documentation d'un [évènement](https://developer.mozilla.org/en-US/docs/Web/API/Event) +(Anglais) +--- + +Event: 'wake-up' + +Returns: + +* `time` String + +--- + +L'évènement est une chaine utilisée après un listener `.on`. Si il retourne une +valeur, elle est écrite en dessous ainsi que son type. Si vous voulez écouter et +répondre à l'évènement wake-up, ça donne quelque chose comme : + +```javascript +Alarm.on('wake-up', function(time) { + console.log(time) +}) +``` From f63d8b4d5ec2a139e616acd14330630fd254105d Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Sun, 7 Feb 2016 16:02:48 +0900 Subject: [PATCH 202/688] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 2 +- docs-translations/ko-KR/api/browser-window.md | 2 +- docs-translations/ko-KR/api/clipboard.md | 13 +++++++++++++ docs-translations/ko-KR/api/ipc-renderer.md | 8 ++++---- docs-translations/ko-KR/api/session.md | 8 ++++---- .../ko-KR/tutorial/application-distribution.md | 5 ++--- .../ko-KR/tutorial/using-selenium-and-webdriver.md | 2 +- 7 files changed, 26 insertions(+), 14 deletions(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index ec4cb74c253..32412d13180 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -92,7 +92,7 @@ Returns: 이 이벤트를 처리할 땐 반드시 `event.preventDefault()`를 호출해야 합니다. -Windows에선 `process.argv`를 통해 파일 경로를 얻을 수 있습니다. +Windows에선 `process.argv` (메인 프로세스에서)를 통해 파일 경로를 얻을 수 있습니다. ### Event: 'open-url' _OS X_ diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index f79b201d0a1..f487a38f5da 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -773,7 +773,7 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 그리고 아이콘입니다. `null`로 지정하면 빈 오버레이가 사용됩니다 * `description` String - 접근성 설정에 의한 스크린 리더에 제공될 설명입니다 -현재 작업표시줄 아이콘에 16px 크기의 오버레이를 지정합니다. 보통 이 기능은 +현재 작업표시줄 아이콘에 16 x 16 픽셀 크기의 오버레이를 지정합니다. 보통 이 기능은 어플리케이션의 여러 상태를 사용자에게 소극적으로 알리기 위한 방법으로 사용됩니다. ### `win.setHasShadow(hasShadow)` _OS X_ diff --git a/docs-translations/ko-KR/api/clipboard.md b/docs-translations/ko-KR/api/clipboard.md index 2a0c98da2c0..df6475ad611 100644 --- a/docs-translations/ko-KR/api/clipboard.md +++ b/docs-translations/ko-KR/api/clipboard.md @@ -62,6 +62,19 @@ console.log(clipboard.readText('selection')); 클립보드에 `image`를 씁니다. +### `clipboard.readRtf([type])` + +* `type` String (optional) + +클립보드로부터 RTF 형식으로 컨텐츠를 읽어옵니다. + +### `clipboard.writeRtf(text[, type])` + +* `text` String +* `type` String (optional) + +클립보드에 `text`를 RTF 형식으로 씁니다. + ### `clipboard.clear([type])` * `type` String (optional) diff --git a/docs-translations/ko-KR/api/ipc-renderer.md b/docs-translations/ko-KR/api/ipc-renderer.md index aba632430b5..12fac95bbee 100644 --- a/docs-translations/ko-KR/api/ipc-renderer.md +++ b/docs-translations/ko-KR/api/ipc-renderer.md @@ -17,7 +17,7 @@ 이벤트가 일어나면 `event` 객체와 임의의 인자와 함께 `callback` 함수가 호출됩니다. -### `ipcMain.removeListener(channel, callback)` +### `ipcRenderer.removeListener(channel, callback)` * `channel` String - 이벤트의 이름 * `callback` Function - `ipcMain.on(channel, callback)`에서 사용한 함수의 레퍼런스 @@ -26,15 +26,15 @@ 메시지 전송을 멈출수 없을 때, 이 함수를 통해 지정한 채널에 대한 콜백을 삭제할 수 있습니다. -### `ipcMain.removeAllListeners(channel)` +### `ipcRenderer.removeAllListeners(channel)` * `channel` String - 이벤트의 이름 이 ipc 채널에 등록된 *모든* 핸들러들을 삭제합니다. -### `ipcMain.once(channel, callback)` +### `ipcRenderer.once(channel, callback)` -`ipcMain.on()` 대신 이 함수를 사용할 경우 핸들러가 단 한 번만 호출됩니다. +`ipcRenderer.on()` 대신 이 함수를 사용할 경우 핸들러가 단 한 번만 호출됩니다. `callback`이 한 번 호출된 이후 활성화되지 않습니다. ## 메시지 보내기 diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index 59eceb05a7a..5598fb6eb26 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -293,23 +293,23 @@ myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, c * `handler` Function * `webContents` Object - [WebContents](web-contents.md) 권한을 요청. * `permission` String - 'media', 'geolocation', 'notifications', - 'midiSysex'의 나열. + 'midiSysex', 'pointerLock', 'fullscreen'의 나열. * `callback` Function - 권한 허용 및 거부. `session`의 권한 요청에 응답을 하는데 사용하는 핸들러를 설정합니다. -`callback('granted')`를 호출하면 권한 제공을 허용하고 `callback('denied')`를 +`callback(true)`를 호출하면 권한 제공을 허용하고 `callback(false)`를 호출하면 권한 제공을 거부합니다. ```javascript session.fromPartition(partition).setPermissionRequestHandler(function(webContents, permission, callback) { if (webContents.getURL() === host) { if (permission == "notifications") { - callback(); // 거부됨. + callback(false); // 거부됨. return; } } - callback('granted'); + callback(true); }); ``` diff --git a/docs-translations/ko-KR/tutorial/application-distribution.md b/docs-translations/ko-KR/tutorial/application-distribution.md index 63533757415..7072d7c4d95 100644 --- a/docs-translations/ko-KR/tutorial/application-distribution.md +++ b/docs-translations/ko-KR/tutorial/application-distribution.md @@ -59,9 +59,8 @@ electron/resources/ ### Windows -`electron.exe`을 원하는 이름으로 변경할 수 있습니다. -그리고 [rcedit](https://github.com/atom/rcedit) -를 사용하여 아이콘을 변경할 수 있습니다. +[rcedit](https://github.com/atom/rcedit)를 통해 `electron.exe`을 원하는 이름으로 +변경할 수 있고, 또한 아이콘과 기타 정보도 변경할 수 있습니다. ### OS X diff --git a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md index d0684e0cfe1..6cc5472bb12 100644 --- a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md @@ -48,7 +48,7 @@ var driver = new webdriver.Builder() .withCapabilities({ chromeOptions: { // 여기에 사용중인 Electron 바이너리의 경로를 지정하세요. - binary: '/Path-to-Your-App.app/Contents/MacOS/Atom', + binary: '/Path-to-Your-App.app/Contents/MacOS/Electron', } }) .forBrowser('electron') From 17603d5dfbc7a98583e704502378c9867b26e999 Mon Sep 17 00:00:00 2001 From: Jacob Page Date: Sun, 14 Feb 2016 19:13:11 -0800 Subject: [PATCH 203/688] makeSingleInstance clarification Removed callback return value from the sample code for makeSingleInstance because it appears to not be used for anything. --- docs/api/app.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index adba230b0e2..5e56e970e1b 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -398,7 +398,7 @@ quit. On OS X the system enforces single instance automatically when users try to open a second instance of your app in Finder, and the `open-file` and `open-url` events will be emitted for that. However when users start your app in command -line the system's single instance machanism will be bypassed and you have to +line the system's single instance mechanism will be bypassed and you have to use this method to ensure single instance. An example of activating the window of primary instance when a second instance @@ -413,7 +413,6 @@ var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) if (myWindow.isMinimized()) myWindow.restore(); myWindow.focus(); } - return true; }); if (shouldQuit) { From 2c6e5d046440081dea4f7ce66925796d820c1b44 Mon Sep 17 00:00:00 2001 From: Luke Page Date: Fri, 12 Feb 2016 05:47:27 +0100 Subject: [PATCH 204/688] Clarify arguments sent via ipc --- docs/api/ipc-renderer.md | 2 +- docs/api/web-contents.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index 96936632563..d8f344a204a 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -52,7 +52,7 @@ The `ipcRenderer` module has the following methods for sending messages: * `arg` (optional) Send an event to the main process asynchronously via a `channel`, you can also -send arbitrary arguments. The main process handles it by listening for the +send arbitrary arguments. Arguments will be serialized (json) and hence no functions or prototype chain will be included. The main process handles it by listening for the `channel` event with `ipcMain`. ### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index afdd08c4d00..61c2ab1f691 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -693,7 +693,7 @@ Opens the developer tools for the service worker context. * `arg` (optional) Send an asynchronous message to renderer process via `channel`, you can also -send arbitrary arguments. The renderer process can handle the message by +send arbitrary arguments. Arguments will be serialized (json) and hence no functions or prototype chain will be included. The renderer process can handle the message by listening to the `channel` event with the `ipcRenderer` module. An example of sending messages from the main process to the renderer process: From a141d6b3d474fef058f5c152bb35e52597242926 Mon Sep 17 00:00:00 2001 From: Luke Page Date: Mon, 15 Feb 2016 06:51:20 +0100 Subject: [PATCH 205/688] spelling fixes and americanisms --- docs/api/app.md | 4 ++-- docs/api/browser-window.md | 4 ++-- docs/api/web-view-tag.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index adba230b0e2..4c806246e8f 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -246,7 +246,7 @@ returning `false` in the `beforeunload` event handler. ### `app.hide()` _OS X_ -Hides all application windows without minimising them. +Hides all application windows without minimizing them. ### `app.show()` _OS X_ @@ -398,7 +398,7 @@ quit. On OS X the system enforces single instance automatically when users try to open a second instance of your app in Finder, and the `open-file` and `open-url` events will be emitted for that. However when users start your app in command -line the system's single instance machanism will be bypassed and you have to +line the system's single instance mechanism will be bypassed and you have to use this method to ensure single instance. An example of activating the window of primary instance when a second instance diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 7cf684a3953..25e1de72933 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -58,7 +58,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `alwaysOnTop` Boolean - Whether the window should always stay on top of other windows. Default is `false`. * `fullscreen` Boolean - Whether the window should show in fullscreen. When - explicity set to `false` the fullscreen button will be hidden or disabled + explicitly set to `false` the fullscreen button will be hidden or disabled on OS X, or the maximize button will be disabled on Windows. Default is `false`. * `fullscreenable` Boolean - Whether the maximize/zoom button on OS X should @@ -717,7 +717,7 @@ Returns the pathname of the file the window represents. * `edited` Boolean Specifies whether the window’s document has been edited, and the icon in title -bar will become grey when set to `true`. +bar will become gray when set to `true`. ### `win.isDocumentEdited()` _OS X_ diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index c410287553a..6bdbb6826e8 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -522,7 +522,7 @@ Returns: * `explicitSet` Boolean Fired when page title is set during navigation. `explicitSet` is false when -title is synthesised from file url. +title is synthesized from file url. ### Event: 'page-favicon-updated' From 7c7e6ffc77c8b074949c2e0f7422db1db5c21c68 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 15 Feb 2016 16:36:01 +0800 Subject: [PATCH 206/688] Fix broken links in desktop-environment-integration.md Close #4404. --- docs/tutorial/desktop-environment-integration.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 7d7eb44ecb6..ac38f1088e7 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -294,15 +294,15 @@ window.setRepresentedFilename('/etc/passwd'); window.setDocumentEdited(true); ``` -[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath -[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments -[setusertaskstasks]: ../api/app.md#appsetusertaskstasks -[setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress -[setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename -[setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited +[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath-os-x-windows +[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-os-x-windows +[setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows +[setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress +[setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-os-x +[setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-os-x [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx [unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher -[setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons +[setthumbarbuttons]: ../api/browser-window.md#winsetthumbarbuttonsbuttons-windows-7 [tray-balloon]: ../api/tray.md#traydisplayballoonoptions-windows [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx [notification-spec]: https://developer.gnome.org/notification-spec/ From 367a3524b9686791d5b19e3aab2181e4ebce4035 Mon Sep 17 00:00:00 2001 From: Prayag Verma Date: Tue, 16 Feb 2016 07:51:14 +0530 Subject: [PATCH 207/688] docs: fix a minor typo Remove extra `will` --- docs/api/content-tracing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/content-tracing.md b/docs/api/content-tracing.md index aae5306523a..0b83c2759c6 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -155,7 +155,7 @@ called. * `eventName` String * `callback` Function -`callback` will will be called every time the given event occurs on any +`callback` will be called every time the given event occurs on any process. ### `contentTracing.cancelWatchEvent()` From ed1966ac760dcd2a7e80234c81319098bcf48ecb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 10:30:18 +0800 Subject: [PATCH 208/688] spec: Bring back beginFrameSubscription test --- spec/api-browser-window-spec.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 1c92d408c4c..89e9b770ab2 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -478,10 +478,16 @@ describe('browser-window module', function() { }); }); - xdescribe('beginFrameSubscription method', function() { + describe('beginFrameSubscription method', function() { it('subscribes frame updates', function(done) { + let called = false; w.loadURL("file://" + fixtures + "/api/blank.html"); w.webContents.beginFrameSubscription(function(data) { + // This callback might be called twice. + if (called) + return; + called = true; + assert.notEqual(data.length, 0); w.webContents.endFrameSubscription(); done(); From 66bb6a85341f67dbeed92b1aa2a149fa1b84d18c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 10:44:10 +0800 Subject: [PATCH 209/688] Use weak pointer instead of manual bookkeeping --- atom/browser/api/atom_api_web_contents.cc | 8 ++--- atom/browser/api/frame_subscriber.cc | 40 +++-------------------- atom/browser/api/frame_subscriber.h | 30 +++++------------ 3 files changed, 16 insertions(+), 62 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 1f441801407..a7946786c51 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1072,11 +1072,9 @@ void WebContents::BeginFrameSubscription( const FrameSubscriber::FrameCaptureCallback& callback) { const auto view = web_contents()->GetRenderWidgetHostView(); if (view) { - FrameSubscriber* frame_subscriber = new FrameSubscriber( - isolate(), view->GetVisibleViewportSize(), callback); - scoped_ptr del_frame_subscriber( - frame_subscriber->GetSubscriber()); - view->BeginFrameSubscription(del_frame_subscriber.Pass()); + scoped_ptr frame_subscriber(new FrameSubscriber( + isolate(), view->GetVisibleViewportSize(), callback)); + view->BeginFrameSubscription(frame_subscriber.Pass()); } } diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 7d973892405..b2b049ce8b7 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -13,58 +13,28 @@ namespace atom { namespace api { -using Subscriber = FrameSubscriber::Subscriber; - FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, const gfx::Size& size, const FrameCaptureCallback& callback) - : isolate_(isolate), size_(size), callback_(callback), pending_frames(0) { - subscriber_ = new Subscriber(this); + : isolate_(isolate), size_(size), callback_(callback), weak_factory_(this) { } -Subscriber::Subscriber( - FrameSubscriber* frame_subscriber) : frame_subscriber_(frame_subscriber) { -} - -Subscriber::~Subscriber() { - frame_subscriber_->subscriber_ = NULL; - frame_subscriber_->RequestDestruct(); -} - -bool Subscriber::ShouldCaptureFrame( +bool FrameSubscriber::ShouldCaptureFrame( const gfx::Rect& damage_rect, base::TimeTicks present_time, scoped_refptr* storage, DeliverFrameCallback* callback) { *storage = media::VideoFrame::CreateFrame( media::PIXEL_FORMAT_YV12, - frame_subscriber_->size_, gfx::Rect(frame_subscriber_->size_), - frame_subscriber_->size_, base::TimeDelta()); + size_, gfx::Rect(size_), size_, base::TimeDelta()); *callback = base::Bind(&FrameSubscriber::OnFrameDelivered, - base::Unretained(frame_subscriber_), *storage); - frame_subscriber_->pending_frames++; + weak_factory_.GetWeakPtr(), *storage); return true; } -Subscriber* FrameSubscriber::GetSubscriber() { - return subscriber_; -} - -bool FrameSubscriber::RequestDestruct() { - bool deletable = (subscriber_ == NULL && pending_frames == 0); - // Destruct FrameSubscriber if we're not waiting for frames and the - // subscription has ended - if (deletable) - delete this; - - return deletable; -} - void FrameSubscriber::OnFrameDelivered( scoped_refptr frame, base::TimeTicks, bool result) { - pending_frames--; - - if (RequestDestruct() || subscriber_ == NULL || !result) + if (!result) return; v8::Locker locker(isolate_); diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h index 6f6d66b6be8..089c4922d79 100644 --- a/atom/browser/api/frame_subscriber.h +++ b/atom/browser/api/frame_subscriber.h @@ -6,6 +6,7 @@ #define ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_ #include "base/callback.h" +#include "base/memory/weak_ptr.h" #include "content/public/browser/render_widget_host_view_frame_subscriber.h" #include "ui/gfx/geometry/size.h" #include "v8/include/v8.h" @@ -14,43 +15,28 @@ namespace atom { namespace api { -class FrameSubscriber { +class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { public: using FrameCaptureCallback = base::Callback)>; - // Inner class that is the actual subscriber sent to chromium - class Subscriber : - public content::RenderWidgetHostViewFrameSubscriber { - public: - explicit Subscriber(FrameSubscriber* frame_subscriber); - - bool ShouldCaptureFrame(const gfx::Rect& damage_rect, - base::TimeTicks present_time, - scoped_refptr* storage, - DeliverFrameCallback* callback) override; - - ~Subscriber(); - private: - FrameSubscriber* frame_subscriber_; - }; - FrameSubscriber(v8::Isolate* isolate, const gfx::Size& size, const FrameCaptureCallback& callback); - Subscriber* GetSubscriber(); + bool ShouldCaptureFrame(const gfx::Rect& damage_rect, + base::TimeTicks present_time, + scoped_refptr* storage, + DeliverFrameCallback* callback) override; private: void OnFrameDelivered( scoped_refptr frame, base::TimeTicks, bool); - bool RequestDestruct(); - v8::Isolate* isolate_; gfx::Size size_; FrameCaptureCallback callback_; - Subscriber* subscriber_; - int pending_frames; + + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(FrameSubscriber); }; From 3c4043fd3968a2c153b978251de3e84d4f58ace9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 11:00:36 +0800 Subject: [PATCH 210/688] spec: Skip autoUpdater tests in MAS build --- spec/api-auto-updater-spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/api-auto-updater-spec.js b/spec/api-auto-updater-spec.js index 72a1d90a7fe..efd3afe3882 100644 --- a/spec/api-auto-updater-spec.js +++ b/spec/api-auto-updater-spec.js @@ -2,6 +2,10 @@ const assert = require('assert'); const autoUpdater = require('electron').remote.autoUpdater; const ipcRenderer = require('electron').ipcRenderer; +// Skip autoUpdater tests in MAS build. +if (process.mas) + return; + describe('autoUpdater module', function() { describe('checkForUpdates', function() { it('emits an error on Windows when called the feed URL is not set', function (done) { From 2aff0c47d03458947dad5866069523fca717042f Mon Sep 17 00:00:00 2001 From: cesine Date: Mon, 15 Feb 2016 21:26:25 -0500 Subject: [PATCH 211/688] :arrow_up: :shirt: updated to eslint 2.1.0 Verified migration doc (nothing to be done) http://eslint.org/docs/user-guide/migrating-to-2.0.0 And made sure the eslint tasks passed --- atom/browser/lib/rpc-server.js | 6 ++++-- package.json | 2 +- spec/asar-spec.js | 1 - spec/fixtures/api/quit-app/main.js | 12 ++++++------ spec/fixtures/module/call.js | 4 ++-- spec/fixtures/module/id.js | 2 +- spec/fixtures/module/locale-compare.js | 2 +- spec/fixtures/module/original-fs.js | 2 +- spec/fixtures/module/print_name.js | 4 ++-- spec/fixtures/module/promise.js | 2 +- spec/fixtures/module/property.js | 2 +- spec/fixtures/module/send-later.js | 2 +- spec/fixtures/module/set-immediate.js | 2 +- spec/fixtures/workers/shared_worker.js | 6 +++--- spec/fixtures/workers/worker.js | 2 +- spec/static/main.js | 4 ++-- 16 files changed, 28 insertions(+), 27 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index 2f2b739e4a1..976a42331b6 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -130,7 +130,7 @@ var unwrapArgs = function(sender, args) { return Promise.resolve({ then: metaToValue(meta.then) }); - case 'object': + case 'object': { let ret = v8Util.createObjectWithName(meta.name); ref = meta.members; for (i = 0, len = ref.length; i < len; i++) { @@ -138,12 +138,13 @@ var unwrapArgs = function(sender, args) { ret[member.name] = metaToValue(member.value); } return ret; + } case 'function-with-return-value': returnValue = metaToValue(meta.value); return function() { return returnValue; }; - case 'function': + case 'function': { // Cache the callbacks in renderer. if (!sender.callbacks) { sender.callbacks = new IDWeakMap; @@ -172,6 +173,7 @@ var unwrapArgs = function(sender, args) { }); sender.callbacks.set(meta.id, callIntoRenderer); return callIntoRenderer; + } default: throw new TypeError("Unknown type: " + meta.type); } diff --git a/package.json b/package.json index 6d812087199..f684386269e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.36.7", "devDependencies": { "asar": "^0.9.0", - "eslint": "^1.10.3", + "eslint": "^2.1.0", "request": "*" }, "optionalDependencies": { diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 81d881f7eb4..a8f449451fc 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -517,7 +517,6 @@ describe('asar package', function() { }); }); describe('child_process.fork', function() { - child_process = require('child_process'); it('opens a normal js file', function(done) { var child; child = child_process.fork(path.join(fixtures, 'asar', 'a.asar', 'ping.js')); diff --git a/spec/fixtures/api/quit-app/main.js b/spec/fixtures/api/quit-app/main.js index e2f97affe6d..114e830076a 100644 --- a/spec/fixtures/api/quit-app/main.js +++ b/spec/fixtures/api/quit-app/main.js @@ -1,12 +1,12 @@ -var app = require('electron').app +var app = require('electron').app; app.on('ready', function () { // This setImmediate call gets the spec passing on Linux setImmediate(function () { - app.exit(123) - }) -}) + app.exit(123); + }); +}); process.on('exit', function (code) { - console.log('Exit event with code: ' + code) -}) + console.log('Exit event with code: ' + code); +}); diff --git a/spec/fixtures/module/call.js b/spec/fixtures/module/call.js index 4cf232e220d..ce0eb6324df 100644 --- a/spec/fixtures/module/call.js +++ b/spec/fixtures/module/call.js @@ -1,7 +1,7 @@ exports.call = function(func) { return func(); -} +}; exports.constructor = function() { this.test = 'test'; -} +}; diff --git a/spec/fixtures/module/id.js b/spec/fixtures/module/id.js index 2faec9d3832..5bfae457fe0 100644 --- a/spec/fixtures/module/id.js +++ b/spec/fixtures/module/id.js @@ -1 +1 @@ -exports.id = 1127 +exports.id = 1127; diff --git a/spec/fixtures/module/locale-compare.js b/spec/fixtures/module/locale-compare.js index f99e7c3be11..32dfb309926 100644 --- a/spec/fixtures/module/locale-compare.js +++ b/spec/fixtures/module/locale-compare.js @@ -1,4 +1,4 @@ -process.on('message', function (msg) { +process.on('message', function () { process.send([ 'a'.localeCompare('a'), 'ä'.localeCompare('z', 'de'), diff --git a/spec/fixtures/module/original-fs.js b/spec/fixtures/module/original-fs.js index 90b6abcf9b7..7a527c63358 100644 --- a/spec/fixtures/module/original-fs.js +++ b/spec/fixtures/module/original-fs.js @@ -1,3 +1,3 @@ -process.on('message', function (msg) { +process.on('message', function () { process.send(typeof require('original-fs')); }); diff --git a/spec/fixtures/module/print_name.js b/spec/fixtures/module/print_name.js index 01d13f4ba8b..96ac2d6f3cb 100644 --- a/spec/fixtures/module/print_name.js +++ b/spec/fixtures/module/print_name.js @@ -1,7 +1,7 @@ exports.print = function(obj) { return obj.constructor.name; -} +}; exports.echo = function(obj) { return obj; -} +}; diff --git a/spec/fixtures/module/promise.js b/spec/fixtures/module/promise.js index 2e52ed37440..b9b568855e3 100644 --- a/spec/fixtures/module/promise.js +++ b/spec/fixtures/module/promise.js @@ -2,4 +2,4 @@ exports.twicePromise = function (promise) { return promise.then(function (value) { return value * 2; }); -} +}; diff --git a/spec/fixtures/module/property.js b/spec/fixtures/module/property.js index 88e596f7308..36286d800e1 100644 --- a/spec/fixtures/module/property.js +++ b/spec/fixtures/module/property.js @@ -1 +1 @@ -exports.property = 1127 +exports.property = 1127; diff --git a/spec/fixtures/module/send-later.js b/spec/fixtures/module/send-later.js index 13f02452db1..704f47d328d 100644 --- a/spec/fixtures/module/send-later.js +++ b/spec/fixtures/module/send-later.js @@ -1,4 +1,4 @@ var ipcRenderer = require('electron').ipcRenderer; window.onload = function() { ipcRenderer.send('answer', typeof window.process); -} +}; diff --git a/spec/fixtures/module/set-immediate.js b/spec/fixtures/module/set-immediate.js index e7d44a75d1f..d36355ee23b 100644 --- a/spec/fixtures/module/set-immediate.js +++ b/spec/fixtures/module/set-immediate.js @@ -3,7 +3,7 @@ process.on('uncaughtException', function(error) { process.exit(1); }); -process.on('message', function(msg) { +process.on('message', function() { setImmediate(function() { process.send('ok'); process.exit(0); diff --git a/spec/fixtures/workers/shared_worker.js b/spec/fixtures/workers/shared_worker.js index d35b47435e8..40220793979 100644 --- a/spec/fixtures/workers/shared_worker.js +++ b/spec/fixtures/workers/shared_worker.js @@ -1,7 +1,7 @@ -onconnect = function(event) { +this.onconnect = function(event) { var port = event.ports[0]; port.start(); port.onmessage = function(event) { port.postMessage(event.data); - } -} + }; +}; diff --git a/spec/fixtures/workers/worker.js b/spec/fixtures/workers/worker.js index 6f9533708a0..4f445470b9a 100644 --- a/spec/fixtures/workers/worker.js +++ b/spec/fixtures/workers/worker.js @@ -1,3 +1,3 @@ this.onmessage = function(msg) { this.postMessage(msg.data); -} +}; diff --git a/spec/static/main.js b/spec/static/main.js index 125ef72f609..48fdf17c3dc 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -74,7 +74,7 @@ app.on('ready', function() { // Send auto updater errors to window to be verified in specs electron.autoUpdater.on('error', function (error) { - window.send('auto-updater-error', error.message) + window.send('auto-updater-error', error.message); }); window = new BrowserWindow({ @@ -108,7 +108,7 @@ app.on('ready', function() { // reply the result to renderer for verifying var downloadFilePath = path.join(__dirname, '..', 'fixtures', 'mock.pdf'); ipcMain.on('set-download-option', function(event, need_cancel, prevent_default) { - window.webContents.session.once('will-download', function(e, item, webContents) { + window.webContents.session.once('will-download', function(e, item) { if (prevent_default) { e.preventDefault(); const url = item.getURL(); From b8e8e4c930b3d06a2ae71f995b8b329ea41bd545 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 11:34:39 +0800 Subject: [PATCH 212/688] docs: Cleanup the IPC docs --- docs/api/ipc-main.md | 46 +++++++++++++++--------------- docs/api/ipc-renderer.md | 61 +++++++++++++++++++++------------------- docs/api/web-contents.md | 7 +++-- 3 files changed, 61 insertions(+), 53 deletions(-) diff --git a/docs/api/ipc-main.md b/docs/api/ipc-main.md index 337d86be217..84fbcfd5a72 100644 --- a/docs/api/ipc-main.md +++ b/docs/api/ipc-main.md @@ -9,7 +9,7 @@ module. ## Sending Messages It is also possible to send messages from the main process to the renderer -process, see [webContents.send](web-contents.md#webcontentssendchannel-arg1-arg2-) for more information. +process, see [webContents.send][web-contents-send] for more information. * When sending a message, the event name is the `channel`. * To reply a synchronous message, you need to set `event.returnValue`. @@ -48,37 +48,37 @@ ipcRenderer.send('asynchronous-message', 'ping'); The `ipcMain` module has the following method to listen for events: -### `ipcMain.on(channel, callback)` +### `ipcMain.on(channel, listener)` -* `channel` String - The event name. -* `callback` Function +* `channel` String +* `listener` Function -When the event occurs the `callback` is called with an `event` object and -arbitrary arguments. +Listens to `channel`, when a new message arrives `listener` would be called with +`listener(event, args...)`. -### `ipcMain.removeListener(channel, callback)` +### `ipcMain.once(channel, listener)` -* `channel` String - The event name. -* `callback` Function - The reference to the same function that you used for - `ipcMain.on(channel, callback)` +* `channel` String +* `listener` Function -Once done listening for messages, if you no longer want to activate this -callback and for whatever reason can't merely stop sending messages on the -channel, this function will remove the callback handler for the specified -channel. +Adds a one time `listener` function for the event. This `listener` is invoked +only the next time a message is sent to `channel`, after which it is removed. -### `ipcMain.removeAllListeners(channel)` +### `ipcMain.removeListener(channel, listener)` -* `channel` String - The event name. +* `channel` String +* `listener` Function -This removes *all* handlers to this ipc channel. +Removes the specified `listener` from the listener array for the specified +`channel`. -### `ipcMain.once(channel, callback)` +### `ipcMain.removeAllListeners([channel])` -Use this in place of `ipcMain.on()` to fire handlers meant to occur only once, -as in, they won't be activated after one call of `callback` +* `channel` String (optional) -## IPC Event +Removes all listeners, or those of the specified `channel`. + +## Event object The `event` object passed to the `callback` has the following methods: @@ -90,4 +90,6 @@ Set this to the value to be returned in a synchronous message. Returns the `webContents` that sent the message, you can call `event.sender.send` to reply to the asynchronous message, see -[webContents.send](web-contents.md#webcontentssendchannel-arg1-arg2-) for more information. +[webContents.send][web-contents-send] for more information. + +[web-contents-send]: web-contents.md#webcontentssendchannel-arg1-arg2- diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index d8f344a204a..f17843702b5 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -12,35 +12,35 @@ See [ipcMain](ipc-main.md) for code examples. The `ipcRenderer` module has the following method to listen for events: -### `ipcRenderer.on(channel, callback)` +### `ipcRenderer.on(channel, listener)` -* `channel` String - The event name. -* `callback` Function +* `channel` String +* `listener` Function -When the event occurs the `callback` is called with an `event` object and -arbitrary arguments. +Listens to `channel`, when a new message arrives `listener` would be called with +`listener(event, args...)`. -### `ipcRenderer.removeListener(channel, callback)` +### `ipcRenderer.once(channel, listener)` -* `channel` String - The event name. -* `callback` Function - The reference to the same function that you used for - `ipcRenderer.on(channel, callback)` +* `channel` String +* `listener` Function -Once done listening for messages, if you no longer want to activate this -callback and for whatever reason can't merely stop sending messages on the -channel, this function will remove the callback handler for the specified -channel. +Adds a one time `listener` function for the event. This `listener` is invoked +only the next time a message is sent to `channel`, after which it is removed. -### `ipcRenderer.removeAllListeners(channel)` +### `ipcRenderer.removeListener(channel, listener)` -* `channel` String - The event name. +* `channel` String +* `listener` Function -This removes *all* handlers to this ipc channel. +Removes the specified `listener` from the listener array for the specified +`channel`. -### `ipcRenderer.once(channel, callback)` +### `ipcRenderer.removeAllListeners([channel])` -Use this in place of `ipcRenderer.on()` to fire handlers meant to occur only once, -as in, they won't be activated after one call of `callback` +* `channel` String (optional) + +Removes all listeners, or those of the specified `channel`. ## Sending Messages @@ -48,30 +48,33 @@ The `ipcRenderer` module has the following methods for sending messages: ### `ipcRenderer.send(channel[, arg1][, arg2][, ...])` -* `channel` String - The event name. +* `channel` String * `arg` (optional) -Send an event to the main process asynchronously via a `channel`, you can also -send arbitrary arguments. Arguments will be serialized (json) and hence no functions or prototype chain will be included. The main process handles it by listening for the -`channel` event with `ipcMain`. +Send a message to the main process asynchronously via `channel`, you can also +send arbitrary arguments. Arguments will be serialized in JSON internally and +hence no functions or prototype chain will be included. + +The main process handles it by listening for `channel` with `ipcMain` module. ### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` -* `channel` String - The event name. +* `channel` String * `arg` (optional) -Send an event to the main process synchronously via a `channel`, you can also -send arbitrary arguments. +Send a message to the main process synchronously via `channel`, you can also +send arbitrary arguments. Arguments will be serialized in JSON internally and +hence no functions or prototype chain will be included. -The main process handles it by listening for the `channel` event with -`ipcMain` and replies by setting `event.returnValue`. +The main process handles it by listening for `channel` with `ipcMain` module, +and replies by setting `event.returnValue`. __Note:__ Sending a synchronous message will block the whole renderer process, unless you know what you are doing you should never use it. ### `ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])` -* `channel` String - The event name. +* `channel` String * `arg` (optional) Like `ipcRenderer.send` but the event will be sent to the `` element in diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 61c2ab1f691..b868bea9ed5 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -693,8 +693,11 @@ Opens the developer tools for the service worker context. * `arg` (optional) Send an asynchronous message to renderer process via `channel`, you can also -send arbitrary arguments. Arguments will be serialized (json) and hence no functions or prototype chain will be included. The renderer process can handle the message by -listening to the `channel` event with the `ipcRenderer` module. +send arbitrary arguments. Arguments will be serialized in JSON internally and +hence no functions or prototype chain will be included. + +The renderer process can handle the message by listening to `channel` with the +`ipcRenderer` module. An example of sending messages from the main process to the renderer process: From f58bab70c5146d63583af9179941d87fe11d7e60 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 11:52:47 +0800 Subject: [PATCH 213/688] docs: Improve the docs on sharing data --- docs/faq/electron-faq.md | 40 +++++++++++++++++------------------- docs/tutorial/quick-start.md | 18 ++++++++-------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index d5470f70173..a58d31107b6 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -18,40 +18,34 @@ New features of Node.js are usually brought by V8 upgrades, since Electron is using the V8 shipped by Chrome browser, the shiny new JavaScript feature of a new Node.js version is usually already in Electron. -## What are the different techniques to share objects between web pages? +## How to share data between web pages? -To share objects between web pages (that is on the renderer side) the simplest -and more natural technique is to use a web standard API already available in all -browsers. A good candidate is the -[Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Storage), -through either the -[`window.localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) property or the -[`window.sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) property. -Note that the Storage API allows only to store strings, so objects must be -serialized as JSON. -Another candidate is -[IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API). +To share data between web pages (the renderer processes) the simplest way is to +use HTML5 APIs which are already available in browsers. Good candidates are +[Storage API][storage], [`localStorage`][local-storage], +[`sessionStorage`][session-storage], and [IndexedDB][indexed-db]. -Another technique, but this time specific to Electron, is to store objects in -the main process as a global variable and then to access them from the renderers -through the `remote` module: +Or you can use the IPC system, which are specific to Electron, to store objects +in the main process as a global variable, and then to access them from the +renderers through the `remote` module: ```javascript -// In main.js of browser process -global.sharedObject = {}; +// In the main process. +global.sharedObject = { + someProperty: 'default value' +}; ``` ```javascript -// js in page-1.html -require('remote').getGlobal('sharedObject').someProperty = 'some value'; +// In page 1. +require('remote').getGlobal('sharedObject').someProperty = 'new value'; ``` ```javascript -// js in page-2.html +// In page 2. console.log(require('remote').getGlobal('sharedObject').someProperty); ``` - ## My app's window/tray disappeared after a few minutes. This happens when the variable which is used to store the window/tray gets @@ -154,3 +148,7 @@ is only available in renderer processes. [memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx [electron-module]: https://www.npmjs.com/package/electron +[storage]: https://developer.mozilla.org/en-US/docs/Web/API/Storage +[local-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage +[session-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage +[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index 67fe5d608a1..684c72c6669 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -34,8 +34,8 @@ The main process creates web pages by creating `BrowserWindow` instances. Each is also terminated. The main process manages all web pages and their corresponding renderer -processes. Each renderer process is isolated and only cares -about the web page running in it. +processes. Each renderer process is isolated and only cares about the web page +running in it. In web pages, calling native GUI related APIs is not allowed because managing native GUI resources in web pages is very dangerous and it is easy to leak @@ -43,13 +43,11 @@ resources. If you want to perform GUI operations in a web page, the renderer process of the web page must communicate with the main process to request that the main process perform those operations. -In Electron, we have provided the [ipc](../api/ipc-renderer.md) module for -communication between the main process and renderer process. There is also a -[remote](../api/remote.md) module for RPC style communication. - -And finally there are different techniques [to share objects between web -pages](../faq/electron-faq.md#what-are-the-different-techniques-to-share-objects-between-web-pages) -of the same window or of different windows. +In Electron, we have several ways to communicate between the main process and +renderer processes. Like [`ipcRenderer`](../api/ipc-renderer.md) and +[`ipcMain`](../api/ipc-main.md) modules for sending messages, and the +[remote](../api/remote.md) module for RPC style communication. There is also +an FAQ entry on [how to share data between web pages][share-data]. ## Write your First Electron App @@ -209,3 +207,5 @@ $ cd electron-quick-start # Install dependencies and run the app $ npm install && npm start ``` + +[share-data]: ../faq/electron-faq.md#how-to-share-data-between-web-pages From 2b406ccaf751bb2541b1924aae8204863bab6d4f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 11:54:41 +0800 Subject: [PATCH 214/688] Optional => optional --- docs/api/web-contents.md | 6 +++--- docs/api/web-view-tag.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index b868bea9ed5..c243425c5d9 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -259,8 +259,8 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - Indicates if more responses are to follow. - * `matches` Integer (Optional) - Number of Matches. - * `selectionArea` Object (Optional) - Coordinates of first match region. + * `matches` Integer (optional) - Number of Matches. + * `selectionArea` Object (optional) - Coordinates of first match region. Emitted when a result is available for [`webContents.findInPage`](web-contents.md#webcontentsfindinpage) request. @@ -503,7 +503,7 @@ Inserts `text` to the focused element. ### `webContents.findInPage(text[, options])` * `text` String - Content to be searched, must not be empty. -* `options` Object (Optional) +* `options` Object (optional) * `forward` Boolean - Whether to search forward or backward, defaults to `true`. * `findNext` Boolean - Whether the operation is first request or a follow up, defaults to `false`. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index c410287553a..976f859efca 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -382,7 +382,7 @@ Inserts `text` to the focused element. ### `.findInPage(text[, options])` * `text` String - Content to be searched, must not be empty. -* `options` Object (Optional) +* `options` Object (optional) * `forward` Boolean - Whether to search forward or backward, defaults to `true`. * `findNext` Boolean - Whether the operation is first request or a follow up, defaults to `false`. @@ -567,8 +567,8 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - Indicates if more responses are to follow. - * `matches` Integer (Optional) - Number of Matches. - * `selectionArea` Object (Optional) - Coordinates of first match region. + * `matches` Integer (optional) - Number of Matches. + * `selectionArea` Object (optional) - Coordinates of first match region. Fired when a result is available for [`webview.findInPage`](web-view-tag.md#webviewtagfindinpage) request. From fded8d80b118fa39cb5fd225e4412434f0bb31ee Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 12:11:05 +0800 Subject: [PATCH 215/688] docs: Remove unnecessary "properties: " suffix --- docs/api/browser-window.md | 53 +++++++++++++++++++------------------- docs/api/crash-reporter.md | 23 +++++++---------- docs/api/web-contents.md | 46 +++++++++++++-------------------- docs/api/web-view-tag.md | 2 +- 4 files changed, 56 insertions(+), 68 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 7cf684a3953..2bd6c1a9635 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -458,7 +458,7 @@ Returns a boolean, whether the window is in fullscreen mode. * `aspectRatio` The aspect ratio we want to maintain for some portion of the content view. * `extraSize` Object (optional) - The extra size not to be included while -maintaining the aspect ratio. Properties: +maintaining the aspect ratio. * `width` Integer * `height` Integer @@ -478,13 +478,11 @@ height areas you have within the overall content view. ### `win.setBounds(options[, animate])` -* `options` Object, properties: - +* `options` Object * `x` Integer * `y` Integer * `width` Integer * `height` Integer - * `animate` Boolean (optional) _OS X_ Resizes and moves the window to `width`, `height`, `x`, `y`. @@ -729,7 +727,7 @@ Whether the window's document has been edited. ### `win.capturePage([rect, ]callback)` -* `rect` Object (optional)- The area of page to be captured, properties: +* `rect` Object (optional) - The area of page to be captured * `x` Integer * `y` Integer * `width` Integer @@ -802,27 +800,7 @@ Returns whether the window has a shadow. On Windows and Linux always returns ### `win.setThumbarButtons(buttons)` _Windows 7+_ -`buttons` Array of `button` Objects: - -`button` Object, properties: - -* `icon` [NativeImage](native-image.md) - The icon showing in thumbnail - toolbar. -* `tooltip` String (optional) - The text of the button's tooltip. -* `flags` Array (optional) - Control specific states and behaviors - of the button. By default, it uses `enabled`. It can include following - Strings: - * `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 taskbar button's - flyout 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. -* `click` - Function +* `buttons` Array Add a thumbnail toolbar with a specified set of buttons to the thumbnail image of a window in a taskbar button layout. Returns a `Boolean` object indicates @@ -833,6 +811,29 @@ the limited room. Once you setup the thumbnail toolbar, the toolbar cannot be removed due to the platform's limitation. But you can call the API with an empty array to clean the buttons. +The `buttons` is an array of `Button` objects: + +* `Button` 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` Array (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. + ### `win.showDefinitionForSelection()` _OS X_ Shows pop-up dictionary that searches the selected word on the page. diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index 1b092826356..98465dffc97 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -22,19 +22,16 @@ The `crash-reporter` module has the following methods: ### `crashReporter.start(options)` -`options` Object, properties: - -* `productName` String, default: Electron. -* `companyName` String (**required**) -* `submitURL` String, (**required**) - * URL that crash reports will be sent to as POST. -* `autoSubmit` Boolean, default: `true`. - * Send the crash report without user interaction. -* `ignoreSystemCrashHandler` Boolean, default: `false`. -* `extra` Object - * An object you can define that will be sent along with the report. - * Only string properties are sent correctly. - * Nested objects are not supported. +* `options` Object + * `companyName` String + * `submitURL` String - URL that crash reports will be sent to as POST. + * `productName` String (optional) - Default is `Electron`. + * `autoSubmit` Boolean - Send the crash report without user interaction. + Default is `true`. + * `ignoreSystemCrashHandler` Boolean - Default is `false`. + * `extra` Object - An object you can define that will be sent along with the + report. Only string properties are sent correctly, Nested objects are not + supported. You are required to call this method before using other `crashReporter` APIs. diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index c243425c5d9..e0139a29fa6 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -310,7 +310,7 @@ The `webContents` object has the following instance methods: ### `webContents.loadURL(url[, options])` * `url` URL -* `options` Object (optional), properties: +* `options` Object (optional) * `httpReferrer` String - A HTTP Referrer url. * `userAgent` String - A user agent originating the request. * `extraHeaders` String - Extra headers separated by "\n" @@ -556,11 +556,10 @@ when the JS promise is rejected. ### `webContents.print([options])` -`options` Object (optional), properties: - -* `silent` Boolean - Don't ask user for print settings, defaults to `false` -* `printBackground` Boolean - Also prints the background color and image of - the web page, defaults to `false`. +* `options` Object (optional) + * `silent` Boolean - Don't ask user for print settings. Default is `false`. + * `printBackground` Boolean - Also prints the background color and image of + the web page. Default is `false`. Prints window's web page. When `silent` is set to `false`, Electron will pick up system's default printer and default settings for printing. @@ -574,31 +573,22 @@ size. ### `webContents.printToPDF(options, callback)` -`options` Object, properties: - -* `marginsType` Integer - Specify the type of margins to use - * 0 - default - * 1 - none - * 2 - minimum -* `pageSize` String - Specify page size of the generated PDF. - * `A5` - * `A4` - * `A3` - * `Legal` - * `Letter` - * `Tabloid` -* `printBackground` Boolean - Whether to print CSS backgrounds. -* `printSelectionOnly` Boolean - Whether to print selection only. -* `landscape` Boolean - `true` for landscape, `false` for portrait. - -`callback` Function - `function(error, data) {}` - -* `error` Error -* `data` Buffer - PDF file content. +* `options` Object + * `marginsType` Integer - Specifies the type of margins to use. Uses 0 for + default margin, 1 for no margin, and 2 for minimum margin. + * `pageSize` String - Specify page size of the generated PDF. Can be `A3`, + `A4`, `A5`, `Legal`, `Letter` and `Tabloid`. + * `printBackground` Boolean - Whether to print CSS backgrounds. + * `printSelectionOnly` Boolean - Whether to print selection only. + * `landscape` Boolean - `true` for landscape, `false` for portrait. +* `callback` Function Prints window's web page as PDF with Chromium's preview printing custom settings. +The `callback` will be called with `callback(error, data)` on completion. The +`data` is a `Buffer` that contains the generated PDF data. + By default, an empty `options` will be regarded as: ```javascript @@ -651,7 +641,7 @@ Removes the specified path from DevTools workspace. ### `webContents.openDevTools([options])` -* `options` Object (optional). Properties: +* `options` Object (optional) * `detach` Boolean - opens DevTools in a new window Opens the devtools. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 976f859efca..3ba9a602e8b 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -184,7 +184,7 @@ webview.addEventListener("dom-ready", function() { ### `.loadURL(url[, options])` * `url` URL -* `options` Object (optional), properties: +* `options` Object (optional) * `httpReferrer` String - A HTTP Referrer url. * `userAgent` String - A user agent originating the request. * `extraHeaders` String - Extra headers separated by "\n" From 81ffde3c2a88f7f2bc25532b97a26e96cc28432e Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Tue, 16 Feb 2016 09:55:59 +0900 Subject: [PATCH 216/688] :memo: Update as upstream [ci skip] --- .../desktop-environment-integration.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md index 91fc59a8f2e..cd6ff545e14 100644 --- a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md +++ b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md @@ -283,13 +283,15 @@ window.setRepresentedFilename('/etc/passwd'); window.setDocumentEdited(true); ``` -[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath -[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments -[setusertaskstasks]: ../api/app.md#appsetusertaskstasks -[setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress -[setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename -[setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited +[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath-os-x-windows +[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-os-x-windows +[setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows +[setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress +[setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-os-x +[setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-os-x [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx [unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher -[setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons -[trayballoon]: ../api/tray.md#traydisplayballoonoptions-windows +[setthumbarbuttons]: ../api/browser-window.md#winsetthumbarbuttonsbuttons-windows-7 +[tray-balloon]: ../api/tray.md#traydisplayballoonoptions-windows +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx +[notification-spec]: https://developer.gnome.org/notification-spec/ From aaca93046c5a6d0a16880ac0bc17c6890c57ffa9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 16:20:15 +0800 Subject: [PATCH 217/688] spec: Give beginFrameSubscription test more time to run --- spec/api-browser-window-spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index a38bdb16904..b64ef6145b7 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -480,6 +480,8 @@ describe('browser-window module', function() { }); describe('beginFrameSubscription method', function() { + this.timeout(20000); + it('subscribes frame updates', function(done) { let called = false; w.loadURL("file://" + fixtures + "/api/blank.html"); From afacca252e21804a4351570de7a7e879c95b5753 Mon Sep 17 00:00:00 2001 From: Destan Sarpkaya Date: Tue, 16 Feb 2016 16:24:05 +0200 Subject: [PATCH 218/688] add a new platform definition for linux On Linux in order for changes made to individual `MenuItem`s to take effect, you have to call `setContextMenu` again Regarding https://github.com/atom/electron/issues/1473 --- docs/api/tray.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/api/tray.md b/docs/api/tray.md index 08a43638be1..3d6f94ad0e5 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -32,6 +32,12 @@ __Platform limitations:__ install `libappindicator1` to make the tray icon work. * App indicator will only be shown when it has a context menu. * When app indicator is used on Linux, the `click` event is ignored. +* On Linux in order for changes made to individual `MenuItem`s to take effect, you have to call `setContextMenu` again. For example: + +```javascript +appIcon.menu.items[2].checked = false; +appIcon.setContextMenu(trayIcon.menu); +``` If you want to keep exact same behaviors on all platforms, you should not rely on the `click` event and always attach a context menu to the tray icon. From 0ba86b971633399b7d18086fdce1389718198f43 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 16 Feb 2016 23:10:05 +0800 Subject: [PATCH 219/688] docs: Make variable names follow previous example --- docs/api/tray.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/api/tray.md b/docs/api/tray.md index 3d6f94ad0e5..22ab9aea5b7 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -32,11 +32,12 @@ __Platform limitations:__ install `libappindicator1` to make the tray icon work. * App indicator will only be shown when it has a context menu. * When app indicator is used on Linux, the `click` event is ignored. -* On Linux in order for changes made to individual `MenuItem`s to take effect, you have to call `setContextMenu` again. For example: +* On Linux in order for changes made to individual `MenuItem`s to take effect, + you have to call `setContextMenu` again. For example: ```javascript -appIcon.menu.items[2].checked = false; -appIcon.setContextMenu(trayIcon.menu); +contextMenu.items[2].checked = false; +appIcon.setContextMenu(contextMenu); ``` If you want to keep exact same behaviors on all platforms, you should not From 959c08a1ecdc31bb7c39ff3a4fcdf0c59bfbe50b Mon Sep 17 00:00:00 2001 From: dmnlk Date: Wed, 17 Feb 2016 02:20:38 +0900 Subject: [PATCH 220/688] add Japanese Electron Community --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ce6d483f0df..0080585b54c 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ forums - [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack - [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)* - [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)* +- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(Japanese)* Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron) for a community maintained list of useful example apps, tools and resources. From 2346caf6fbb691b7a2c7fe73e363344f371a8027 Mon Sep 17 00:00:00 2001 From: Seemann Date: Tue, 16 Feb 2016 23:19:20 +0300 Subject: [PATCH 221/688] fixed typo in the russian translation of README.md --- docs-translations/ru-RU/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/ru-RU/README.md b/docs-translations/ru-RU/README.md index 07e50028df9..4e7ed443468 100644 --- a/docs-translations/ru-RU/README.md +++ b/docs-translations/ru-RU/README.md @@ -1,6 +1,6 @@ Пожалуйста, убедитесь, что вы используете документацию, которые соответствует вашей версии Electron. Номер версии должен быть частью адреса страницы. Если это не так, вы -возможно,используете документицию ветки разработки, которая может содержать изменения api, +возможно, используете документацию ветки разработки, которая может содержать изменения api, которые не совместимы с вашей версией Electron. Если это так, Вы можете переключиться на другую версию документации в списке [доступные версии](http://electron.atom.io/docs/) на atom.io, или From ccef805e9b85c4e17114e68cb14070c98e8a166c Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 16 Feb 2016 15:09:35 -0800 Subject: [PATCH 222/688] Add API for custom handling of deprecations --- atom/common/api/lib/deprecate.js | 14 ++++++++++++- atom/common/api/lib/deprecations.js | 11 ++++++++++ atom/common/api/lib/exports/electron.js | 6 ++++++ filenames.gypi | 1 + spec/api-deprecations-spec.js | 27 +++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 atom/common/api/lib/deprecations.js create mode 100644 spec/api-deprecations-spec.js diff --git a/atom/common/api/lib/deprecate.js b/atom/common/api/lib/deprecate.js index dcaf5f6cf6f..04b56e06b96 100644 --- a/atom/common/api/lib/deprecate.js +++ b/atom/common/api/lib/deprecate.js @@ -88,9 +88,13 @@ deprecate.warn = function(oldName, newName) { return deprecate.log(oldName + " is deprecated. Use " + newName + " instead."); }; +var deprecationHandler = null; + // Print deprecation message. deprecate.log = function(message) { - if (process.throwDeprecation) { + if (typeof deprecationHandler === 'function') { + deprecationHandler(message); + } else if (process.throwDeprecation) { throw new Error(message); } else if (process.traceDeprecation) { return console.trace(message); @@ -99,4 +103,12 @@ deprecate.log = function(message) { } }; +deprecate.setHandler = function(handler) { + deprecationHandler = handler; +}; + +deprecate.getHandler = function() { + return deprecationHandler; +} + module.exports = deprecate; diff --git a/atom/common/api/lib/deprecations.js b/atom/common/api/lib/deprecations.js new file mode 100644 index 00000000000..871ad036272 --- /dev/null +++ b/atom/common/api/lib/deprecations.js @@ -0,0 +1,11 @@ +'use strict'; + +const deprecate = require('electron').deprecate; + +exports.setHandler = function (deprecationHandler) { + deprecate.setHandler(deprecationHandler); +}; + +exports.getHandler = function () { + return deprecate.getHandler(); +} diff --git a/atom/common/api/lib/exports/electron.js b/atom/common/api/lib/exports/electron.js index 6811e73a10b..51ab48ded83 100644 --- a/atom/common/api/lib/exports/electron.js +++ b/atom/common/api/lib/exports/electron.js @@ -31,6 +31,12 @@ exports.defineProperties = function(exports) { return require('../crash-reporter'); } }, + deprecations: { + enumerable: true, + get: function() { + return require('../deprecations'); + } + }, nativeImage: { enumerable: true, get: function() { diff --git a/filenames.gypi b/filenames.gypi index a5369570cad..abb11453210 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -41,6 +41,7 @@ 'atom/common/api/lib/clipboard.js', 'atom/common/api/lib/crash-reporter.js', 'atom/common/api/lib/deprecate.js', + 'atom/common/api/lib/deprecations.js', 'atom/common/api/lib/exports/electron.js', 'atom/common/api/lib/native-image.js', 'atom/common/api/lib/shell.js', diff --git a/spec/api-deprecations-spec.js b/spec/api-deprecations-spec.js new file mode 100644 index 00000000000..282991a6858 --- /dev/null +++ b/spec/api-deprecations-spec.js @@ -0,0 +1,27 @@ +const assert = require('assert'); +const deprecations = require('electron').deprecations; + +describe('deprecations', function() { + beforeEach(function() { + deprecations.setHandler(null); + process.throwDeprecation = true; + }); + + it('allows a deprecation handler function to be specified', function() { + var messages = []; + + deprecations.setHandler(function (message) { + messages.push(message) + }); + + require('electron').webFrame.registerUrlSchemeAsSecure('some-scheme') + + assert.deepEqual(messages, ['registerUrlSchemeAsSecure is deprecated. Use registerURLSchemeAsSecure instead.']); + }); + + it('throws an exception if no deprecation handler is specified', function() { + assert.throws(function() { + require('electron').webFrame.registerUrlSchemeAsPrivileged('some-scheme') + }, "registerUrlSchemeAsPrivileged is deprecated. Use registerURLSchemeAsPrivileged instead."); + }); +}) From 3e3e59336600c88ebb5220c5be35fd3c07549878 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 16 Feb 2016 15:26:58 -0800 Subject: [PATCH 223/688] :shirt: Add missing semicolons --- atom/common/api/lib/deprecate.js | 2 +- atom/common/api/lib/deprecations.js | 2 +- spec/api-deprecations-spec.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/atom/common/api/lib/deprecate.js b/atom/common/api/lib/deprecate.js index 04b56e06b96..852d544deea 100644 --- a/atom/common/api/lib/deprecate.js +++ b/atom/common/api/lib/deprecate.js @@ -109,6 +109,6 @@ deprecate.setHandler = function(handler) { deprecate.getHandler = function() { return deprecationHandler; -} +}; module.exports = deprecate; diff --git a/atom/common/api/lib/deprecations.js b/atom/common/api/lib/deprecations.js index 871ad036272..e4290c74947 100644 --- a/atom/common/api/lib/deprecations.js +++ b/atom/common/api/lib/deprecations.js @@ -8,4 +8,4 @@ exports.setHandler = function (deprecationHandler) { exports.getHandler = function () { return deprecate.getHandler(); -} +}; diff --git a/spec/api-deprecations-spec.js b/spec/api-deprecations-spec.js index 282991a6858..2f010059059 100644 --- a/spec/api-deprecations-spec.js +++ b/spec/api-deprecations-spec.js @@ -11,17 +11,17 @@ describe('deprecations', function() { var messages = []; deprecations.setHandler(function (message) { - messages.push(message) + messages.push(message); }); - require('electron').webFrame.registerUrlSchemeAsSecure('some-scheme') + require('electron').webFrame.registerUrlSchemeAsSecure('some-scheme'); assert.deepEqual(messages, ['registerUrlSchemeAsSecure is deprecated. Use registerURLSchemeAsSecure instead.']); }); it('throws an exception if no deprecation handler is specified', function() { assert.throws(function() { - require('electron').webFrame.registerUrlSchemeAsPrivileged('some-scheme') + require('electron').webFrame.registerUrlSchemeAsPrivileged('some-scheme'); }, "registerUrlSchemeAsPrivileged is deprecated. Use registerURLSchemeAsPrivileged instead."); }); -}) +}); From 407bef5727a8bf36fd011d4e6e6800386b236ac3 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 17 Feb 2016 00:40:35 +0900 Subject: [PATCH 224/688] :memo: Update as upstream [ci skip] --- README-ko.md | 1 + docs-translations/ko-KR/api/browser-window.md | 46 +++++++------- docs-translations/ko-KR/api/crash-reporter.md | 22 +++---- docs-translations/ko-KR/api/ipc-main.md | 44 +++++++------ docs-translations/ko-KR/api/ipc-renderer.md | 51 +++++++++------- docs-translations/ko-KR/api/web-contents.md | 61 ++++++++----------- docs-translations/ko-KR/api/web-view-tag.md | 8 +-- docs-translations/ko-KR/faq/electron-faq.md | 32 ++++++++++ .../desktop-environment-integration.md | 28 +++++++++ .../ko-KR/tutorial/quick-start.md | 5 +- 10 files changed, 182 insertions(+), 116 deletions(-) diff --git a/README-ko.md b/README-ko.md index 664075dd481..b9085828d46 100644 --- a/README-ko.md +++ b/README-ko.md @@ -57,6 +57,7 @@ API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝 - [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW) - [우크라이나어](https://github.com/atom/electron/tree/master/docs-translations/uk-UA) - [러시아어](https://github.com/atom/electron/tree/master/docs-translations/ru-RU) +- [프랑스어](https://github.com/atom/electron/tree/master/docs-translations/fr-FR) ## 시작하기 diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index f487a38f5da..8bc4a1545fc 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -451,7 +451,6 @@ var win = new BrowserWindow({ width: 800, height: 600 }); * `aspectRatio` 유지하려 하는 컨텐츠 뷰 일부의 종횡비 * `extraSize` Object (optional) - 종횡비를 유지하는 동안 포함되지 않을 엑스트라 크기. - 사용 가능한 속성: * `width` Integer * `height` Integer @@ -469,7 +468,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.setBounds(options[, animate])` -* `options` Object, properties: +* `options` Object * `x` Integer * `y` Integer @@ -719,8 +718,7 @@ Windows 메시지 훅을 등록합니다. `callback`은 WndProc에서 메시지 ### `win.capturePage([rect, ]callback)` -* `rect` Object (optional) - 캡쳐할 페이지의 영역. - 사용할 수 있는 속성은 다음과 같습니다: +* `rect` Object (optional) - 캡쳐할 페이지의 영역 * `x` Integer * `y` Integer * `width` Integer @@ -790,34 +788,34 @@ Linux 플랫폼에선 Unity 데스크톱 환경만 지원합니다. 그리고 ### `win.setThumbarButtons(buttons)` _Windows 7+_ -`buttons` - `button` 객체의 배열 - -`button` 객체는 다음과 같은 속성을 가지고 있습니다: - -* `icon` [NativeImage](native-image.md) - 미리보기 툴바에 보여질 아이콘. -* `tooltip` String (optional) - 버튼의 툴팁 텍스트. -* `flags` Array (optional) - 버튼의 특정 동작 및 상태 제어. 기본적으로 `enabled`이 - 사용됩니다. 이 속성은 다음 문자열들을 포함할 수 있습니다: - * `enabled` - 사용자가 사용할 수 있도록 버튼이 활성화 됩니다. - * `disabled` - 버튼이 비활성화 됩니다. 버튼은 표시되지만 시각적인 상태는 사용자의 - 동작에 응답하지 않는 비활성화 상태로 표시됩니다. - * `dismissonclick` - 버튼이 클릭되면 작업표시줄 버튼의 미리보기(flyout)가 즉시 - 종료됩니다. - * `nobackground` - 버튼의 테두리를 표시하지 않습니다. 이미지에만 사용할 수 있습니다. - * `hidden` - 버튼을 사용자에게 표시되지 않도록 숨깁니다. - * `noninteractive` - 버튼은 활성화되어 있지만 반응이 제거되며 버튼을 눌러도 - 눌려지지 않은 상태를 유지합니다. 이 값은 버튼을 알림의 용도로 사용하기 위해 - 만들어졌습니다. -* `click` - Function +* `buttons` - Array 윈도우 작업표시줄 버튼 레이아웃의 미리보기 이미지 영역에 미리보기 툴바와 버튼 세트를 -지정합니다. 반환되는 `Boolean` 값은 미리보기 툴바가 성공적으로 추가됬는지를 알려줍니다. +추가합니다. 반환되는 `Boolean` 값은 미리보기 툴바가 성공적으로 추가됬는지를 알려줍니다. 미리보기 이미지 영역의 제한된 크기로 인해 미리보기 툴바에 추가될 수 있는 최대 버튼의 개수는 7개이며 이 이상 추가될 수 없습니다. 플랫폼의 제약으로 인해 미리보기 툴바는 한 번 설정되면 삭제할 수 없습니다. 하지만 이 API에 빈 배열을 전달하여 버튼들을 제거할 수 있습니다. +`buttons`는 `Button` 객체의 배열입니다: + +* `Button` 객체 + * `icon` [NativeImage](native-image.md) - 미리보기 툴바에 보여질 아이콘. + * `tooltip` String (optional) - 버튼의 툴팁 텍스트. + * `flags` Array (optional) - 버튼의 특정 동작 및 상태 제어. 기본적으로 `enabled`이 + 사용됩니다. 이 속성은 다음 문자열들을 포함할 수 있습니다: + * `enabled` - 사용자가 사용할 수 있도록 버튼이 활성화 됩니다. + * `disabled` - 버튼이 비활성화 됩니다. 버튼은 표시되지만 시각적인 상태는 사용자의 + 동작에 응답하지 않는 비활성화 상태로 표시됩니다. + * `dismissonclick` - 버튼이 클릭되면 작업표시줄 버튼의 미리보기(flyout)가 즉시 + 종료됩니다. + * `nobackground` - 버튼의 테두리를 표시하지 않습니다. 이미지에만 사용할 수 있습니다. + * `hidden` - 버튼을 사용자에게 표시되지 않도록 숨깁니다. + * `noninteractive` - 버튼은 활성화되어 있지만 반응이 제거되며 버튼을 눌러도 + 눌려지지 않은 상태를 유지합니다. 이 값은 버튼을 알림의 용도로 사용하기 위해 + 만들어졌습니다. + ### `win.showDefinitionForSelection()` _OS X_ 페이지의 선택된 단어에 대한 사전 검색 결과 팝업을 표시합니다. diff --git a/docs-translations/ko-KR/api/crash-reporter.md b/docs-translations/ko-KR/api/crash-reporter.md index 0b7daba14dd..81713760a85 100644 --- a/docs-translations/ko-KR/api/crash-reporter.md +++ b/docs-translations/ko-KR/api/crash-reporter.md @@ -22,19 +22,15 @@ crashReporter.start({ ### `crashReporter.start(options)` -* `options` Object, properties: - -* `productName` String, 기본값: Electron -* `companyName` String (**필수항목**) -* `submitURL` String, (**필수항목**) - * 크래시 리포트는 POST 방식으로 이 URL로 전송됩니다. -* `autoSubmit` Boolean, 기본값: true - * true로 지정할 경우 유저의 승인 없이 자동으로 오류를 보고합니다. -* `ignoreSystemCrashHandler` Boolean, 기본값: false -* `extra` Object - * 크래시 리포트 시 같이 보낼 추가 정보를 지정하는 객체입니다. - * 문자열로 된 속성만 정상적으로 보내집니다. - * 중첩 객체는 지원되지 않습니다. (Nested objects are not supported) +* `options` Object + * `companyName` String + * `submitURL` String - 크래시 리포트는 POST 방식으로 이 URL로 전송됩니다. + * `productName` String (optional) - 기본값은 `Electron` 입니다. + * `autoSubmit` Boolean - 유저의 승인 없이 자동으로 오류를 보고합니다. 기본값은 + `true` 입니다. + * `ignoreSystemCrashHandler` Boolean - 기본값은 `false` 입니다. + * `extra` Object - 크래시 리포트 시 같이 보낼 추가 정보를 지정하는 객체입니다. + 문자열로 된 속성만 정상적으로 보내집니다. 중첩된 객체는 지원되지 않습니다. 다른 crashReporter API를 사용하기 전에 이 메서드를 먼저 호출해야 합니다. diff --git a/docs-translations/ko-KR/api/ipc-main.md b/docs-translations/ko-KR/api/ipc-main.md index 3ae519d294b..30b10247f9d 100644 --- a/docs-translations/ko-KR/api/ipc-main.md +++ b/docs-translations/ko-KR/api/ipc-main.md @@ -8,8 +8,7 @@ ## 메시지 전송 물론 메시지를 받는 것 말고도 메인 프로세스에서 랜더러 프로세스로 보내는 것도 가능합니다. -자세한 내용은 [webContents.send](web-contents.md#webcontentssendchannel-arg1-arg2-)를 -참고하세요. +자세한 내용은 [webContents.send][web-contents-send]를 참고하세요. * 메시지를 전송할 때 이벤트 이름은 `channel`이 됩니다. * 메시지에 동기로 응답할 땐 반드시 `event.returnValue`를 설정해야 합니다. @@ -46,34 +45,40 @@ ipcRenderer.send('asynchronous-message', 'ping'); `ipcMain`은 다음과 같은 이벤트 리스닝 메서드를 가지고 있습니다: -### `ipcMain.on(channel, callback)` +### `ipcMain.on(channel, listener)` -* `channel` String - 이벤트 이름 -* `callback` Function +* `channel` String +* `listener` Function -이벤트가 발생하면 `event` 객체와 임의 메시지와 함께 `callback`이 호출됩니다. +`channel`에 대해 이벤트를 리스닝합니다. 새로운 메시지가 도착하면 `listener`가 +`listener(event, args...)` 형식으로 호출됩니다. -### `ipcMain.removeListener(channel, callback)` +### `ipcMain.once(channel, listener)` -* `channel` String - 이벤트의 이름 -* `callback` Function - `ipcMain.on(channel, callback)`에서 사용한 함수의 레퍼런스 +* `channel` String +* `listener` Function + +이벤트에 대해 한 번만 작동하는 `listener` 함수를 등록합니다. 이 `listener`는 등록된 +후 `channel`에 보내지는 메시지에 한해 호출됩니다. 호출된 이후엔 리스너가 삭제됩니다. + +### `ipcMain.removeListener(channel, listener)` + +* `channel` String +* `listener` Function 메시지 수신을 완료한 후, 더 이상의 콜백이 필요하지 않을 때 또는 몇 가지 이유로 채널의 메시지 전송을 멈출수 없을 때, 이 함수를 통해 지정한 채널에 대한 콜백을 삭제할 수 있습니다. +지정한 `channel`에 대한 리스너를 저장하는 배열에서 지정한 `listener`를 삭제합니다. + ### `ipcMain.removeAllListeners(channel)` -* `channel` String - 이벤트의 이름 +* `channel` String (optional) -이 ipc 채널에 등록된 *모든* 핸들러들을 삭제합니다. +이 ipc 채널에 등록된 모든 핸들러들을 삭제하거나 지정한 `channel`을 삭제합니다. -### `ipcMain.once(channel, callback)` - -`ipcMain.on()` 대신 이 함수를 사용할 경우 핸들러가 단 한 번만 호출됩니다. -`callback`이 한 번 호출된 이후 활성화되지 않습니다. - -## IPC Event +## Event 객체 `callback`에서 전달된 `event` 객체는 다음과 같은 메서드와 속성을 가지고 있습니다: @@ -85,5 +90,6 @@ ipcRenderer.send('asynchronous-message', 'ping'); 메시지를 보낸 `webContents` 객체를 반환합니다. `event.sender.send` 메서드를 통해 비동기로 메시지를 전달할 수 있습니다. 자세한 내용은 -[webContents.send](web-contents.md#webcontentssendchannel-arg1-arg2-)를 -참고하세요. +[webContents.send][web-contents-send]를 참고하세요. + +[web-contents-send]: web-contents.md#webcontentssendchannel-arg1-arg2- diff --git a/docs-translations/ko-KR/api/ipc-renderer.md b/docs-translations/ko-KR/api/ipc-renderer.md index 12fac95bbee..0d43b157d16 100644 --- a/docs-translations/ko-KR/api/ipc-renderer.md +++ b/docs-translations/ko-KR/api/ipc-renderer.md @@ -10,32 +10,38 @@ `ipcRenderer`는 다음과 같은 이벤트 리스닝 메서드를 가지고 있습니다: -### `ipcRenderer.on(channel, callback)` +### `ipcMain.on(channel, listener)` -* `channel` String - 이벤트 이름 -* `callback` Function +* `channel` String +* `listener` Function -이벤트가 일어나면 `event` 객체와 임의의 인자와 함께 `callback` 함수가 호출됩니다. +`channel`에 대해 이벤트를 리스닝합니다. 새로운 메시지가 도착하면 `listener`가 +`listener(event, args...)` 형식으로 호출됩니다. -### `ipcRenderer.removeListener(channel, callback)` +### `ipcMain.once(channel, listener)` -* `channel` String - 이벤트의 이름 -* `callback` Function - `ipcMain.on(channel, callback)`에서 사용한 함수의 레퍼런스 +* `channel` String +* `listener` Function + +이벤트에 대해 한 번만 작동하는 `listener` 함수를 등록합니다. 이 `listener`는 등록된 +후 `channel`에 보내지는 메시지에 한해 호출됩니다. 호출된 이후엔 리스너가 삭제됩니다. + +### `ipcMain.removeListener(channel, listener)` + +* `channel` String +* `listener` Function 메시지 수신을 완료한 후, 더 이상의 콜백이 필요하지 않을 때 또는 몇 가지 이유로 채널의 메시지 전송을 멈출수 없을 때, 이 함수를 통해 지정한 채널에 대한 콜백을 삭제할 수 있습니다. -### `ipcRenderer.removeAllListeners(channel)` +지정한 `channel`에 대한 리스너를 저장하는 배열에서 지정한 `listener`를 삭제합니다. -* `channel` String - 이벤트의 이름 +### `ipcMain.removeAllListeners(channel)` -이 ipc 채널에 등록된 *모든* 핸들러들을 삭제합니다. +* `channel` String (optional) -### `ipcRenderer.once(channel, callback)` - -`ipcRenderer.on()` 대신 이 함수를 사용할 경우 핸들러가 단 한 번만 호출됩니다. -`callback`이 한 번 호출된 이후 활성화되지 않습니다. +이 ipc 채널에 등록된 모든 핸들러들을 삭제하거나 지정한 `channel`을 삭제합니다. ## 메시지 보내기 @@ -43,23 +49,26 @@ ### `ipcRenderer.send(channel[, arg1][, arg2][, ...])` -* `channel` String - 이벤트 이름 +* `channel` String * `arg` (optional) `channel`을 통해 메인 프로세스에 비동기 메시지를 보냅니다. 그리고 필요에 따라 임의의 -인자를 사용할 수도 있습니다. 메인 프로세스는 `ipcMain` 모듈의 `channel` 이벤트를 통해 +인수를 사용할 수도 있습니다. 인수들은 내부적으로 JSON 포맷으로 직렬화 되며, 이후 함수와 +프로토타입 체인은 포함되지 않게 됩니다. + +메인 프로세스는 `ipcMain` 모듈의 `channel` 이벤트를 통해 이벤트를 리스닝 할 수 있습니다. ### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` -* `channel` String - 이벤트 이름 +* `channel` String * `arg` (optional) `channel`을 통해 메인 프로세스에 동기 메시지를 보냅니다. 그리고 필요에 따라 임의의 -인자를 사용할 수도 있습니다. 메인 프로세스는 `ipc`를 통해 `channel` 이벤트를 리스닝 -할 수 있습니다. +인자를 사용할 수도 있습니다. 인수들은 내부적으로 JSON 포맷으로 직렬화 되며, 이후 함수와 +프로토타입 체인은 포함되지 않게 됩니다. -메인 프로세스에선 `ipcMain` 모듈의 `channel` 이벤트를 통해 받은 +메인 프로세스는 `ipcMain` 모듈을 통해 `channel` 이벤트를 리스닝 할 수 있고, `event.returnValue`로 회신 할 수 있습니다. __참고:__ 동기 메서드는 모든 랜더러 프로세스의 작업을 일시 중단시킵니다. 사용 목적이 @@ -67,7 +76,7 @@ __참고:__ 동기 메서드는 모든 랜더러 프로세스의 작업을 일 ### `ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])` -* `channel` String - 이벤트 이름 +* `channel` String * `arg` (optional) `ipcRenderer.send`와 비슷하지만 이벤트를 메인 프로세스 대신 호스트 페이지내의 diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 3f9a7daaaa7..6e41f31155c 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -255,8 +255,8 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - 더 많은 응답이 따르는 경우를 표시합니다. - * `matches` Integer (Optional) - 일치하는 개수. - * `selectionArea` Object (Optional) - 첫 일치 부위의 좌표. + * `matches` Integer (optional) - 일치하는 개수. + * `selectionArea` Object (optional) - 첫 일치 부위의 좌표. [`webContents.findInPage`](web-contents.md#webcontentsfindinpage) 요청의 결과를 사용할 수 있을 때 발생하는 이벤트입니다. @@ -307,7 +307,7 @@ Returns: ### `webContents.loadURL(url[, options])` * `url` URL -* `options` Object (optional), 속성들: +* `options` Object (optional) * `httpReferrer` String - HTTP 레퍼러 url. * `userAgent` String - 요청을 시작한 유저 에이전트. * `extraHeaders` String - "\n"로 구분된 Extra 헤더들. @@ -493,7 +493,7 @@ CSS 코드를 현재 웹 페이지에 삽입합니다. ### `webContents.findInPage(text[, options])` * `text` String - 찾을 컨텐츠, 반드시 공백이 아니여야 합니다. -* `options` Object (Optional) +* `options` Object (optional) * `forward` Boolean - 앞에서부터 검색할지 뒤에서부터 검색할지 여부입니다. 기본값은 `true`입니다. * `findNext` Boolean - 작업을 계속 처리할지 첫 요청만 처리할지 여부입니다. 기본값은 @@ -546,11 +546,10 @@ ServiceWorker가 존재하면 모두 등록을 해제하고 JS Promise가 만족 ### `webContents.print([options])` -`options` Object (optional), properties: - -* `silent` Boolean - 사용자에게 프린트 설정을 묻지 않습니다. 기본값을 `false`입니다. -* `printBackground` Boolean - 웹 페이지의 배경 색과 이미지를 출력합니다. 기본값은 - `false`입니다. +`options` Object (optional) + * `silent` Boolean - 사용자에게 프린트 설정을 묻지 않습니다. 기본값을 `false`입니다. + * `printBackground` Boolean - 웹 페이지의 배경 색과 이미지를 출력합니다. 기본값은 + `false`입니다. 윈도우의 웹 페이지를 프린트합니다. `silent`가 `false`로 지정되어있을 땐, Electron이 시스템의 기본 프린터와 기본 프린터 설정을 가져옵니다. @@ -565,32 +564,23 @@ print기능을 사용하지 않는 경우 전체 바이너리 크기를 줄이 ### `webContents.printToPDF(options, callback)` -`options` Object, properties: - -* `marginsType` Integer - 사용할 마진의 종류를 지정합니다. - * 0 - default - * 1 - none - * 2 - minimum -* `pageSize` String - 생성되는 PDF의 페이지 크기를 지정합니다. - * `A5` - * `A4` - * `A3` - * `Legal` - * `Letter` - * `Tabloid` -* `printBackground` Boolean - CSS 배경을 프린트할지 여부를 정합니다. -* `printSelectionOnly` Boolean - 선택된 영역만 프린트할지 여부를 정합니다. -* `landscape` Boolean - landscape을 위해선 `true`를, portrait를 위해선 `false`를 - 사용합니다. - -`callback` Function - `function(error, data) {}` - -* `error` Error -* `data` Buffer - PDF 파일 내용. +* `options` Object + * `marginsType` Integer - 사용할 마진의 종류를 지정합니다. 0 부터 2 사이 값을 사용할 + 수 있고 각각 기본 마진, 마진 없음, 최소 마진입니다. + * `pageSize` String - 생성되는 PDF의 페이지 크기를 지정합니다. 값은 `A3`, `A4`, + `A5`, `Legal`, `Letter` 와 `Tabloid`가 사용될 수 있습니다. + * `printBackground` Boolean - CSS 배경을 프린트할지 여부를 정합니다. + * `printSelectionOnly` Boolean - 선택된 영역만 프린트할지 여부를 정합니다. + * `landscape` Boolean - landscape을 위해선 `true`를, portrait를 위해선 `false`를 + 사용합니다. +* `callback` Function - `function(error, data) {}` Chromium의 미리보기 프린팅 커스텀 설정을 이용하여 윈도우의 웹 페이지를 PDF로 프린트합니다. +`callback`은 작업이 완료되면 `callback(error, data)` 형식으로 호출됩니다. `data`는 +생성된 PDF 데이터를 담고있는 `Buffer`입니다. + 기본으로 비어있는 `options`은 다음과 같이 여겨지게 됩니다: ```javascript @@ -643,7 +633,7 @@ mainWindow.webContents.on('devtools-opened', function() { ### `webContents.openDevTools([options])` -* `options` Object (optional). Properties: +* `options` Object (optional) * `detach` Boolean - 새 창에서 개발자 도구를 엽니다. 개발자 도구를 엽니다. @@ -681,8 +671,11 @@ mainWindow.webContents.on('devtools-opened', function() { * `arg` (optional) `channel`을 통하여 렌더러 프로세스에 비동기 메시지를 보냅니다. 임의의 인수를 보낼수도 -있습니다. 렌더러 프로세스는 `ipcRenderer` 모듈을 통하여 `channel`를 리슨하여 메시지를 -처리할 수 있습니다. +있습니다. 인수들은 내부적으로 JSON 포맷으로 직렬화 되며, 이후 함수와 프로토타입 체인은 +포함되지 않게 됩니다. + +렌더러 프로세스는 `ipcRenderer` 모듈을 통하여 `channel`를 리스닝하여 메시지를 처리할 +수 있습니다. 메인 프로세스에서 렌더러 프로세스로 메시지를 보내는 예시 입니다: diff --git a/docs-translations/ko-KR/api/web-view-tag.md b/docs-translations/ko-KR/api/web-view-tag.md index bd07c883e06..30da9f253b4 100644 --- a/docs-translations/ko-KR/api/web-view-tag.md +++ b/docs-translations/ko-KR/api/web-view-tag.md @@ -178,7 +178,7 @@ webview.addEventListener("dom-ready", function() { ### `.loadURL(url[, options])` * `url` URL -* `options` Object (optional), 속성들: +* `options` Object (optional) * `httpReferrer` String - HTTP 레퍼러 url. * `userAgent` String - 요청을 시작한 유저 에이전트. * `extraHeaders` String - "\n"로 구분된 Extra 헤더들. @@ -370,7 +370,7 @@ Service worker에 대한 개발자 도구를 엽니다. ### `webContents.findInPage(text[, options])` * `text` String - 찾을 컨텐츠, 반드시 공백이 아니여야 합니다. -* `options` Object (Optional) +* `options` Object (optional) * `forward` Boolean - 앞에서부터 검색할지 뒤에서부터 검색할지 여부입니다. 기본값은 `true`입니다. * `findNext` Boolean - 작업을 계속 처리할지 첫 요청만 처리할지 여부입니다. 기본값은 @@ -557,8 +557,8 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - 더 많은 응답이 따르는 경우를 표시합니다. - * `matches` Integer (Optional) - 일치하는 개수. - * `selectionArea` Object (Optional) - 첫 일치 부위의 좌표. + * `matches` Integer (optional) - 일치하는 개수. + * `selectionArea` Object (optional) - 첫 일치 부위의 좌표. [`webContents.findInPage`](web-contents.md#webcontentsfindinpage) 요청의 결과를 사용할 수 있을 때 발생하는 이벤트입니다. diff --git a/docs-translations/ko-KR/faq/electron-faq.md b/docs-translations/ko-KR/faq/electron-faq.md index 0978dc00539..ea9953fcd4c 100644 --- a/docs-translations/ko-KR/faq/electron-faq.md +++ b/docs-translations/ko-KR/faq/electron-faq.md @@ -18,6 +18,34 @@ Node.js의 새로운 기능은 보통 V8 업그레이드에서 가져옵니다. 브라우저에 탑재된 V8을 사용하고 있습니다. 눈부신 새로운 Node.js 버전의 자바스크립트 기능은 보통 이미 Electron에 있습니다. +## 어떻게 웹 페이지 간에 데이터를 공유할 수 있나요? + +두 웹페이지 간에 (랜더러 프로세스) 데이터를 공유하려면 간단히 이미 모든 브라우저에서 +사용할 수 있는 HTML5 API들을 사용하면 됩니다. 가장 좋은 후보는 +[Storage API][storage], [`localStorage`][local-storage], +[`sessionStorage`][session-storage], 그리고 [IndexedDB][indexed-db]가 있습니다. + +또는 Electron에서만 사용할 수 있는 IPC 시스템을 사용하여 메인 프로세스의 global +변수에 데이터를 저장한 후 다음과 같이 랜더러 프로세스에서 `remote` 모듈을 사용하여 +접근할 수 있습니다: + +```javascript +// 메인 프로세스에서 +global.sharedObject = { + someProperty: 'default value' +}; +``` + +```javascript +// 첫 번째 페이지에서 +require('remote').getGlobal('sharedObject').someProperty = 'new value'; +``` + +```javascript +// 두 번째 페이지에서 +console.log(require('remote').getGlobal('sharedObject').someProperty); +``` + ## 제작한 어플리케이션의 윈도우/트레이가 몇 분 후에나 나타납니다. 이러한 문제가 발생하는 이유는 보통 윈도우/트레이를 담은 변수에 가비지 컬렉션이 작동해서 @@ -119,3 +147,7 @@ npm uninstall -g electron [memory-management]: https://developer.mozilla.org/ko/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx [electron-module]: https://www.npmjs.com/package/electron +[storage]: https://developer.mozilla.org/en-US/docs/Web/API/Storage +[local-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage +[session-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage +[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API diff --git a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md index cd6ff545e14..38830b91e82 100644 --- a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md +++ b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md @@ -263,6 +263,33 @@ var window = new BrowserWindow({...}); window.setProgressBar(0.5); ``` +## 작업 표시줄의 아이콘 오버레이 (Windows) + +Windows에선 작업 표시줄 버튼에 어플리케이션의 상태를 표시하는 작은 오버레이를 사용할 +수 있습니다. MSDN에서 인용하자면 (영문): + +> Icon overlays serve as a contextual notification of status, and are intended +> to negate the need for a separate notification area status icon to communicate +> that information to the user. For instance, the new mail status in Microsoft +> Outlook, currently shown in the notification area, can now be indicated +> through an overlay on the taskbar button. Again, you must decide during your +> development cycle which method is best for your application. Overlay icons are +> intended to supply important, long-standing status or notifications such as +> network status, messenger status, or new mail. The user should not be +> presented with constantly changing overlays or animations. + +__작업 표시줄 버튼 위의 오버레이:__ + +![작업 표시줄 버튼 위의 오버레이](https://i-msdn.sec.s-msft.com/dynimg/IC420441.png) + +윈도우에 오버레이 아이콘을 설정하려면 [BrowserWindow.setOverlayIcon][setoverlayicon] +API를 사용할 수 있습니다: + +```javascript +var window = new BrowserWindow({...}); +window.setOverlayIcon('path/to/overlay.png', 'Description for overlay'); +``` + ## 대표 파일 제시 (OS X) OS X는 창에서 대표 파일을 설정할 수 있습니다. 타이틀바에서 파일 아이콘이 있고, 사용자가 @@ -287,6 +314,7 @@ window.setDocumentEdited(true); [clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-os-x-windows [setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows [setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress +[setoverlayicon]: ../api/browser-window.md#winsetoverlayiconoverlay-description-windows-7 [setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-os-x [setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-os-x [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx diff --git a/docs-translations/ko-KR/tutorial/quick-start.md b/docs-translations/ko-KR/tutorial/quick-start.md index 708a48080ff..82d359e0de5 100644 --- a/docs-translations/ko-KR/tutorial/quick-start.md +++ b/docs-translations/ko-KR/tutorial/quick-start.md @@ -12,7 +12,7 @@ Electron은 웹 페이지의 GUI를 사용합니다. 쉽게 말해 Electron은 ### 메인 프로세스 -Electron은 실행될 때 __메인 프로세스__로 불리는 `package.json`의 `main` 스크립트를 +Electron은 실행될 때 __메인 프로세스__ 로 불리는 `package.json`의 `main` 스크립트를 호출합니다. 이 스크립트는 메인 프로세스에서 작동합니다. GUI 컴포넌트를 조작하거나 웹 페이지 창을 생성할 수 있습니다. @@ -43,6 +43,7 @@ API를 사용하여 low-level 수준으로 운영체제와 상호작용할 수 Electron에는 메인 프로세스와 랜더러 프로세스 사이에 통신을 할 수 있도록 [ipc](../api/ipc-renderer.md) 모듈을 제공하고 있습니다. 또는 [remote](../api/remote.md) 모듈을 사용하여 RPC 스타일로 통신할 수도 있습니다. +또한 FAQ에서 [다양한 객체를 공유하는 방법](share-data)도 소개하고 있습니다. ## 첫번째 Electron 앱 만들기 @@ -211,3 +212,5 @@ $ cd electron-quick-start # 어플리케이션의 종속성 모듈을 설치한 후 실행합니다 $ npm install && npm start ``` + +[share-data]: ../faq/electron-faq.md#어떻게-웹-페이지-간에-데이터를-공유할-수-있나요 From ee0cac7d5475549802fadcf0ab67a9a24354eef4 Mon Sep 17 00:00:00 2001 From: Kevin Jose Martin Date: Tue, 16 Feb 2016 21:23:13 -0500 Subject: [PATCH 225/688] Remove command line switches, add v8 flags --- atom/browser/lib/init.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/atom/browser/lib/init.js b/atom/browser/lib/init.js index b687aa6eeda..4769faee0a3 100644 --- a/atom/browser/lib/init.js +++ b/atom/browser/lib/init.js @@ -2,6 +2,7 @@ const fs = require('fs'); const path = require('path'); const util = require('util'); const Module = require('module'); +const v8 = require('v8'); var slice = [].slice; @@ -129,22 +130,14 @@ if (packageJson.desktopName != null) { app.setDesktopName((app.getName()) + ".desktop"); } +// Set v8 flags +if (packageJson.v8Flags != null) { + v8.setFlagsFromString(packageJson.v8Flags); +} + // Chrome 42 disables NPAPI plugins by default, reenable them here app.commandLine.appendSwitch('enable-npapi'); -// Add other command line switches -if (packageJson.commandLineSwitches) { - for (let i = 0; i < packageJson.commandLineSwitches.length; i++) { - const option = packageJson.commandLineSwitches[i]; - - if (typeof option === 'string') { - app.commandLine.appendSwitch(option); - } else { - app.commandLine.appendSwitch(option[0], option[1]); - } - } -} - // Set the user path according to application's name. app.setPath('userData', path.join(app.getPath('appData'), app.getName())); From baf44c7a4144c3c78a9bcf01708f5a580fbcd889 Mon Sep 17 00:00:00 2001 From: deenjun Date: Wed, 17 Feb 2016 10:42:59 +0800 Subject: [PATCH 226/688] tanslate file-object.md --- docs-translations/zh-CN/api/file-object.md | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs-translations/zh-CN/api/file-object.md diff --git a/docs-translations/zh-CN/api/file-object.md b/docs-translations/zh-CN/api/file-object.md new file mode 100644 index 00000000000..343fc4dc53a --- /dev/null +++ b/docs-translations/zh-CN/api/file-object.md @@ -0,0 +1,33 @@ +# `文件`对象 + +为了让用户能够通过HTML5的file API直接操作本地文件,DOM的File接口提供了对本地文件的抽象。Electron在File接口中增加了一个path属性,它是文件在系统中的真实路径。 + +The DOM’s File interface provides abstraction around native files in order to let users work on native files directly with the HTML5 file API. Electron has added a path attribute to the File interface which exposes the file’s real path on filesystem. + +--- + +获取拖动到APP中文件的真实路径的例子: + +Example on getting a real path from a dragged-onto-the-app file: + +``` +
+ Drag your file here +
+ + +``` From 01ede11cb885cc0f77fd23258f37aaaf92c30652 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 17 Feb 2016 10:54:44 +0800 Subject: [PATCH 227/688] Skip eslint on our Windows build machine for now --- script/eslint.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/script/eslint.py b/script/eslint.py index 8fa2c3a7e3a..7b912e0e1d6 100755 --- a/script/eslint.py +++ b/script/eslint.py @@ -4,6 +4,7 @@ import glob import os import sys +from lib.config import PLATFORM from lib.util import execute @@ -13,6 +14,10 @@ SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) def main(): os.chdir(SOURCE_ROOT) + # Skip eslint on our Windows build machine for now. + if PLATFORM == 'win32' and os.getenv('JANKY_SHA1'): + return + eslint = os.path.join(SOURCE_ROOT, 'node_modules', '.bin', 'eslint') if sys.platform in ['win32', 'cygwin']: eslint += '.cmd' From 28635e5f2c20f2d8642965460e9e5eb378cd32df Mon Sep 17 00:00:00 2001 From: deenjun Date: Wed, 17 Feb 2016 14:54:57 +0800 Subject: [PATCH 228/688] remove original English text --- docs-translations/zh-CN/api/file-object.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs-translations/zh-CN/api/file-object.md b/docs-translations/zh-CN/api/file-object.md index 343fc4dc53a..ef320b36994 100644 --- a/docs-translations/zh-CN/api/file-object.md +++ b/docs-translations/zh-CN/api/file-object.md @@ -1,15 +1,11 @@ -# `文件`对象 +# `File`对象 为了让用户能够通过HTML5的file API直接操作本地文件,DOM的File接口提供了对本地文件的抽象。Electron在File接口中增加了一个path属性,它是文件在系统中的真实路径。 -The DOM’s File interface provides abstraction around native files in order to let users work on native files directly with the HTML5 file API. Electron has added a path attribute to the File interface which exposes the file’s real path on filesystem. - --- 获取拖动到APP中文件的真实路径的例子: -Example on getting a real path from a dragged-onto-the-app file: - ```
Drag your file here From 7fece7e9b3ecfa57b5a37e07c2f4eb65169589dd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 17 Feb 2016 22:21:14 +0800 Subject: [PATCH 229/688] Link with ffmpeg --- atom.gyp | 3 +++ vendor/brightray | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/atom.gyp b/atom.gyp index dbaf6db5629..c8c714858b4 100644 --- a/atom.gyp +++ b/atom.gyp @@ -144,6 +144,7 @@ }, { 'copied_libraries': [ '<(libchromiumcontent_dir)/pdf.dll', + '<(libchromiumcontent_dir)/ffmpeg.dll', ], }], ], @@ -193,6 +194,7 @@ }, { 'copied_libraries': [ '<(PRODUCT_DIR)/lib/libnode.so', + '<(libchromiumcontent_dir)/libffmpeg.so', ], }], ], @@ -461,6 +463,7 @@ }, { 'copied_libraries': [ '<(PRODUCT_DIR)/libnode.dylib', + '<(libchromiumcontent_dir)/libffmpeg.dylib', ], }], ], diff --git a/vendor/brightray b/vendor/brightray index 2a5cd7178b6..d06de26dff8 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 2a5cd7178b641de91ca6eb0bca826fea588f923a +Subproject commit d06de26dff8b641d9aee4c78ee830b416710f554 From 3d3fc18a3ab8aa409296b41ed00c8474911ad254 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 17 Feb 2016 22:21:59 +0800 Subject: [PATCH 230/688] Update libchromiumcontent to use shared ffmpeg --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index 279fa7340a9..004e87dd070 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'ad63d8ba890bcaad2f1b7e6de148b7992f4d3af7' +LIBCHROMIUMCONTENT_COMMIT = '1be1a55abba527d6fb0fc2a589cbaef2f5a6a79e' PLATFORM = { 'cygwin': 'win32', From d8679b38993ae66c9e6d60968da19124005d09b6 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Tue, 2 Feb 2016 23:01:00 -0800 Subject: [PATCH 231/688] Allow openExternal to open URLs in the background #3224 --- .../atom_resource_dispatcher_host_delegate.cc | 2 +- atom/common/api/atom_api_shell.cc | 12 +++++++++++- atom/common/platform_util.h | 2 +- atom/common/platform_util_linux.cc | 2 +- atom/common/platform_util_mac.mm | 12 ++++++++++-- atom/common/platform_util_win.cc | 2 +- docs/api/shell.md | 10 ++++++++-- 7 files changed, 33 insertions(+), 9 deletions(-) diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index aaba1f31045..33e90671aba 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -26,7 +26,7 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( bool has_user_gesture) { GURL escaped_url(net::EscapeExternalHandlerValue(url.spec())); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(base::IgnoreResult(platform_util::OpenExternal), escaped_url)); + base::Bind(base::IgnoreResult(platform_util::OpenExternal), escaped_url, false)); return true; } diff --git a/atom/common/api/atom_api_shell.cc b/atom/common/api/atom_api_shell.cc index a4599ee0c35..d479911fbe3 100644 --- a/atom/common/api/atom_api_shell.cc +++ b/atom/common/api/atom_api_shell.cc @@ -12,12 +12,22 @@ namespace { +bool OpenExternal(const GURL& url, mate::Arguments* args) { + bool without_activation = false; + if (args->Length() == 2) { + mate::Dictionary options; + args->GetNext(&options); + options.Get("withoutActivation", &without_activation); + } + return platform_util::OpenExternal(url, without_activation); +} + void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); dict.SetMethod("showItemInFolder", &platform_util::ShowItemInFolder); dict.SetMethod("openItem", &platform_util::OpenItem); - dict.SetMethod("openExternal", &platform_util::OpenExternal); + dict.SetMethod("openExternal", &OpenExternal); dict.SetMethod("moveItemToTrash", &platform_util::MoveItemToTrash); dict.SetMethod("beep", &platform_util::Beep); } diff --git a/atom/common/platform_util.h b/atom/common/platform_util.h index 312942c4f5d..3550c243bb6 100644 --- a/atom/common/platform_util.h +++ b/atom/common/platform_util.h @@ -23,7 +23,7 @@ void OpenItem(const base::FilePath& full_path); // Open the given external protocol URL in the desktop's default manner. // (For example, mailto: URLs in the default mail user agent.) -bool OpenExternal(const GURL& url); +bool OpenExternal(const GURL& url, const bool without_activation); // Move a file to trash. bool MoveItemToTrash(const base::FilePath& full_path); diff --git a/atom/common/platform_util_linux.cc b/atom/common/platform_util_linux.cc index aa7439968da..fd4dcba6973 100644 --- a/atom/common/platform_util_linux.cc +++ b/atom/common/platform_util_linux.cc @@ -64,7 +64,7 @@ void OpenItem(const base::FilePath& full_path) { XDGOpen(full_path.value()); } -bool OpenExternal(const GURL& url) { +bool OpenExternal(const GURL& url, const bool without_activation) { if (url.SchemeIs("mailto")) return XDGEmail(url.spec()); else diff --git a/atom/common/platform_util_mac.mm b/atom/common/platform_util_mac.mm index 7184593ae19..e84b3fbec30 100644 --- a/atom/common/platform_util_mac.mm +++ b/atom/common/platform_util_mac.mm @@ -119,7 +119,7 @@ void OpenItem(const base::FilePath& full_path) { } } -bool OpenExternal(const GURL& url) { +bool OpenExternal(const GURL& url, const bool without_activation) { DCHECK([NSThread isMainThread]); NSURL* ns_url = net::NSURLWithGURL(url); if (!ns_url) { @@ -136,7 +136,15 @@ bool OpenExternal(const GURL& url) { } CFRelease(openingApp); // NOT A BUG; LSGetApplicationForURL retains for us - return [[NSWorkspace sharedWorkspace] openURL:ns_url]; + NSUInteger launchOptions = NSWorkspaceLaunchDefault; + if (without_activation) + launchOptions = launchOptions | NSWorkspaceLaunchWithoutActivation; + + return [[NSWorkspace sharedWorkspace] openURLs: @[ns_url] + withAppBundleIdentifier: nil + options: launchOptions + additionalEventParamDescriptor: NULL + launchIdentifiers: NULL]; } bool MoveItemToTrash(const base::FilePath& full_path) { diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 4de5224668b..76b71cb7f70 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -301,7 +301,7 @@ void OpenItem(const base::FilePath& full_path) { ui::win::OpenFileViaShell(full_path); } -bool OpenExternal(const GURL& url) { +bool OpenExternal(const GURL& url, const bool without_activation) { // Quote the input scheme to be sure that the command does not have // parameters unexpected by the external program. This url should already // have been escaped. diff --git a/docs/api/shell.md b/docs/api/shell.md index e6678a95536..a7f03a52f9c 100644 --- a/docs/api/shell.md +++ b/docs/api/shell.md @@ -26,12 +26,18 @@ Show the given file in a file manager. If possible, select the file. Open the given file in the desktop's default manner. -### `shell.openExternal(url)` +### `shell.openExternal(url[, options])` * `url` String Open the given external protocol URL in the desktop's default manner. (For -example, mailto: URLs in the user's default mail agent.) +example, mailto: URLs in the user's default mail agent.) Returns true if an +application was available to open the URL, false otherwise. + +On Mac OS X, you can pass additional options to openExternal: + +- withoutActivation: Pass true to open the URL without bringing the + application into the foreground. ### `shell.moveItemToTrash(fullPath)` From 52db43eee55975ab1cbd4926beedbd4b037c2a38 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Wed, 3 Feb 2016 11:35:01 -0800 Subject: [PATCH 232/688] Fix linter error --- atom/browser/atom_resource_dispatcher_host_delegate.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index 33e90671aba..0ed59b71be9 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -26,7 +26,8 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( bool has_user_gesture) { GURL escaped_url(net::EscapeExternalHandlerValue(url.spec())); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(base::IgnoreResult(platform_util::OpenExternal), escaped_url, false)); + base::Bind( + base::IgnoreResult(platform_util::OpenExternal), escaped_url, false)); return true; } From f5bed87199732cfac34b4dfe5ddcc6072fd5b549 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 15:55:37 -0800 Subject: [PATCH 233/688] without_activation -> activate --- atom/common/api/atom_api_shell.cc | 12 +----------- atom/common/api/lib/shell.js | 18 +++++++++++++++++- atom/common/platform_util.h | 2 +- atom/common/platform_util_linux.cc | 2 +- atom/common/platform_util_mac.mm | 6 +++--- atom/common/platform_util_win.cc | 2 +- 6 files changed, 24 insertions(+), 18 deletions(-) diff --git a/atom/common/api/atom_api_shell.cc b/atom/common/api/atom_api_shell.cc index d479911fbe3..d0e795e8745 100644 --- a/atom/common/api/atom_api_shell.cc +++ b/atom/common/api/atom_api_shell.cc @@ -12,22 +12,12 @@ namespace { -bool OpenExternal(const GURL& url, mate::Arguments* args) { - bool without_activation = false; - if (args->Length() == 2) { - mate::Dictionary options; - args->GetNext(&options); - options.Get("withoutActivation", &without_activation); - } - return platform_util::OpenExternal(url, without_activation); -} - void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); dict.SetMethod("showItemInFolder", &platform_util::ShowItemInFolder); dict.SetMethod("openItem", &platform_util::OpenItem); - dict.SetMethod("openExternal", &OpenExternal); + dict.SetMethod("_openExternal", &platform_util::OpenExternal); dict.SetMethod("moveItemToTrash", &platform_util::MoveItemToTrash); dict.SetMethod("beep", &platform_util::Beep); } diff --git a/atom/common/api/lib/shell.js b/atom/common/api/lib/shell.js index 08cc4e8eb41..e032a737076 100644 --- a/atom/common/api/lib/shell.js +++ b/atom/common/api/lib/shell.js @@ -1 +1,17 @@ -module.exports = process.atomBinding('shell'); +'use strict'; + +const bindings = process.atomBinding('shell'); + +exports.beep = bindings.beep; +exports.moveItemToTrash = bindings.moveItemToTrash; +exports.openItem = bindings.openItem; +exports.showItemInFolder = bindings.showItemInFolder; + +exports.openExternal = (url, options) => { + var activate = true; + if (options != null && options.activate != null) { + activate = !!options.activate; + } + + bindings._openExternal(url, activate); +} diff --git a/atom/common/platform_util.h b/atom/common/platform_util.h index 3550c243bb6..4565221e9d8 100644 --- a/atom/common/platform_util.h +++ b/atom/common/platform_util.h @@ -23,7 +23,7 @@ void OpenItem(const base::FilePath& full_path); // Open the given external protocol URL in the desktop's default manner. // (For example, mailto: URLs in the default mail user agent.) -bool OpenExternal(const GURL& url, const bool without_activation); +bool OpenExternal(const GURL& url, bool activate); // Move a file to trash. bool MoveItemToTrash(const base::FilePath& full_path); diff --git a/atom/common/platform_util_linux.cc b/atom/common/platform_util_linux.cc index fd4dcba6973..1e437b866cc 100644 --- a/atom/common/platform_util_linux.cc +++ b/atom/common/platform_util_linux.cc @@ -64,7 +64,7 @@ void OpenItem(const base::FilePath& full_path) { XDGOpen(full_path.value()); } -bool OpenExternal(const GURL& url, const bool without_activation) { +bool OpenExternal(const GURL& url, bool activate) { if (url.SchemeIs("mailto")) return XDGEmail(url.spec()); else diff --git a/atom/common/platform_util_mac.mm b/atom/common/platform_util_mac.mm index e84b3fbec30..98bc4e537d8 100644 --- a/atom/common/platform_util_mac.mm +++ b/atom/common/platform_util_mac.mm @@ -119,7 +119,7 @@ void OpenItem(const base::FilePath& full_path) { } } -bool OpenExternal(const GURL& url, const bool without_activation) { +bool OpenExternal(const GURL& url, bool activate) { DCHECK([NSThread isMainThread]); NSURL* ns_url = net::NSURLWithGURL(url); if (!ns_url) { @@ -137,8 +137,8 @@ bool OpenExternal(const GURL& url, const bool without_activation) { CFRelease(openingApp); // NOT A BUG; LSGetApplicationForURL retains for us NSUInteger launchOptions = NSWorkspaceLaunchDefault; - if (without_activation) - launchOptions = launchOptions | NSWorkspaceLaunchWithoutActivation; + if (!activate) + launchOptions |= NSWorkspaceLaunchWithoutActivation; return [[NSWorkspace sharedWorkspace] openURLs: @[ns_url] withAppBundleIdentifier: nil diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 76b71cb7f70..12591a94d56 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -301,7 +301,7 @@ void OpenItem(const base::FilePath& full_path) { ui::win::OpenFileViaShell(full_path); } -bool OpenExternal(const GURL& url, const bool without_activation) { +bool OpenExternal(const GURL& url, bool activate) { // Quote the input scheme to be sure that the command does not have // parameters unexpected by the external program. This url should already // have been escaped. From 42041cd40273851d694bff1da6abd67489cb53e9 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 15:58:33 -0800 Subject: [PATCH 234/688] Use markdown list for new options param --- docs/api/shell.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/api/shell.md b/docs/api/shell.md index a7f03a52f9c..823dc481bb0 100644 --- a/docs/api/shell.md +++ b/docs/api/shell.md @@ -29,16 +29,14 @@ Open the given file in the desktop's default manner. ### `shell.openExternal(url[, options])` * `url` String +* `options` Object (optional) _OS X_ + * `activate` Boolean - `true` to bring the opened application to the + foreground. The default is `true`. Open the given external protocol URL in the desktop's default manner. (For example, mailto: URLs in the user's default mail agent.) Returns true if an application was available to open the URL, false otherwise. -On Mac OS X, you can pass additional options to openExternal: - -- withoutActivation: Pass true to open the URL without bringing the - application into the foreground. - ### `shell.moveItemToTrash(fullPath)` * `fullPath` String From 5e5313d8b1659f9fbdee5ff3cf6198c696928005 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 16:02:41 -0800 Subject: [PATCH 235/688] Return value from bindings method --- atom/common/api/lib/shell.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/common/api/lib/shell.js b/atom/common/api/lib/shell.js index e032a737076..7caf8518395 100644 --- a/atom/common/api/lib/shell.js +++ b/atom/common/api/lib/shell.js @@ -13,5 +13,5 @@ exports.openExternal = (url, options) => { activate = !!options.activate; } - bindings._openExternal(url, activate); + return bindings._openExternal(url, activate); } From 04517caf36265055505c6dbec085c34aa0e14b33 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 16:08:36 -0800 Subject: [PATCH 236/688] Add missing semicolon --- atom/common/api/lib/shell.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/common/api/lib/shell.js b/atom/common/api/lib/shell.js index 7caf8518395..d62280277c5 100644 --- a/atom/common/api/lib/shell.js +++ b/atom/common/api/lib/shell.js @@ -14,4 +14,4 @@ exports.openExternal = (url, options) => { } return bindings._openExternal(url, activate); -} +}; From 3f42909ecfe46fc786cb7e9eb662bb7f6e255154 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 16:09:30 -0800 Subject: [PATCH 237/688] Call OpenExternal with new true default to activate arg --- atom/browser/atom_resource_dispatcher_host_delegate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index 0ed59b71be9..4d969786c19 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -27,7 +27,7 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( GURL escaped_url(net::EscapeExternalHandlerValue(url.spec())); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( - base::IgnoreResult(platform_util::OpenExternal), escaped_url, false)); + base::IgnoreResult(platform_util::OpenExternal), escaped_url, true)); return true; } From b3ac48cf52f0b36831fb8366fc16ecf2be287cf8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 09:05:21 -0800 Subject: [PATCH 238/688] Handle argument parsing in C++ --- atom/common/api/atom_api_shell.cc | 13 ++++++++++++- atom/common/api/lib/shell.js | 18 +----------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/atom/common/api/atom_api_shell.cc b/atom/common/api/atom_api_shell.cc index d0e795e8745..f99e2ba1854 100644 --- a/atom/common/api/atom_api_shell.cc +++ b/atom/common/api/atom_api_shell.cc @@ -12,12 +12,23 @@ namespace { +bool OpenExternal(const GURL& url, mate::Arguments* args) { + bool activate = true; + if (args->Length() == 2) { + mate::Dictionary options; + if (args->GetNext(&options)) { + options.Get("activate", &activate); + } + } + return platform_util::OpenExternal(url, activate); +} + void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); dict.SetMethod("showItemInFolder", &platform_util::ShowItemInFolder); dict.SetMethod("openItem", &platform_util::OpenItem); - dict.SetMethod("_openExternal", &platform_util::OpenExternal); + dict.SetMethod("openExternal", &OpenExternal); dict.SetMethod("moveItemToTrash", &platform_util::MoveItemToTrash); dict.SetMethod("beep", &platform_util::Beep); } diff --git a/atom/common/api/lib/shell.js b/atom/common/api/lib/shell.js index d62280277c5..08cc4e8eb41 100644 --- a/atom/common/api/lib/shell.js +++ b/atom/common/api/lib/shell.js @@ -1,17 +1 @@ -'use strict'; - -const bindings = process.atomBinding('shell'); - -exports.beep = bindings.beep; -exports.moveItemToTrash = bindings.moveItemToTrash; -exports.openItem = bindings.openItem; -exports.showItemInFolder = bindings.showItemInFolder; - -exports.openExternal = (url, options) => { - var activate = true; - if (options != null && options.activate != null) { - activate = !!options.activate; - } - - return bindings._openExternal(url, activate); -}; +module.exports = process.atomBinding('shell'); From 709661156a0d9bb4b96bbcb98687912af6f6aa83 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 16:46:49 -0800 Subject: [PATCH 239/688] Use const for requires --- spec/api-app-spec.js | 16 ++++++---------- spec/api-clipboard-spec.js | 10 ++++------ spec/api-crash-reporter-spec.js | 27 +++++++++++---------------- spec/api-debugger-spec.js | 12 +++--------- spec/api-ipc-spec.js | 15 +++++++-------- spec/api-menu-spec.js | 10 +++++----- spec/api-screen-spec.js | 7 ++----- spec/api-web-frame-spec.js | 10 +++------- 8 files changed, 41 insertions(+), 66 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 0019ec59d5f..176a94a0437 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -1,14 +1,10 @@ -var BrowserWindow, ChildProcess, app, assert, path, ref, remote; +const assert = require('assert'); +const ChildProcess = require('child_process'); +const path = require('path'); +const remote = require('electron').remote; -assert = require('assert'); - -ChildProcess = require('child_process'); - -path = require('path'); - -remote = require('electron').remote; - -ref = remote.require('electron'), app = ref.app, BrowserWindow = ref.BrowserWindow; +const app = remote.require('electron').app; +const BrowserWindow = remote.require('electron').BrowserWindow; describe('electron module', function() { it ('can prevent exposing internal modules to require', function(done) { diff --git a/spec/api-clipboard-spec.js b/spec/api-clipboard-spec.js index fe94e330d41..48ba558dfd0 100644 --- a/spec/api-clipboard-spec.js +++ b/spec/api-clipboard-spec.js @@ -1,10 +1,8 @@ -var assert, clipboard, nativeImage, path, ref; +const assert = require('assert'); +const path = require('path'); -assert = require('assert'); - -path = require('path'); - -ref = require('electron'), clipboard = ref.clipboard, nativeImage = ref.nativeImage; +const clipboard = require('electron').clipboard; +const nativeImage = require('electron').nativeImage; describe('clipboard module', function() { var fixtures; diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index b3c4c311589..dac1307a8e8 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -1,18 +1,13 @@ -var BrowserWindow, app, assert, crashReporter, http, multiparty, path, ref, remote, url; +const assert = require('assert'); +const http = require('http'); +const multiparty = require('multiparty'); +const path = require('path'); +const url = require('url'); -assert = require('assert'); - -path = require('path'); - -http = require('http'); - -url = require('url'); - -multiparty = require('multiparty'); - -remote = require('electron').remote; - -ref = remote.require('electron'), app = ref.app, crashReporter = ref.crashReporter, BrowserWindow = ref.BrowserWindow; +const remote = require('electron').remote; +const app = remote.require('electron').app; +const crashReporter = remote.require('electron').crashReporter; +const BrowserWindow = remote.require('electron').BrowserWindow; describe('crash-reporter module', function() { var fixtures, isCI, w; @@ -63,7 +58,7 @@ describe('crash-reporter module', function() { return server.listen(port, '127.0.0.1', function() { port = server.address().port; remote.process.port = port; - url = url.format({ + const crashUrl = url.format({ protocol: 'file', pathname: path.join(fixtures, 'api', 'crash.html'), search: "?port=" + port @@ -74,7 +69,7 @@ describe('crash-reporter module', function() { submitURL: "http://127.0.0.1:" + port }); } - return w.loadURL(url); + return w.loadURL(crashUrl); }); }); return describe(".start(options)", function() { diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index 7a16ca7263c..3c69d38ed32 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -1,12 +1,6 @@ -var assert, path, remote, BrowserWindow; - -assert = require('assert'); - -path = require('path'); - -remote = require('electron').remote; - -BrowserWindow = remote.BrowserWindow; +const assert = require('assert'); +const path = require('path'); +const BrowserWindow = require('electron').remote.BrowserWindow; describe('debugger module', function() { var fixtures, w; diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 66f392a577c..ce5641b71cb 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -1,14 +1,13 @@ -var BrowserWindow, assert, comparePaths, ipcMain, ipcRenderer, path, ref, ref1, remote; +const assert = require('assert'); +const path = require('path'); -assert = require('assert'); +const ipcRenderer = require('electron').ipcRenderer; +const remote = require('electron').remote; -path = require('path'); +const ipcMain = remote.require('electron').ipcMain; +const BrowserWindow = remote.require('electron').BrowserWindow; -ref = require('electron'), ipcRenderer = ref.ipcRenderer, remote = ref.remote; - -ref1 = remote.require('electron'), ipcMain = ref1.ipcMain, BrowserWindow = ref1.BrowserWindow; - -comparePaths = function(path1, path2) { +const comparePaths = function(path1, path2) { if (process.platform === 'win32') { path1 = path1.toLowerCase(); path2 = path2.toLowerCase(); diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index 5771358337e..67705d22b3d 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -1,10 +1,10 @@ -var Menu, MenuItem, assert, ipcRenderer, ref, ref1, remote; +const assert = require('assert'); -assert = require('assert'); +const remote = require('electron').remote; +const ipcRenderer = require('electron').ipcRenderer; -ref = require('electron'), remote = ref.remote, ipcRenderer = ref.ipcRenderer; - -ref1 = remote.require('electron'), Menu = ref1.Menu, MenuItem = ref1.MenuItem; +const Menu = remote.require('electron').Menu; +const MenuItem = remote.require('electron').MenuItem; describe('menu module', function() { describe('Menu.buildFromTemplate', function() { diff --git a/spec/api-screen-spec.js b/spec/api-screen-spec.js index b393d4b99ee..abc12784165 100644 --- a/spec/api-screen-spec.js +++ b/spec/api-screen-spec.js @@ -1,8 +1,5 @@ -var assert, screen; - -assert = require('assert'); - -screen = require('electron').screen; +const assert = require('assert'); +const screen = require('electron').screen; describe('screen module', function() { describe('screen.getCursorScreenPoint()', function() { diff --git a/spec/api-web-frame-spec.js b/spec/api-web-frame-spec.js index 3d287a6acba..d3d43986ec8 100644 --- a/spec/api-web-frame-spec.js +++ b/spec/api-web-frame-spec.js @@ -1,10 +1,6 @@ -var assert, path, webFrame; - -assert = require('assert'); - -path = require('path'); - -webFrame = require('electron').webFrame; +const assert = require('assert'); +const path = require('path'); +const webFrame = require('electron').webFrame; describe('webFrame module', function() { var fixtures; From e63c3c727a2d42a266b3a020d882a9b0c3a0bf83 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 17:09:41 -0800 Subject: [PATCH 240/688] Add newlines between describe/it blocks --- spec/api-app-spec.js | 18 ++- spec/api-clipboard-spec.js | 8 +- spec/api-crash-reporter-spec.js | 21 ++- spec/api-debugger-spec.js | 7 +- spec/api-ipc-spec.js | 63 ++++---- spec/api-menu-spec.js | 48 +++--- spec/api-protocol-spec.js | 160 ++++++++++--------- spec/api-screen-spec.js | 7 +- spec/api-session-spec.js | 16 +- spec/api-web-frame-spec.js | 6 +- spec/api-web-request-spec.js | 36 ++++- spec/asar-spec.js | 271 ++++++++++++++++++-------------- spec/chromium-spec.js | 59 +++++-- spec/modules-spec.js | 7 +- spec/node-spec.js | 23 ++- 15 files changed, 455 insertions(+), 295 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 176a94a0437..ea305ae9535 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -27,6 +27,7 @@ describe('app module', function() { return assert.equal(app.getVersion(), '0.1.0'); }); }); + describe('app.setVersion(version)', function() { return it('overrides the version', function() { assert.equal(app.getVersion(), '0.1.0'); @@ -35,11 +36,13 @@ describe('app module', function() { return app.setVersion('0.1.0'); }); }); + describe('app.getName()', function() { return it('returns the name field of package.json', function() { return assert.equal(app.getName(), 'Electron Test'); }); }); + describe('app.setName(name)', function() { return it('overrides the name', function() { assert.equal(app.getName(), 'Electron Test'); @@ -48,17 +51,20 @@ describe('app module', function() { return app.setName('Electron Test'); }); }); + describe('app.getLocale()', function() { return it('should not be empty', function() { return assert.notEqual(app.getLocale(), ''); }); }); + describe('app.exit(exitCode)', function() { - var appProcess; - appProcess = null; + var appProcess = null; + afterEach(function() { return appProcess != null ? appProcess.kill() : void 0; }); + return it('emits a process exit event with the code', function(done) { var appPath, electronPath, output; appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app'); @@ -77,15 +83,17 @@ describe('app module', function() { }); }); }); + return describe('BrowserWindow events', function() { - var w; - w = null; + var w = null; + afterEach(function() { if (w != null) { w.destroy(); } return w = null; }); + it('should emit browser-window-focus event when window is focused', function(done) { app.once('browser-window-focus', function(e, window) { assert.equal(w.id, window.id); @@ -96,6 +104,7 @@ describe('app module', function() { }); return w.emit('focus'); }); + it('should emit browser-window-blur event when window is blured', function(done) { app.once('browser-window-blur', function(e, window) { assert.equal(w.id, window.id); @@ -106,6 +115,7 @@ describe('app module', function() { }); return w.emit('blur'); }); + return it('should emit browser-window-created event when window is created', function(done) { app.once('browser-window-created', function(e, window) { return setImmediate(function() { diff --git a/spec/api-clipboard-spec.js b/spec/api-clipboard-spec.js index 48ba558dfd0..28afb4a5307 100644 --- a/spec/api-clipboard-spec.js +++ b/spec/api-clipboard-spec.js @@ -5,8 +5,8 @@ const clipboard = require('electron').clipboard; const nativeImage = require('electron').nativeImage; describe('clipboard module', function() { - var fixtures; - fixtures = path.resolve(__dirname, 'fixtures'); + var fixtures = path.resolve(__dirname, 'fixtures'); + describe('clipboard.readImage()', function() { return it('returns NativeImage intance', function() { var i, p; @@ -16,6 +16,7 @@ describe('clipboard module', function() { return assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); }); }); + describe('clipboard.readText()', function() { return it('returns unicode string correctly', function() { var text; @@ -24,6 +25,7 @@ describe('clipboard module', function() { return assert.equal(clipboard.readText(), text); }); }); + describe('clipboard.readHtml()', function() { return it('returns markup correctly', function() { var markup, text; @@ -33,6 +35,7 @@ describe('clipboard module', function() { return assert.equal(clipboard.readHtml(), markup); }); }); + describe('clipboard.readRtf', function() { return it('returns rtf text correctly', function() { var rtf = "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}"; @@ -40,6 +43,7 @@ describe('clipboard module', function() { return assert.equal(clipboard.readRtf(), rtf); }); }); + return describe('clipboard.write()', function() { return it('returns data correctly', function() { var i, markup, p, text, rtf; diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index dac1307a8e8..72662aa3d93 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -10,29 +10,33 @@ const crashReporter = remote.require('electron').crashReporter; const BrowserWindow = remote.require('electron').BrowserWindow; describe('crash-reporter module', function() { - var fixtures, isCI, w; - fixtures = path.resolve(__dirname, 'fixtures'); - w = null; + var fixtures = path.resolve(__dirname, 'fixtures'); + var w = null; + beforeEach(function() { return w = new BrowserWindow({ show: false }); }); + afterEach(function() { return w.destroy(); }); + if (process.mas) { return; } - isCI = remote.getGlobal('isCi'); + + var isCI = remote.getGlobal('isCi'); if (isCI) { return; } + it('should send minidump when renderer crashes', function(done) { - var called, port, server; this.timeout(120000); - called = false; - server = http.createServer(function(req, res) { + + var called = false; + var server = http.createServer(function(req, res) { var form; server.close(); form = new multiparty.Form(); @@ -54,7 +58,7 @@ describe('crash-reporter module', function() { return done(); }); }); - port = remote.process.port; + var port = remote.process.port; return server.listen(port, '127.0.0.1', function() { port = server.address().port; remote.process.port = port; @@ -72,6 +76,7 @@ describe('crash-reporter module', function() { return w.loadURL(crashUrl); }); }); + return describe(".start(options)", function() { return it('requires that the companyName and submitURL options be specified', function() { assert.throws(function() { diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index 3c69d38ed32..714d5fda48c 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -3,9 +3,9 @@ const path = require('path'); const BrowserWindow = require('electron').remote.BrowserWindow; describe('debugger module', function() { - var fixtures, w; - fixtures = path.resolve(__dirname, 'fixtures'); - w = null; + var fixtures = path.resolve(__dirname, 'fixtures'); + var w = null; + beforeEach(function() { if (w != null) { w.destroy(); @@ -16,6 +16,7 @@ describe('debugger module', function() { height: 400 }); }); + afterEach(function() { if (w != null) { w.destroy(); diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index ce5641b71cb..6b1c99779b2 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -16,8 +16,8 @@ const comparePaths = function(path1, path2) { }; describe('ipc module', function() { - var fixtures; - fixtures = path.join(__dirname, 'fixtures'); + var fixtures = path.join(__dirname, 'fixtures'); + describe('remote.require', function() { it('should returns same object for the same module', function() { var dialog1, dialog2; @@ -25,36 +25,39 @@ describe('ipc module', function() { dialog2 = remote.require('electron'); return assert.equal(dialog1, dialog2); }); + it('should work when object contains id property', function() { var a; a = remote.require(path.join(fixtures, 'module', 'id.js')); return assert.equal(a.id, 1127); }); + return it('should search module from the user app', function() { comparePaths(path.normalize(remote.process.mainModule.filename), path.resolve(__dirname, 'static', 'main.js')); return comparePaths(path.normalize(remote.process.mainModule.paths[0]), path.resolve(__dirname, 'static', 'node_modules')); }); }); + describe('remote.createFunctionWithReturnValue', function() { return it('should be called in browser synchronously', function() { - var buf, call, result; - buf = new Buffer('test'); - call = remote.require(path.join(fixtures, 'module', 'call.js')); - result = call.call(remote.createFunctionWithReturnValue(buf)); + var buf = new Buffer('test'); + var call = remote.require(path.join(fixtures, 'module', 'call.js')); + var result = call.call(remote.createFunctionWithReturnValue(buf)); return assert.equal(result.constructor.name, 'Buffer'); }); }); + describe('remote object in renderer', function() { it('can change its properties', function() { - var property, property2; - property = remote.require(path.join(fixtures, 'module', 'property.js')); + var property = remote.require(path.join(fixtures, 'module', 'property.js')); assert.equal(property.property, 1127); property.property = 1007; assert.equal(property.property, 1007); - property2 = remote.require(path.join(fixtures, 'module', 'property.js')); + var property2 = remote.require(path.join(fixtures, 'module', 'property.js')); assert.equal(property2.property, 1007); return property.property = 1127; }); + return it('can construct an object from its member', function() { var call, obj; call = remote.require(path.join(fixtures, 'module', 'call.js')); @@ -62,37 +65,37 @@ describe('ipc module', function() { return assert.equal(obj.test, 'test'); }); }); + describe('remote value in browser', function() { - var print; - print = path.join(fixtures, 'module', 'print_name.js'); + var print = path.join(fixtures, 'module', 'print_name.js'); + it('keeps its constructor name for objects', function() { - var buf, print_name; - buf = new Buffer('test'); - print_name = remote.require(print); + var buf = new Buffer('test'); + var print_name = remote.require(print); return assert.equal(print_name.print(buf), 'Buffer'); }); + return it('supports instanceof Date', function() { - var now, print_name; - now = new Date(); - print_name = remote.require(print); + var now = new Date(); + var print_name = remote.require(print); assert.equal(print_name.print(now), 'Date'); return assert.deepEqual(print_name.echo(now), now); }); }); + describe('remote promise', function() { return it('can be used as promise in each side', function(done) { - var promise; - promise = remote.require(path.join(fixtures, 'module', 'promise.js')); + var promise = remote.require(path.join(fixtures, 'module', 'promise.js')); return promise.twicePromise(Promise.resolve(1234)).then(function(value) { assert.equal(value, 2468); return done(); }); }); }); + describe('ipc.sender.send', function() { return it('should work when sending an object containing id property', function(done) { - var obj; - obj = { + var obj = { id: 1, name: 'ly' }; @@ -103,16 +106,17 @@ describe('ipc module', function() { return ipcRenderer.send('message', obj); }); }); + describe('ipc.sendSync', function() { it('can be replied by setting event.returnValue', function() { - var msg; - msg = ipcRenderer.sendSync('echo', 'test'); + var msg = ipcRenderer.sendSync('echo', 'test'); return assert.equal(msg, 'test'); }); + return it('does not crash when reply is not sent and browser is destroyed', function(done) { - var w; this.timeout(10000); - w = new BrowserWindow({ + + var w = new BrowserWindow({ show: false }); ipcMain.once('send-sync-message', function(event) { @@ -123,18 +127,19 @@ describe('ipc module', function() { return w.loadURL('file://' + path.join(fixtures, 'api', 'send-sync-message.html')); }); }); + return describe('remote listeners', function() { - var w; - w = null; + var w = null; + afterEach(function() { return w.destroy(); }); + return it('can be added and removed correctly', function() { - var listener; w = new BrowserWindow({ show: false }); - listener = function() {}; + var listener = function() {}; w.on('test', listener); assert.equal(w.listenerCount('test'), 1); w.removeListener('test', listener); diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index 67705d22b3d..292a65a0f08 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -9,8 +9,7 @@ const MenuItem = remote.require('electron').MenuItem; describe('menu module', function() { describe('Menu.buildFromTemplate', function() { it('should be able to attach extra fields', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: 'text', extra: 'field' @@ -18,9 +17,9 @@ describe('menu module', function() { ]); return assert.equal(menu.items[0].extra, 'field'); }); + it('does not modify the specified template', function() { - var template; - template = ipcRenderer.sendSync('eval', "var template = [{label: 'text', submenu: [{label: 'sub'}]}];\nrequire('electron').Menu.buildFromTemplate(template);\ntemplate;"); + var template = ipcRenderer.sendSync('eval', "var template = [{label: 'text', submenu: [{label: 'sub'}]}];\nrequire('electron').Menu.buildFromTemplate(template);\ntemplate;"); return assert.deepStrictEqual(template, [ { label: 'text', @@ -32,10 +31,10 @@ describe('menu module', function() { } ]); }); + return describe('Menu.buildFromTemplate should reorder based on item position specifiers', function() { it('should position before existing item', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: '2', id: '2' @@ -52,9 +51,9 @@ describe('menu module', function() { assert.equal(menu.items[1].label, '2'); return assert.equal(menu.items[2].label, '3'); }); + it('should position after existing item', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: '1', id: '1' @@ -71,9 +70,9 @@ describe('menu module', function() { assert.equal(menu.items[1].label, '2'); return assert.equal(menu.items[2].label, '3'); }); + it('should position at endof existing separator groups', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { type: 'separator', id: 'numbers' @@ -115,9 +114,9 @@ describe('menu module', function() { assert.equal(menu.items[6].label, 'b'); return assert.equal(menu.items[7].label, 'c'); }); + it('should create separator group if endof does not reference existing separator group', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: 'a', id: 'a', @@ -153,9 +152,9 @@ describe('menu module', function() { assert.equal(menu.items[6].label, '2'); return assert.equal(menu.items[7].label, '3'); }); + return it('should continue inserting items at next index when no specifier is present', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: '4', id: '4' @@ -182,10 +181,10 @@ describe('menu module', function() { }); }); }); + describe('Menu.insert', function() { return it('should store item in @items by its index', function() { - var item, menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: '1' }, { @@ -194,7 +193,7 @@ describe('menu module', function() { label: '3' } ]); - item = new MenuItem({ + var item = new MenuItem({ label: 'inserted' }); menu.insert(1, item); @@ -204,10 +203,10 @@ describe('menu module', function() { return assert.equal(menu.items[3].label, '3'); }); }); + describe('MenuItem.click', function() { return it('should be called with the item object passed', function(done) { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: 'text', click: function(item) { @@ -220,10 +219,10 @@ describe('menu module', function() { return menu.delegate.executeCommand(menu.items[0].commandId); }); }); + return describe('MenuItem with checked property', function() { it('clicking an checkbox item should flip the checked property', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: 'text', type: 'checkbox' @@ -233,9 +232,9 @@ describe('menu module', function() { menu.delegate.executeCommand(menu.items[0].commandId); return assert.equal(menu.items[0].checked, true); }); + it('clicking an radio item should always make checked property true', function() { - var menu; - menu = Menu.buildFromTemplate([ + var menu = Menu.buildFromTemplate([ { label: 'text', type: 'radio' @@ -246,6 +245,7 @@ describe('menu module', function() { menu.delegate.executeCommand(menu.items[0].commandId); return assert.equal(menu.items[0].checked, true); }); + it('at least have one item checked in each group', function() { var i, j, k, menu, template; template = []; @@ -269,6 +269,7 @@ describe('menu module', function() { assert.equal(menu.items[0].checked, true); return assert.equal(menu.items[12].checked, true); }); + it('should assign groupId automatically', function() { var groupId, i, j, k, l, m, menu, results, template; template = []; @@ -298,6 +299,7 @@ describe('menu module', function() { } return results; }); + return it("setting 'checked' should flip other items' 'checked' property", function() { var i, j, k, l, m, menu, n, o, p, q, results, template; template = []; diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 284033b967d..6426e3312ec 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -6,13 +6,13 @@ const remote = require('electron').remote; const protocol = remote.require('electron').protocol; describe('protocol module', function() { - var postData, protocolName, text; - protocolName = 'sp'; - text = 'valar morghulis'; - postData = { + var protocolName = 'sp'; + var text = 'valar morghulis'; + var postData = { name: 'post test', type: 'string' }; + afterEach(function(done) { return protocol.unregisterProtocol(protocolName, function() { return protocol.uninterceptProtocol('http', function() { @@ -20,11 +20,12 @@ describe('protocol module', function() { }); }); }); + describe('protocol.register(Any)Protocol', function() { - var emptyHandler; - emptyHandler = function(request, callback) { + var emptyHandler = function(request, callback) { return callback(); }; + it('throws error when scheme is already registered', function(done) { return protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { assert.equal(error, null); @@ -34,9 +35,9 @@ describe('protocol module', function() { }); }); }); + it('does not crash when handler is called twice', function(done) { - var doubleHandler; - doubleHandler = function(request, callback) { + var doubleHandler = function(request, callback) { try { callback(text); return callback(); @@ -60,6 +61,7 @@ describe('protocol module', function() { }); }); }); + it('sends error when callback is called with nothing', function(done) { return protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { if (error) { @@ -77,9 +79,9 @@ describe('protocol module', function() { }); }); }); + return it('does not crash when callback is called in next tick', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return setImmediate(function() { return callback(text); }); @@ -101,6 +103,7 @@ describe('protocol module', function() { }); }); }); + describe('protocol.unregisterProtocol', function() { return it('returns error when scheme does not exist', function(done) { return protocol.unregisterProtocol('not-exist', function(error) { @@ -109,10 +112,10 @@ describe('protocol module', function() { }); }); }); + describe('protocol.registerStringProtocol', function() { it('sends string as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(text); }; return protocol.registerStringProtocol(protocolName, handler, function(error) { @@ -131,9 +134,9 @@ describe('protocol module', function() { }); }); }); + it('sets Access-Control-Allow-Origin', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(text); }; return protocol.registerStringProtocol(protocolName, handler, function(error) { @@ -153,9 +156,9 @@ describe('protocol module', function() { }); }); }); + it('sends object as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback({ data: text, mimeType: 'text/html' @@ -177,9 +180,9 @@ describe('protocol module', function() { }); }); }); + return it('fails when sending object other than string', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(new Date); }; return protocol.registerBufferProtocol(protocolName, handler, function(error) { @@ -199,12 +202,12 @@ describe('protocol module', function() { }); }); }); + describe('protocol.registerBufferProtocol', function() { - var buffer; - buffer = new Buffer(text); + var buffer = new Buffer(text); + it('sends Buffer as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(buffer); }; return protocol.registerBufferProtocol(protocolName, handler, function(error) { @@ -223,11 +226,12 @@ describe('protocol module', function() { }); }); }); + it('sets Access-Control-Allow-Origin', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(buffer); }; + return protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); @@ -245,9 +249,9 @@ describe('protocol module', function() { }); }); }); + it('sends object as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback({ data: buffer, mimeType: 'text/html' @@ -269,9 +273,9 @@ describe('protocol module', function() { }); }); }); + return it('fails when sending string', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(text); }; return protocol.registerBufferProtocol(protocolName, handler, function(error) { @@ -291,15 +295,15 @@ describe('protocol module', function() { }); }); }); + describe('protocol.registerFileProtocol', function() { - var fileContent, filePath, normalContent, normalPath; - filePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'file1'); - fileContent = require('fs').readFileSync(filePath); - normalPath = path.join(__dirname, 'fixtures', 'pages', 'a.html'); - normalContent = require('fs').readFileSync(normalPath); + var filePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'file1'); + var fileContent = require('fs').readFileSync(filePath); + var normalPath = path.join(__dirname, 'fixtures', 'pages', 'a.html'); + var normalContent = require('fs').readFileSync(normalPath); + it('sends file path as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(filePath); }; return protocol.registerFileProtocol(protocolName, handler, function(error) { @@ -318,9 +322,9 @@ describe('protocol module', function() { }); }); }); + it('sets Access-Control-Allow-Origin', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(filePath); }; return protocol.registerFileProtocol(protocolName, handler, function(error) { @@ -363,11 +367,12 @@ describe('protocol module', function() { }); }); }); + it('can send normal file', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(normalPath); }; + return protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { return done(error); @@ -384,10 +389,10 @@ describe('protocol module', function() { }); }); }); + it('fails when sending unexist-file', function(done) { - var fakeFilePath, handler; - fakeFilePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'not-exist'); - handler = function(request, callback) { + var fakeFilePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'not-exist'); + var handler = function(request, callback) { return callback(fakeFilePath); }; return protocol.registerBufferProtocol(protocolName, handler, function(error) { @@ -406,9 +411,9 @@ describe('protocol module', function() { }); }); }); + return it('fails when sending unsupported content', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(new Date); }; return protocol.registerBufferProtocol(protocolName, handler, function(error) { @@ -428,10 +433,10 @@ describe('protocol module', function() { }); }); }); + describe('protocol.registerHttpProtocol', function() { it('sends url as response', function(done) { - var server; - server = http.createServer(function(req, res) { + var server = http.createServer(function(req, res) { assert.notEqual(req.headers.accept, ''); res.end(text); return server.close(); @@ -462,9 +467,9 @@ describe('protocol module', function() { }); }); }); + it('fails when sending invalid url', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback({ url: 'url' }); @@ -485,9 +490,9 @@ describe('protocol module', function() { }); }); }); + return it('fails when sending unsupported content', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(new Date); }; return protocol.registerHttpProtocol(protocolName, handler, function(error) { @@ -507,6 +512,7 @@ describe('protocol module', function() { }); }); }); + describe('protocol.isProtocolHandled', function() { it('returns true for file:', function(done) { return protocol.isProtocolHandled('file', function(result) { @@ -514,27 +520,30 @@ describe('protocol module', function() { return done(); }); }); + it('returns true for http:', function(done) { return protocol.isProtocolHandled('http', function(result) { assert.equal(result, true); return done(); }); }); + it('returns true for https:', function(done) { return protocol.isProtocolHandled('https', function(result) { assert.equal(result, true); return done(); }); }); + it('returns false when scheme is not registred', function(done) { return protocol.isProtocolHandled('no-exist', function(result) { assert.equal(result, false); return done(); }); }); + it('returns true for custom protocol', function(done) { - var emptyHandler; - emptyHandler = function(request, callback) { + var emptyHandler = function(request, callback) { return callback(); }; return protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { @@ -545,9 +554,9 @@ describe('protocol module', function() { }); }); }); + return it('returns true for intercepted protocol', function(done) { - var emptyHandler; - emptyHandler = function(request, callback) { + var emptyHandler = function(request, callback) { return callback(); }; return protocol.interceptStringProtocol('http', emptyHandler, function(error) { @@ -559,11 +568,12 @@ describe('protocol module', function() { }); }); }); + describe('protocol.intercept(Any)Protocol', function() { - var emptyHandler; - emptyHandler = function(request, callback) { + var emptyHandler = function(request, callback) { return callback(); }; + it('throws error when scheme is already intercepted', function(done) { return protocol.interceptStringProtocol('http', emptyHandler, function(error) { assert.equal(error, null); @@ -573,9 +583,9 @@ describe('protocol module', function() { }); }); }); + it('does not crash when handler is called twice', function(done) { - var doubleHandler; - doubleHandler = function(request, callback) { + var doubleHandler = function(request, callback) { try { callback(text); return callback(); @@ -599,6 +609,7 @@ describe('protocol module', function() { }); }); }); + return it('sends error when callback is called with nothing', function(done) { if (process.env.TRAVIS === 'true') { return done(); @@ -620,10 +631,10 @@ describe('protocol module', function() { }); }); }); + describe('protocol.interceptStringProtocol', function() { it('can intercept http protocol', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(text); }; return protocol.interceptStringProtocol('http', handler, function(error) { @@ -642,9 +653,9 @@ describe('protocol module', function() { }); }); }); + it('can set content-type', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback({ mimeType: 'application/json', data: '{"value": 1}' @@ -667,9 +678,9 @@ describe('protocol module', function() { }); }); }); + return it('can receive post data', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { var uploadData; uploadData = request.uploadData[0].bytes.toString(); return callback({ @@ -695,10 +706,10 @@ describe('protocol module', function() { }); }); }); + describe('protocol.interceptBufferProtocol', function() { it('can intercept http protocol', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback(new Buffer(text)); }; return protocol.interceptBufferProtocol('http', handler, function(error) { @@ -717,9 +728,9 @@ describe('protocol module', function() { }); }); }); + return it('can receive post data', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { var uploadData; uploadData = request.uploadData[0].bytes; return callback(uploadData); @@ -743,10 +754,10 @@ describe('protocol module', function() { }); }); }); + describe('protocol.interceptHttpProtocol', function() { return it('can send POST request', function(done) { - var server; - server = http.createServer(function(req, res) { + var server = http.createServer(function(req, res) { var body; body = ''; req.on('data', function(chunk) { @@ -758,10 +769,9 @@ describe('protocol module', function() { return server.close(); }); return server.listen(0, '127.0.0.1', function() { - var handler, port, url; - port = server.address().port; - url = "http://127.0.0.1:" + port; - handler = function(request, callback) { + var port = server.address().port; + var url = "http://127.0.0.1:" + port; + var handler = function(request, callback) { var data; data = { url: url, @@ -794,6 +804,7 @@ describe('protocol module', function() { }); }); }); + return describe('protocol.uninterceptProtocol', function() { it('returns error when scheme does not exist', function(done) { return protocol.uninterceptProtocol('not-exist', function(error) { @@ -801,6 +812,7 @@ describe('protocol module', function() { return done(); }); }); + return it('returns error when scheme is not intercepted', function(done) { return protocol.uninterceptProtocol('http', function(error) { assert.notEqual(error, null); diff --git a/spec/api-screen-spec.js b/spec/api-screen-spec.js index abc12784165..9329c01823d 100644 --- a/spec/api-screen-spec.js +++ b/spec/api-screen-spec.js @@ -4,16 +4,15 @@ const screen = require('electron').screen; describe('screen module', function() { describe('screen.getCursorScreenPoint()', function() { return it('returns a point object', function() { - var point; - point = screen.getCursorScreenPoint(); + var point = screen.getCursorScreenPoint(); assert.equal(typeof point.x, 'number'); return assert.equal(typeof point.y, 'number'); }); }); + return describe('screen.getPrimaryDisplay()', function() { return it('returns a display object', function() { - var display; - display = screen.getPrimaryDisplay(); + var display = screen.getPrimaryDisplay(); assert.equal(typeof display.scaleFactor, 'number'); assert(display.size.width > 0); return assert(display.size.height > 0); diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index fe27f932cee..a4421a18ed0 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -11,11 +11,12 @@ const session = remote.session; const BrowserWindow = remote.BrowserWindow; describe('session module', function() { - var fixtures, url, w; this.timeout(10000); - fixtures = path.resolve(__dirname, 'fixtures'); - w = null; - url = "http://127.0.0.1"; + + var fixtures = path.resolve(__dirname, 'fixtures'); + var w = null; + var url = "http://127.0.0.1"; + beforeEach(function() { return w = new BrowserWindow({ show: false, @@ -23,6 +24,7 @@ describe('session module', function() { height: 400 }); }); + afterEach(function() { return w.destroy(); }); @@ -62,6 +64,7 @@ describe('session module', function() { }); }); }); + it('should over-write the existent cookie', function(done) { return session.defaultSession.cookies.set({ url: url, @@ -92,6 +95,7 @@ describe('session module', function() { }); }); }); + it('should remove cookies', function(done) { return session.defaultSession.cookies.set({ url: url, @@ -155,6 +159,7 @@ describe('session module', function() { height: 400 }); }); + afterEach(function() { return w.destroy(); }); @@ -213,6 +218,7 @@ describe('session module', function() { assert(fs.existsSync(downloadFilePath)); return fs.unlinkSync(downloadFilePath); }; + it('can download using BrowserWindow.loadURL', function(done) { return downloadServer.listen(0, '127.0.0.1', function() { var port; @@ -225,6 +231,7 @@ describe('session module', function() { }); }); }); + it('can download using WebView.downloadURL', function(done) { return downloadServer.listen(0, '127.0.0.1', function() { var port, webview; @@ -243,6 +250,7 @@ describe('session module', function() { return document.body.appendChild(webview); }); }); + it('can cancel download', function(done) { return downloadServer.listen(0, '127.0.0.1', function() { var port; diff --git a/spec/api-web-frame-spec.js b/spec/api-web-frame-spec.js index d3d43986ec8..1a3eca6d584 100644 --- a/spec/api-web-frame-spec.js +++ b/spec/api-web-frame-spec.js @@ -3,13 +3,11 @@ const path = require('path'); const webFrame = require('electron').webFrame; describe('webFrame module', function() { - var fixtures; - fixtures = path.resolve(__dirname, 'fixtures'); + var fixtures = path.resolve(__dirname, 'fixtures'); return describe('webFrame.registerURLSchemeAsPrivileged', function() { return it('supports fetch api', function(done) { - var url; webFrame.registerURLSchemeAsPrivileged('file'); - url = "file://" + fixtures + "/assets/logo.png"; + var url = "file://" + fixtures + "/assets/logo.png"; return fetch(url).then(function(response) { assert(response.ok); return done(); diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index 91b84c77e1b..e2a3a1ca38f 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -5,9 +5,8 @@ const remote = require('electron').remote; const session = remote.session; describe('webRequest module', function() { - var defaultURL, server, ses; - ses = session.defaultSession; - server = http.createServer(function(req, res) { + var ses = session.defaultSession; + var server = http.createServer(function(req, res) { var content; res.setHeader('Custom', ['Header']); content = req.url; @@ -16,7 +15,8 @@ describe('webRequest module', function() { } return res.end(content); }); - defaultURL = null; + var defaultURL = null; + before(function(done) { return server.listen(0, '127.0.0.1', function() { var port; @@ -25,13 +25,16 @@ describe('webRequest module', function() { return done(); }); }); + after(function() { return server.close(); }); + describe('webRequest.onBeforeRequest', function() { afterEach(function() { return ses.webRequest.onBeforeRequest(null); }); + it('can cancel the request', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { return callback({ @@ -48,9 +51,9 @@ describe('webRequest module', function() { } }); }); + it('can filter URLs', function(done) { - var filter; - filter = { + var filter = { urls: [defaultURL + "filter/*"] }; ses.webRequest.onBeforeRequest(filter, function(details, callback) { @@ -77,6 +80,7 @@ describe('webRequest module', function() { } }); }); + it('receives details object', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { assert.equal(typeof details.id, 'number'); @@ -98,6 +102,7 @@ describe('webRequest module', function() { } }); }); + it('receives post data in details object', function(done) { var postData = { name: 'post test', @@ -125,6 +130,7 @@ describe('webRequest module', function() { } }); }); + return it('can redirect the request', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { if (details.url === defaultURL) { @@ -147,10 +153,12 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onBeforeSendHeaders', function() { afterEach(function() { return ses.webRequest.onBeforeSendHeaders(null); }); + it('receives details object', function(done) { ses.webRequest.onBeforeSendHeaders(function(details, callback) { assert.equal(typeof details.requestHeaders, 'object'); @@ -167,6 +175,7 @@ describe('webRequest module', function() { } }); }); + it('can change the request headers', function(done) { ses.webRequest.onBeforeSendHeaders(function(details, callback) { var requestHeaders; @@ -187,6 +196,7 @@ describe('webRequest module', function() { } }); }); + return it('resets the whole headers', function(done) { var requestHeaders; requestHeaders = { @@ -209,10 +219,12 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onSendHeaders', function() { afterEach(function() { return ses.webRequest.onSendHeaders(null); }); + return it('receives details object', function(done) { ses.webRequest.onSendHeaders(function(details) { return assert.equal(typeof details.requestHeaders, 'object'); @@ -229,10 +241,12 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onHeadersReceived', function() { afterEach(function() { return ses.webRequest.onHeadersReceived(null); }); + it('receives details object', function(done) { ses.webRequest.onHeadersReceived(function(details, callback) { assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); @@ -251,6 +265,7 @@ describe('webRequest module', function() { } }); }); + it('can change the response header', function(done) { ses.webRequest.onHeadersReceived(function(details, callback) { var responseHeaders; @@ -272,6 +287,7 @@ describe('webRequest module', function() { } }); }); + return it('does not change header by default', function(done) { ses.webRequest.onHeadersReceived(function(details, callback) { return callback({}); @@ -289,10 +305,12 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onResponseStarted', function() { afterEach(function() { return ses.webRequest.onResponseStarted(null); }); + return it('receives details object', function(done) { ses.webRequest.onResponseStarted(function(details) { assert.equal(typeof details.fromCache, 'boolean'); @@ -313,11 +331,13 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onBeforeRedirect', function() { afterEach(function() { ses.webRequest.onBeforeRedirect(null); return ses.webRequest.onBeforeRequest(null); }); + return it('receives details object', function(done) { var redirectURL; redirectURL = defaultURL + "redirect"; @@ -348,10 +368,12 @@ describe('webRequest module', function() { }); }); }); + describe('webRequest.onCompleted', function() { afterEach(function() { return ses.webRequest.onCompleted(null); }); + return it('receives details object', function(done) { ses.webRequest.onCompleted(function(details) { assert.equal(typeof details.fromCache, 'boolean'); @@ -370,11 +392,13 @@ describe('webRequest module', function() { }); }); }); + return describe('webRequest.onErrorOccurred', function() { afterEach(function() { ses.webRequest.onErrorOccurred(null); return ses.webRequest.onBeforeRequest(null); }); + return it('receives details object', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { return callback({ diff --git a/spec/asar-spec.js b/spec/asar-spec.js index a8f449451fc..064212e7c7e 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -10,8 +10,8 @@ const ipcMain = remote.require('electron').ipcMain; const BrowserWindow = remote.require('electron').BrowserWindow; describe('asar package', function() { - var fixtures; - fixtures = path.join(__dirname, 'fixtures'); + var fixtures = path.join(__dirname, 'fixtures'); + describe('node api', function() { describe('fs.readFileSync', function() { it('does not leak fd', function() { @@ -21,6 +21,7 @@ describe('asar package', function() { readCalls++; } }); + it('reads a normal file', function() { var file1, file2, file3; file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); @@ -30,6 +31,7 @@ describe('asar package', function() { file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); return assert.equal(fs.readFileSync(file3).toString().trim(), 'file3'); }); + it('reads from a empty file', function() { var buffer, file; file = path.join(fixtures, 'asar', 'empty.asar', 'file1'); @@ -37,11 +39,13 @@ describe('asar package', function() { assert.equal(buffer.length, 0); return assert.equal(buffer.toString(), ''); }); + it('reads a linked file', function() { var p; p = path.join(fixtures, 'asar', 'a.asar', 'link1'); return assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); }); + it('reads a file from linked directory', function() { var p; p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1'); @@ -49,6 +53,7 @@ describe('asar package', function() { p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); return assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); }); + it('throws ENOENT error when can not find file', function() { var p, throws; p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); @@ -57,6 +62,7 @@ describe('asar package', function() { }; return assert.throws(throws, /ENOENT/); }); + it('passes ENOENT error to callback when can not find file', function() { var async, p; p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); @@ -67,12 +73,14 @@ describe('asar package', function() { }); return async = true; }); + return it('reads a normal file with unpacked files', function() { var p; p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); return assert.equal(fs.readFileSync(p).toString().trim(), 'a'); }); }); + describe('fs.readFile', function() { it('reads a normal file', function(done) { var p; @@ -83,6 +91,7 @@ describe('asar package', function() { return done(); }); }); + it('reads from a empty file', function(done) { var p; p = path.join(fixtures, 'asar', 'empty.asar', 'file1'); @@ -92,6 +101,7 @@ describe('asar package', function() { return done(); }); }); + it('reads a linked file', function(done) { var p; p = path.join(fixtures, 'asar', 'a.asar', 'link1'); @@ -101,6 +111,7 @@ describe('asar package', function() { return done(); }); }); + it('reads a file from linked directory', function(done) { var p; p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); @@ -110,6 +121,7 @@ describe('asar package', function() { return done(); }); }); + return it('throws ENOENT error when can not find file', function(done) { var p; p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); @@ -119,6 +131,7 @@ describe('asar package', function() { }); }); }); + describe('fs.lstatSync', function() { it('handles path with trailing slash correctly', function() { var p; @@ -126,6 +139,7 @@ describe('asar package', function() { fs.lstatSync(p); return fs.lstatSync(p + '/'); }); + it('returns information of root', function() { var p, stats; p = path.join(fixtures, 'asar', 'a.asar'); @@ -135,6 +149,7 @@ describe('asar package', function() { assert.equal(stats.isSymbolicLink(), false); return assert.equal(stats.size, 0); }); + it('returns information of a normal file', function() { var file, j, len, p, ref2, results, stats; ref2 = ['file1', 'file2', 'file3', path.join('dir1', 'file1'), path.join('link2', 'file1')]; @@ -150,6 +165,7 @@ describe('asar package', function() { } return results; }); + it('returns information of a normal directory', function() { var file, j, len, p, ref2, results, stats; ref2 = ['dir1', 'dir2', 'dir3']; @@ -165,6 +181,7 @@ describe('asar package', function() { } return results; }); + it('returns information of a linked file', function() { var file, j, len, p, ref2, results, stats; ref2 = ['link1', path.join('dir1', 'link1'), path.join('link2', 'link2')]; @@ -180,6 +197,7 @@ describe('asar package', function() { } return results; }); + it('returns information of a linked directory', function() { var file, j, len, p, ref2, results, stats; ref2 = ['link2', path.join('dir1', 'link2'), path.join('link2', 'link2')]; @@ -195,6 +213,7 @@ describe('asar package', function() { } return results; }); + return it('throws ENOENT error when can not find file', function() { var file, j, len, p, ref2, results, throws; ref2 = ['file4', 'file5', path.join('dir1', 'file4')]; @@ -210,12 +229,13 @@ describe('asar package', function() { return results; }); }); + describe('fs.lstat', function() { it('handles path with trailing slash correctly', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); return fs.lstat(p + '/', done); }); + it('returns information of root', function(done) { var p = path.join(fixtures, 'asar', 'a.asar'); fs.lstat(p, function(err, stats) { @@ -227,6 +247,7 @@ describe('asar package', function() { return done(); }); }); + it('returns information of a normal file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1'); fs.lstat(p, function(err, stats) { @@ -238,6 +259,7 @@ describe('asar package', function() { return done(); }); }); + it('returns information of a normal directory', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); fs.lstat(p, function(err, stats) { @@ -249,6 +271,7 @@ describe('asar package', function() { return done(); }); }); + it('returns information of a linked file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link1'); fs.lstat(p, function(err, stats) { @@ -260,6 +283,7 @@ describe('asar package', function() { return done(); }); }); + it('returns information of a linked directory', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); fs.lstat(p, function(err, stats) { @@ -271,6 +295,7 @@ describe('asar package', function() { return done(); }); }); + return it('throws ENOENT error when can not find file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'file4'); fs.lstat(p, function(err) { @@ -279,97 +304,97 @@ describe('asar package', function() { }); }); }); + describe('fs.realpathSync', function() { it('returns real path root', function() { - var p, parent, r; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = 'a.asar'; - r = fs.realpathSync(path.join(parent, p)); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = 'a.asar'; + var r = fs.realpathSync(path.join(parent, p)); return assert.equal(r, path.join(parent, p)); }); + it('returns real path of a normal file', function() { - var p, parent, r; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'file1'); - r = fs.realpathSync(path.join(parent, p)); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'file1'); + var r = fs.realpathSync(path.join(parent, p)); return assert.equal(r, path.join(parent, p)); }); + it('returns real path of a normal directory', function() { - var p, parent, r; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'dir1'); - r = fs.realpathSync(path.join(parent, p)); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'dir1'); + var r = fs.realpathSync(path.join(parent, p)); return assert.equal(r, path.join(parent, p)); }); + it('returns real path of a linked file', function() { - var p, parent, r; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'link2', 'link1'); - r = fs.realpathSync(path.join(parent, p)); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'link2', 'link1'); + var r = fs.realpathSync(path.join(parent, p)); return assert.equal(r, path.join(parent, 'a.asar', 'file1')); }); + it('returns real path of a linked directory', function() { - var p, parent, r; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'link2', 'link2'); - r = fs.realpathSync(path.join(parent, p)); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'link2', 'link2'); + var r = fs.realpathSync(path.join(parent, p)); return assert.equal(r, path.join(parent, 'a.asar', 'dir1')); }); + return it('throws ENOENT error when can not find file', function() { - var p, parent, throws; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'not-exist'); - throws = function() { + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'not-exist'); + var throws = function() { return fs.realpathSync(path.join(parent, p)); }; return assert.throws(throws, /ENOENT/); }); }); + describe('fs.realpath', function() { it('returns real path root', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = 'a.asar'; + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = 'a.asar'; return fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); return done(); }); }); + it('returns real path of a normal file', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'file1'); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'file1'); return fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); return done(); }); }); + it('returns real path of a normal directory', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'dir1'); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'dir1'); return fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); return done(); }); }); + it('returns real path of a linked file', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'link2', 'link1'); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'link2', 'link1'); return fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, 'a.asar', 'file1')); return done(); }); }); + it('returns real path of a linked directory', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'link2', 'link2'); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'link2', 'link2'); return fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, 'a.asar', 'dir1')); @@ -377,9 +402,8 @@ describe('asar package', function() { }); }); return it('throws ENOENT error when can not find file', function(done) { - var p, parent; - parent = fs.realpathSync(path.join(fixtures, 'asar')); - p = path.join('a.asar', 'not-exist'); + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('a.asar', 'not-exist'); return fs.realpath(path.join(parent, p), function(err) { assert.equal(err.code, 'ENOENT'); return done(); @@ -388,32 +412,32 @@ describe('asar package', function() { }); describe('fs.readdirSync', function() { it('reads dirs from root', function() { - var dirs, p; - p = path.join(fixtures, 'asar', 'a.asar'); - dirs = fs.readdirSync(p); + var p = path.join(fixtures, 'asar', 'a.asar'); + var dirs = fs.readdirSync(p); return assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); }); + it('reads dirs from a normal dir', function() { - var dirs, p; - p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); - dirs = fs.readdirSync(p); + var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); + var dirs = fs.readdirSync(p); return assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); }); + it('reads dirs from a linked dir', function() { - var dirs, p; - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); - dirs = fs.readdirSync(p); + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); + var dirs = fs.readdirSync(p); return assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); }); + return it('throws ENOENT error when can not find file', function() { - var p, throws; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - throws = function() { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var throws = function() { return fs.readdirSync(p); }; return assert.throws(throws, /ENOENT/); }); }); + describe('fs.readdir', function() { it('reads dirs from root', function(done) { var p = path.join(fixtures, 'asar', 'a.asar'); @@ -423,6 +447,7 @@ describe('asar package', function() { return done(); }); }); + it('reads dirs from a normal dir', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); fs.readdir(p, function(err, dirs) { @@ -439,15 +464,16 @@ describe('asar package', function() { return done(); }); }); + return it('throws ENOENT error when can not find file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); return fs.readdir(p, function(err) { assert.equal(err.code, 'ENOENT'); return done(); }); }); }); + describe('fs.openSync', function() { it('opens a normal/linked/under-linked-directory file', function() { var buffer, fd, file, j, len, p, ref2, results; @@ -464,19 +490,19 @@ describe('asar package', function() { } return results; }); + return it('throws ENOENT error when can not find file', function() { - var p, throws; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - throws = function() { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var throws = function() { return fs.openSync(p); }; return assert.throws(throws, /ENOENT/); }); }); + describe('fs.open', function() { it('opens a normal file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'file1'); return fs.open(p, 'r', function(err, fd) { var buffer; assert.equal(err, null); @@ -488,48 +514,48 @@ describe('asar package', function() { }); }); }); + return it('throws ENOENT error when can not find file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); return fs.open(p, 'r', function(err) { assert.equal(err.code, 'ENOENT'); return done(); }); }); }); + describe('fs.mkdir', function() { return it('throws error when calling inside asar archive', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); return fs.mkdir(p, function(err) { assert.equal(err.code, 'ENOTDIR'); return done(); }); }); }); + describe('fs.mkdirSync', function() { return it('throws error when calling inside asar archive', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); return assert.throws((function() { return fs.mkdirSync(p); }), new RegExp('ENOTDIR')); }); }); + describe('child_process.fork', function() { it('opens a normal js file', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'asar', 'a.asar', 'ping.js')); + var child = child_process.fork(path.join(fixtures, 'asar', 'a.asar', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); return done(); }); return child.send('message'); }); + return it('supports asar in the forked js', function(done) { - var child, file; - file = path.join(fixtures, 'asar', 'a.asar', 'file1'); - child = child_process.fork(path.join(fixtures, 'module', 'asar.js')); + var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var child = child_process.fork(path.join(fixtures, 'module', 'asar.js')); child.on('message', function(content) { assert.equal(content, fs.readFileSync(file).toString()); return done(); @@ -537,6 +563,7 @@ describe('asar package', function() { return child.send(file); }); }); + describe('child_process.execFile', function() { var echo, execFile, execFileSync, ref2; if (process.platform !== 'darwin') { @@ -544,6 +571,7 @@ describe('asar package', function() { } ref2 = require('child_process'), execFile = ref2.execFile, execFileSync = ref2.execFileSync; echo = path.join(fixtures, 'asar', 'echo.asar', 'echo'); + it('executes binaries', function(done) { execFile(echo, ['test'], function(error, stdout) { assert.equal(error, null); @@ -551,15 +579,17 @@ describe('asar package', function() { return done(); }); }); + return xit('execFileSync executes binaries', function() { var output; output = execFileSync(echo, ['test']); return assert.equal(String(output), 'test\n'); }); }); + describe('internalModuleReadFile', function() { - var internalModuleReadFile; - internalModuleReadFile = process.binding('fs').internalModuleReadFile; + var internalModuleReadFile = process.binding('fs').internalModuleReadFile; + it('read a normal file', function() { var file1, file2, file3; file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); @@ -569,25 +599,28 @@ describe('asar package', function() { file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); return assert.equal(internalModuleReadFile(file3).toString().trim(), 'file3'); }); + return it('reads a normal file with unpacked files', function() { var p; p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); return assert.equal(internalModuleReadFile(p).toString().trim(), 'a'); }); }); + return describe('process.noAsar', function() { - var errorName; - errorName = process.platform === 'win32' ? 'ENOENT' : 'ENOTDIR'; + var errorName = process.platform === 'win32' ? 'ENOENT' : 'ENOTDIR'; + beforeEach(function() { return process.noAsar = true; }); + afterEach(function() { return process.noAsar = false; }); + it('disables asar support in sync API', function() { - var dir, file; - file = path.join(fixtures, 'asar', 'a.asar', 'file1'); - dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); + var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); assert.throws((function() { return fs.readFileSync(file); }), new RegExp(errorName)); @@ -601,6 +634,7 @@ describe('asar package', function() { return fs.readdirSync(dir); }), new RegExp(errorName)); }); + it('disables asar support in async API', function(done) { var dir, file; file = path.join(fixtures, 'asar', 'a.asar', 'file1'); @@ -619,6 +653,7 @@ describe('asar package', function() { }); }); }); + return it('treats *.asar as normal file', function() { var asar, content1, content2, originalFs; originalFs = require('original-fs'); @@ -632,44 +667,44 @@ describe('asar package', function() { }); }); }); + describe('asar protocol', function() { - var url; - url = require('url'); + var url = require('url'); + it('can request a file in package', function(done) { - var p; - p = path.resolve(fixtures, 'asar', 'a.asar', 'file1'); + var p = path.resolve(fixtures, 'asar', 'a.asar', 'file1'); return $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file1'); return done(); }); }); + it('can request a file in package with unpacked files', function(done) { - var p; - p = path.resolve(fixtures, 'asar', 'unpack.asar', 'a.txt'); + var p = path.resolve(fixtures, 'asar', 'unpack.asar', 'a.txt'); return $.get("file://" + p, function(data) { assert.equal(data.trim(), 'a'); return done(); }); }); + it('can request a linked file in package', function(done) { - var p; - p = path.resolve(fixtures, 'asar', 'a.asar', 'link2', 'link1'); + var p = path.resolve(fixtures, 'asar', 'a.asar', 'link2', 'link1'); return $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file1'); return done(); }); }); + it('can request a file in filesystem', function(done) { - var p; - p = path.resolve(fixtures, 'asar', 'file'); + var p = path.resolve(fixtures, 'asar', 'file'); return $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file'); return done(); }); }); + it('gets 404 when file is not found', function(done) { - var p; - p = path.resolve(fixtures, 'asar', 'a.asar', 'no-exist'); + var p = path.resolve(fixtures, 'asar', 'a.asar', 'no-exist'); return $.ajax({ url: "file://" + p, error: function(err) { @@ -678,19 +713,20 @@ describe('asar package', function() { } }); }); + it('sets __dirname correctly', function(done) { - var p, u, w; after(function() { w.destroy(); return ipcMain.removeAllListeners('dirname'); }); - w = new BrowserWindow({ + + var w = new BrowserWindow({ show: false, width: 400, height: 400 }); - p = path.resolve(fixtures, 'asar', 'web.asar', 'index.html'); - u = url.format({ + var p = path.resolve(fixtures, 'asar', 'web.asar', 'index.html'); + var u = url.format({ protocol: 'file', slashed: true, pathname: p @@ -701,19 +737,20 @@ describe('asar package', function() { }); return w.loadURL(u); }); + return it('loads script tag in html', function(done) { - var p, u, w; after(function() { w.destroy(); return ipcMain.removeAllListeners('ping'); }); - w = new BrowserWindow({ + + var w = new BrowserWindow({ show: false, width: 400, height: 400 }); - p = path.resolve(fixtures, 'asar', 'script.asar', 'index.html'); - u = url.format({ + var p = path.resolve(fixtures, 'asar', 'script.asar', 'index.html'); + var u = url.format({ protocol: 'file', slashed: true, pathname: p @@ -725,15 +762,17 @@ describe('asar package', function() { }); }); }); + describe('original-fs module', function() { - var originalFs; - originalFs = require('original-fs'); + var originalFs = require('original-fs'); + it('treats .asar as file', function() { var file, stats; file = path.join(fixtures, 'asar', 'a.asar'); stats = originalFs.statSync(file); return assert(stats.isFile()); }); + return it('is available in forked scripts', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'original-fs.js')); @@ -744,9 +783,10 @@ describe('asar package', function() { return child.send('message'); }); }); + describe('graceful-fs module', function() { - var gfs; - gfs = require('graceful-fs'); + var gfs = require('graceful-fs'); + it('recognize asar archvies', function() { var p; p = path.join(fixtures, 'asar', 'a.asar', 'link1'); @@ -756,9 +796,10 @@ describe('asar package', function() { return assert.notEqual(fs.readdir, gfs.readdir); }); }); + describe('mkdirp module', function() { - var mkdirp; - mkdirp = require('mkdirp'); + var mkdirp = require('mkdirp'); + return it('throws error when calling inside asar archive', function() { var p; p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); @@ -767,20 +808,20 @@ describe('asar package', function() { }), new RegExp('ENOTDIR')); }); }); + return describe('native-image', function() { it('reads image from asar archive', function() { - var logo, p; - p = path.join(fixtures, 'asar', 'logo.asar', 'logo.png'); - logo = nativeImage.createFromPath(p); + var p = path.join(fixtures, 'asar', 'logo.asar', 'logo.png'); + var logo = nativeImage.createFromPath(p); return assert.deepEqual(logo.getSize(), { width: 55, height: 55 }); }); + return it('reads image from asar archive with unpacked files', function() { - var logo, p; - p = path.join(fixtures, 'asar', 'unpack.asar', 'atom.png'); - logo = nativeImage.createFromPath(p); + var p = path.join(fixtures, 'asar', 'unpack.asar', 'atom.png'); + var logo = nativeImage.createFromPath(p); return assert.deepEqual(logo.getSize(), { width: 1024, height: 1024 diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 56fa21c89a7..21cefb0b0bc 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -8,20 +8,22 @@ const BrowserWindow = remote.require('electron').BrowserWindow; const session = remote.require('electron').session; describe('chromium feature', function() { - var fixtures, listener; - fixtures = path.resolve(__dirname, 'fixtures'); - listener = null; + var fixtures = path.resolve(__dirname, 'fixtures'); + var listener = null; + afterEach(function() { if (listener != null) { window.removeEventListener('message', listener); } return listener = null; }); + xdescribe('heap snapshot', function() { return it('does not crash', function() { return process.atomBinding('v8_util').takeHeapSnapshot(); }); }); + describe('sending request of http protocol urls', function() { return it('does not crash', function(done) { var server; @@ -38,13 +40,15 @@ describe('chromium feature', function() { }); }); }); + describe('document.hidden', function() { - var url, w; - url = "file://" + fixtures + "/pages/document-hidden.html"; - w = null; + var url = "file://" + fixtures + "/pages/document-hidden.html"; + var w = null; + afterEach(function() { return w != null ? w.destroy() : void 0; }); + it('is set correctly when window is not shown', function(done) { w = new BrowserWindow({ show: false @@ -55,6 +59,7 @@ describe('chromium feature', function() { }); return w.loadURL(url); }); + return it('is set correctly when window is inactive', function(done) { w = new BrowserWindow({ show: false @@ -67,6 +72,7 @@ describe('chromium feature', function() { return w.loadURL(url); }); }); + xdescribe('navigator.webkitGetUserMedia', function() { return it('calls its callbacks', function(done) { this.timeout(5000); @@ -80,18 +86,21 @@ describe('chromium feature', function() { }); }); }); + describe('navigator.language', function() { return it('should not be empty', function() { return assert.notEqual(navigator.language, ''); }); }); + describe('navigator.serviceWorker', function() { - var url, w; - url = "file://" + fixtures + "/pages/service-worker/index.html"; - w = null; + var url = "file://" + fixtures + "/pages/service-worker/index.html"; + var w = null; + afterEach(function() { return w != null ? w.destroy() : void 0; }); + return it('should register for file scheme', function(done) { w = new BrowserWindow({ show: false @@ -113,8 +122,10 @@ describe('chromium feature', function() { return w.loadURL(url); }); }); + describe('window.open', function() { this.timeout(20000); + it('returns a BrowserWindowProxy object', function() { var b; b = window.open('about:blank', '', 'show=no'); @@ -122,6 +133,7 @@ describe('chromium feature', function() { assert.equal(b.constructor.name, 'BrowserWindowProxy'); return b.close(); }); + it('accepts "node-integration" as feature', function(done) { var b; listener = function(event) { @@ -132,6 +144,7 @@ describe('chromium feature', function() { window.addEventListener('message', listener); return b = window.open("file://" + fixtures + "/pages/window-opener-node.html", '', 'nodeIntegration=no,show=no'); }); + it('inherit options of parent window', function(done) { var b; listener = function(event) { @@ -144,6 +157,7 @@ describe('chromium feature', function() { window.addEventListener('message', listener); return b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', 'show=no'); }); + return it('does not override child options', function(done) { var b, size; size = { @@ -159,6 +173,7 @@ describe('chromium feature', function() { return b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', "show=no,width=" + size.width + ",height=" + size.height); }); }); + describe('window.opener', function() { var url, w; this.timeout(10000); @@ -188,6 +203,7 @@ describe('chromium feature', function() { return b = window.open(url, '', 'show=no'); }); }); + describe('window.postMessage', function() { return it('sets the source and origin correctly', function(done) { var b, sourceId; @@ -211,6 +227,7 @@ describe('chromium feature', function() { }); }); }); + describe('window.opener.postMessage', function() { return it('sets source and origin correctly', function(done) { var b; @@ -225,6 +242,7 @@ describe('chromium feature', function() { return b = window.open("file://" + fixtures + "/pages/window-opener-postMessage.html", '', 'show=no'); }); }); + describe('creating a Uint8Array under browser side', function() { return it('does not crash', function() { var RUint8Array; @@ -232,6 +250,7 @@ describe('chromium feature', function() { return new RUint8Array; }); }); + describe('webgl', function() { return it('can be get as context in canvas', function() { var webgl; @@ -242,6 +261,7 @@ describe('chromium feature', function() { return assert.notEqual(webgl, null); }); }); + describe('web workers', function() { it('Worker can work', function(done) { var message, worker; @@ -254,6 +274,7 @@ describe('chromium feature', function() { }; return worker.postMessage(message); }); + return it('SharedWorker can work', function(done) { var message, worker; worker = new SharedWorker('../fixtures/workers/shared_worker.js'); @@ -265,15 +286,18 @@ describe('chromium feature', function() { return worker.port.postMessage(message); }); }); + describe('iframe', function() { - var iframe; - iframe = null; + var iframe = null; + beforeEach(function() { return iframe = document.createElement('iframe'); }); + afterEach(function() { return document.body.removeChild(iframe); }); + return it('does not have node integration', function(done) { iframe.src = "file://" + fixtures + "/pages/set-global.html"; document.body.appendChild(iframe); @@ -283,6 +307,7 @@ describe('chromium feature', function() { }; }); }); + describe('storage', function() { return it('requesting persitent quota works', function(done) { return navigator.webkitPersistentStorage.requestQuota(1024 * 1024, function(grantedBytes) { @@ -291,15 +316,17 @@ describe('chromium feature', function() { }); }); }); + describe('websockets', function() { - var WebSocketServer, server, wss; - wss = null; - server = null; - WebSocketServer = ws.Server; + var wss = null; + var server = null; + var WebSocketServer = ws.Server; + afterEach(function() { wss.close(); return server.close(); }); + return it('has user agent', function(done) { server = http.createServer(); return server.listen(0, '127.0.0.1', function() { @@ -319,6 +346,7 @@ describe('chromium feature', function() { }); }); }); + return describe('Promise', function() { it('resolves correctly in Node.js calls', function(done) { document.registerElement('x-element', { @@ -338,6 +366,7 @@ describe('chromium feature', function() { return called = true; }); }); + return it('resolves correctly in Electron calls', function(done) { document.registerElement('y-element', { prototype: Object.create(HTMLElement.prototype, { diff --git a/spec/modules-spec.js b/spec/modules-spec.js index 6a0471e4cea..e3d5bd75c6d 100644 --- a/spec/modules-spec.js +++ b/spec/modules-spec.js @@ -3,14 +3,15 @@ const path = require('path'); const temp = require('temp'); describe('third-party module', function() { - var fixtures; - fixtures = path.join(__dirname, 'fixtures'); + var fixtures = path.join(__dirname, 'fixtures'); temp.track(); + if (process.platform !== 'win32' || process.execPath.toLowerCase().indexOf('\\out\\d\\') === -1) { describe('runas', function() { it('can be required in renderer', function() { return require('runas'); }); + return it('can be required in node binary', function(done) { var child, runas; runas = path.join(fixtures, 'module', 'runas.js'); @@ -21,6 +22,7 @@ describe('third-party module', function() { }); }); }); + describe('ffi', function() { return it('does not crash', function() { var ffi, libm; @@ -32,6 +34,7 @@ describe('third-party module', function() { }); }); } + return describe('q', function() { var Q; Q = require('q'); diff --git a/spec/node-spec.js b/spec/node-spec.js index 6f84f59921f..9ead9202653 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -6,8 +6,8 @@ const os = require('os'); const remote = require('electron').remote; describe('node feature', function() { - var fixtures; - fixtures = path.join(__dirname, 'fixtures'); + var fixtures = path.join(__dirname, 'fixtures'); + describe('child_process', function() { return describe('child_process.fork', function() { it('works in current process', function(done) { @@ -19,6 +19,7 @@ describe('node feature', function() { }); return child.send('message'); }); + it('preserves args', function(done) { var args, child; args = ['--expose_gc', '-test', '1']; @@ -29,6 +30,7 @@ describe('node feature', function() { }); return child.send('message'); }); + it('works in forked process', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js')); @@ -38,6 +40,7 @@ describe('node feature', function() { }); return child.send('message'); }); + it('works in forked process when options.env is specifed', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js'), [], { @@ -49,6 +52,7 @@ describe('node feature', function() { }); return child.send('message'); }); + it('works in browser process', function(done) { var child, fork; fork = remote.require('child_process').fork; @@ -59,6 +63,7 @@ describe('node feature', function() { }); return child.send('message'); }); + it('has String::localeCompare working in script', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'locale-compare.js')); @@ -68,6 +73,7 @@ describe('node feature', function() { }); return child.send('message'); }); + return it('has setImmediate working in script', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'set-immediate.js')); @@ -79,17 +85,20 @@ describe('node feature', function() { }); }); }); + describe('contexts', function() { describe('setTimeout in fs callback', function() { if (process.env.TRAVIS === 'true') { return; } + return it('does not crash', function(done) { return fs.readFile(__filename, function() { return setTimeout(done, 0); }); }); }); + describe('throw error in node context', function() { return it('gets caught', function(done) { var error, lsts; @@ -110,11 +119,13 @@ describe('node feature', function() { }); }); }); + describe('setTimeout called under Chromium event loop in browser process', function() { return it('can be scheduled in time', function(done) { return remote.getGlobal('setTimeout')(done, 0); }); }); + return describe('setInterval called under Chromium event loop in browser process', function() { return it('can be scheduled in time', function(done) { var clear, interval; @@ -126,11 +137,13 @@ describe('node feature', function() { }); }); }); + describe('message loop', function() { describe('process.nextTick', function() { it('emits the callback', function(done) { return process.nextTick(done); }); + return it('works in nested calls', function(done) { return process.nextTick(function() { return process.nextTick(function() { @@ -139,10 +152,12 @@ describe('node feature', function() { }); }); }); + return describe('setImmediate', function() { it('emits the callback', function(done) { return setImmediate(done); }); + return it('works in nested calls', function(done) { return setImmediate(function() { return setImmediate(function() { @@ -152,10 +167,12 @@ describe('node feature', function() { }); }); }); + describe('net.connect', function() { if (process.platform !== 'darwin') { return; } + return it('emit error when connect to a socket path without listeners', function(done) { var child, script, socketPath; socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock'); @@ -172,6 +189,7 @@ describe('node feature', function() { }); }); }); + describe('Buffer', function() { it('can be created from WebKit external string', function() { var b, p; @@ -181,6 +199,7 @@ describe('node feature', function() { assert.equal(b.toString(), '闲云潭影日悠悠,物换星移几度秋'); return assert.equal(Buffer.byteLength(p.innerText), 45); }); + return it('correctly parses external one-byte UTF8 string', function() { var b, p; p = document.createElement('p'); From 12adaa0570e6d8ef6a64272027d4a622ea8bc17e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 17:39:11 -0800 Subject: [PATCH 241/688] Remove unneeded returns --- spec/api-app-spec.js | 50 ++--- spec/api-clipboard-spec.js | 46 ++-- spec/api-crash-reporter-spec.js | 22 +- spec/api-ipc-spec.js | 57 +++-- spec/api-menu-spec.js | 46 ++-- spec/api-protocol-spec.js | 384 ++++++++++++++++---------------- spec/api-screen-spec.js | 10 +- spec/api-session-spec.js | 88 ++++---- spec/api-web-frame-spec.js | 12 +- spec/api-web-request-spec.js | 185 ++++++++------- spec/asar-spec.js | 376 +++++++++++++++---------------- spec/chromium-spec.js | 177 +++++++-------- spec/modules-spec.js | 35 ++- spec/node-spec.js | 111 +++++---- 14 files changed, 773 insertions(+), 826 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index ea305ae9535..7b2535d5404 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -23,38 +23,38 @@ describe('electron module', function() { describe('app module', function() { describe('app.getVersion()', function() { - return it('returns the version field of package.json', function() { - return assert.equal(app.getVersion(), '0.1.0'); + it('returns the version field of package.json', function() { + assert.equal(app.getVersion(), '0.1.0'); }); }); describe('app.setVersion(version)', function() { - return it('overrides the version', function() { + it('overrides the version', function() { assert.equal(app.getVersion(), '0.1.0'); app.setVersion('test-version'); assert.equal(app.getVersion(), 'test-version'); - return app.setVersion('0.1.0'); + app.setVersion('0.1.0'); }); }); describe('app.getName()', function() { - return it('returns the name field of package.json', function() { - return assert.equal(app.getName(), 'Electron Test'); + it('returns the name field of package.json', function() { + assert.equal(app.getName(), 'Electron Test'); }); }); describe('app.setName(name)', function() { - return it('overrides the name', function() { + it('overrides the name', function() { assert.equal(app.getName(), 'Electron Test'); app.setName('test-name'); assert.equal(app.getName(), 'test-name'); - return app.setName('Electron Test'); + app.setName('Electron Test'); }); }); describe('app.getLocale()', function() { - return it('should not be empty', function() { - return assert.notEqual(app.getLocale(), ''); + it('should not be empty', function() { + assert.notEqual(app.getLocale(), ''); }); }); @@ -62,71 +62,71 @@ describe('app module', function() { var appProcess = null; afterEach(function() { - return appProcess != null ? appProcess.kill() : void 0; + appProcess != null ? appProcess.kill() : void 0; }); - return it('emits a process exit event with the code', function(done) { + it('emits a process exit event with the code', function(done) { var appPath, electronPath, output; appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app'); electronPath = remote.getGlobal('process').execPath; appProcess = ChildProcess.spawn(electronPath, [appPath]); output = ''; appProcess.stdout.on('data', function(data) { - return output += data; + output += data; }); - return appProcess.on('close', function(code) { + appProcess.on('close', function(code) { if (process.platform !== 'win32') { assert.notEqual(output.indexOf('Exit event with code: 123'), -1); } assert.equal(code, 123); - return done(); + done(); }); }); }); - return describe('BrowserWindow events', function() { + describe('BrowserWindow events', function() { var w = null; afterEach(function() { if (w != null) { w.destroy(); } - return w = null; + w = null; }); it('should emit browser-window-focus event when window is focused', function(done) { app.once('browser-window-focus', function(e, window) { assert.equal(w.id, window.id); - return done(); + done(); }); w = new BrowserWindow({ show: false }); - return w.emit('focus'); + w.emit('focus'); }); it('should emit browser-window-blur event when window is blured', function(done) { app.once('browser-window-blur', function(e, window) { assert.equal(w.id, window.id); - return done(); + done(); }); w = new BrowserWindow({ show: false }); - return w.emit('blur'); + w.emit('blur'); }); - return it('should emit browser-window-created event when window is created', function(done) { + it('should emit browser-window-created event when window is created', function(done) { app.once('browser-window-created', function(e, window) { - return setImmediate(function() { + setImmediate(function() { assert.equal(w.id, window.id); - return done(); + done(); }); }); w = new BrowserWindow({ show: false }); - return w.emit('blur'); + w.emit('blur'); }); }); }); diff --git a/spec/api-clipboard-spec.js b/spec/api-clipboard-spec.js index 28afb4a5307..0b4a9f9521c 100644 --- a/spec/api-clipboard-spec.js +++ b/spec/api-clipboard-spec.js @@ -8,50 +8,46 @@ describe('clipboard module', function() { var fixtures = path.resolve(__dirname, 'fixtures'); describe('clipboard.readImage()', function() { - return it('returns NativeImage intance', function() { - var i, p; - p = path.join(fixtures, 'assets', 'logo.png'); - i = nativeImage.createFromPath(p); + it('returns NativeImage intance', function() { + var p = path.join(fixtures, 'assets', 'logo.png'); + var i = nativeImage.createFromPath(p); clipboard.writeImage(p); - return assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); + assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); }); }); describe('clipboard.readText()', function() { - return it('returns unicode string correctly', function() { - var text; - text = '千江有水千江月,万里无云万里天'; + it('returns unicode string correctly', function() { + var text = '千江有水千江月,万里无云万里天'; clipboard.writeText(text); - return assert.equal(clipboard.readText(), text); + assert.equal(clipboard.readText(), text); }); }); describe('clipboard.readHtml()', function() { - return it('returns markup correctly', function() { - var markup, text; - text = 'Hi'; - markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; + it('returns markup correctly', function() { + var text = 'Hi'; + var markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; clipboard.writeHtml(text); - return assert.equal(clipboard.readHtml(), markup); + assert.equal(clipboard.readHtml(), markup); }); }); describe('clipboard.readRtf', function() { - return it('returns rtf text correctly', function() { + it('returns rtf text correctly', function() { var rtf = "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}"; clipboard.writeRtf(rtf); - return assert.equal(clipboard.readRtf(), rtf); + assert.equal(clipboard.readRtf(), rtf); }); }); - return describe('clipboard.write()', function() { - return it('returns data correctly', function() { - var i, markup, p, text, rtf; - text = 'test'; - rtf = '{\\rtf1\\utf8 text}'; - p = path.join(fixtures, 'assets', 'logo.png'); - i = nativeImage.createFromPath(p); - markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; + describe('clipboard.write()', function() { + it('returns data correctly', function() { + var text = 'test'; + var rtf = '{\\rtf1\\utf8 text}'; + var p = path.join(fixtures, 'assets', 'logo.png'); + var i = nativeImage.createFromPath(p); + var markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; clipboard.write({ text: "test", html: 'Hi', @@ -61,7 +57,7 @@ describe('clipboard module', function() { assert.equal(clipboard.readText(), text); assert.equal(clipboard.readHtml(), markup); assert.equal(clipboard.readRtf(), rtf); - return assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); + assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); }); }); }); diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index 72662aa3d93..43830dd4ee1 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -14,13 +14,13 @@ describe('crash-reporter module', function() { var w = null; beforeEach(function() { - return w = new BrowserWindow({ + w = new BrowserWindow({ show: false }); }); afterEach(function() { - return w.destroy(); + w.destroy(); }); if (process.mas) { @@ -40,7 +40,7 @@ describe('crash-reporter module', function() { var form; server.close(); form = new multiparty.Form(); - return form.parse(req, function(error, fields) { + form.parse(req, function(error, fields) { if (called) { return; } @@ -55,11 +55,11 @@ describe('crash-reporter module', function() { assert.equal(fields['_companyName'], 'Umbrella Corporation'); assert.equal(fields['_version'], app.getVersion()); res.end('abc-123-def'); - return done(); + done(); }); }); var port = remote.process.port; - return server.listen(port, '127.0.0.1', function() { + server.listen(port, '127.0.0.1', function() { port = server.address().port; remote.process.port = port; const crashUrl = url.format({ @@ -73,19 +73,19 @@ describe('crash-reporter module', function() { submitURL: "http://127.0.0.1:" + port }); } - return w.loadURL(crashUrl); + w.loadURL(crashUrl); }); }); - return describe(".start(options)", function() { - return it('requires that the companyName and submitURL options be specified', function() { + describe(".start(options)", function() { + it('requires that the companyName and submitURL options be specified', function() { assert.throws(function() { - return crashReporter.start({ + crashReporter.start({ companyName: 'Missing submitURL' }); }); - return assert.throws(function() { - return crashReporter.start({ + assert.throws(function() { + crashReporter.start({ submitURL: 'Missing companyName' }); }); diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 6b1c99779b2..25d8c925688 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -12,7 +12,7 @@ const comparePaths = function(path1, path2) { path1 = path1.toLowerCase(); path2 = path2.toLowerCase(); } - return assert.equal(path1, path2); + assert.equal(path1, path2); }; describe('ipc module', function() { @@ -23,27 +23,26 @@ describe('ipc module', function() { var dialog1, dialog2; dialog1 = remote.require('electron'); dialog2 = remote.require('electron'); - return assert.equal(dialog1, dialog2); + assert.equal(dialog1, dialog2); }); it('should work when object contains id property', function() { - var a; - a = remote.require(path.join(fixtures, 'module', 'id.js')); - return assert.equal(a.id, 1127); + var a = remote.require(path.join(fixtures, 'module', 'id.js')); + assert.equal(a.id, 1127); }); - return it('should search module from the user app', function() { + it('should search module from the user app', function() { comparePaths(path.normalize(remote.process.mainModule.filename), path.resolve(__dirname, 'static', 'main.js')); - return comparePaths(path.normalize(remote.process.mainModule.paths[0]), path.resolve(__dirname, 'static', 'node_modules')); + comparePaths(path.normalize(remote.process.mainModule.paths[0]), path.resolve(__dirname, 'static', 'node_modules')); }); }); describe('remote.createFunctionWithReturnValue', function() { - return it('should be called in browser synchronously', function() { + it('should be called in browser synchronously', function() { var buf = new Buffer('test'); var call = remote.require(path.join(fixtures, 'module', 'call.js')); var result = call.call(remote.createFunctionWithReturnValue(buf)); - return assert.equal(result.constructor.name, 'Buffer'); + assert.equal(result.constructor.name, 'Buffer'); }); }); @@ -55,14 +54,14 @@ describe('ipc module', function() { assert.equal(property.property, 1007); var property2 = remote.require(path.join(fixtures, 'module', 'property.js')); assert.equal(property2.property, 1007); - return property.property = 1127; + property.property = 1127; }); - return it('can construct an object from its member', function() { + it('can construct an object from its member', function() { var call, obj; call = remote.require(path.join(fixtures, 'module', 'call.js')); obj = new call.constructor; - return assert.equal(obj.test, 'test'); + assert.equal(obj.test, 'test'); }); }); @@ -72,48 +71,48 @@ describe('ipc module', function() { it('keeps its constructor name for objects', function() { var buf = new Buffer('test'); var print_name = remote.require(print); - return assert.equal(print_name.print(buf), 'Buffer'); + assert.equal(print_name.print(buf), 'Buffer'); }); - return it('supports instanceof Date', function() { + it('supports instanceof Date', function() { var now = new Date(); var print_name = remote.require(print); assert.equal(print_name.print(now), 'Date'); - return assert.deepEqual(print_name.echo(now), now); + assert.deepEqual(print_name.echo(now), now); }); }); describe('remote promise', function() { - return it('can be used as promise in each side', function(done) { + it('can be used as promise in each side', function(done) { var promise = remote.require(path.join(fixtures, 'module', 'promise.js')); - return promise.twicePromise(Promise.resolve(1234)).then(function(value) { + promise.twicePromise(Promise.resolve(1234)).then(function(value) { assert.equal(value, 2468); - return done(); + done(); }); }); }); describe('ipc.sender.send', function() { - return it('should work when sending an object containing id property', function(done) { + it('should work when sending an object containing id property', function(done) { var obj = { id: 1, name: 'ly' }; ipcRenderer.once('message', function(event, message) { assert.deepEqual(message, obj); - return done(); + done(); }); - return ipcRenderer.send('message', obj); + ipcRenderer.send('message', obj); }); }); describe('ipc.sendSync', function() { it('can be replied by setting event.returnValue', function() { var msg = ipcRenderer.sendSync('echo', 'test'); - return assert.equal(msg, 'test'); + assert.equal(msg, 'test'); }); - return it('does not crash when reply is not sent and browser is destroyed', function(done) { + it('does not crash when reply is not sent and browser is destroyed', function(done) { this.timeout(10000); var w = new BrowserWindow({ @@ -122,20 +121,20 @@ describe('ipc module', function() { ipcMain.once('send-sync-message', function(event) { event.returnValue = null; w.destroy(); - return done(); + done(); }); - return w.loadURL('file://' + path.join(fixtures, 'api', 'send-sync-message.html')); + w.loadURL('file://' + path.join(fixtures, 'api', 'send-sync-message.html')); }); }); - return describe('remote listeners', function() { + describe('remote listeners', function() { var w = null; afterEach(function() { - return w.destroy(); + w.destroy(); }); - return it('can be added and removed correctly', function() { + it('can be added and removed correctly', function() { w = new BrowserWindow({ show: false }); @@ -143,7 +142,7 @@ describe('ipc module', function() { w.on('test', listener); assert.equal(w.listenerCount('test'), 1); w.removeListener('test', listener); - return assert.equal(w.listenerCount('test'), 0); + assert.equal(w.listenerCount('test'), 0); }); }); }); diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index 292a65a0f08..60464c73275 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -15,12 +15,12 @@ describe('menu module', function() { extra: 'field' } ]); - return assert.equal(menu.items[0].extra, 'field'); + assert.equal(menu.items[0].extra, 'field'); }); it('does not modify the specified template', function() { var template = ipcRenderer.sendSync('eval', "var template = [{label: 'text', submenu: [{label: 'sub'}]}];\nrequire('electron').Menu.buildFromTemplate(template);\ntemplate;"); - return assert.deepStrictEqual(template, [ + assert.deepStrictEqual(template, [ { label: 'text', submenu: [ @@ -32,7 +32,7 @@ describe('menu module', function() { ]); }); - return describe('Menu.buildFromTemplate should reorder based on item position specifiers', function() { + describe('Menu.buildFromTemplate should reorder based on item position specifiers', function() { it('should position before existing item', function() { var menu = Menu.buildFromTemplate([ { @@ -49,7 +49,7 @@ describe('menu module', function() { ]); assert.equal(menu.items[0].label, '1'); assert.equal(menu.items[1].label, '2'); - return assert.equal(menu.items[2].label, '3'); + assert.equal(menu.items[2].label, '3'); }); it('should position after existing item', function() { @@ -68,7 +68,7 @@ describe('menu module', function() { ]); assert.equal(menu.items[0].label, '1'); assert.equal(menu.items[1].label, '2'); - return assert.equal(menu.items[2].label, '3'); + assert.equal(menu.items[2].label, '3'); }); it('should position at endof existing separator groups', function() { @@ -112,7 +112,7 @@ describe('menu module', function() { assert.equal(menu.items[4].id, 'letters'); assert.equal(menu.items[5].label, 'a'); assert.equal(menu.items[6].label, 'b'); - return assert.equal(menu.items[7].label, 'c'); + assert.equal(menu.items[7].label, 'c'); }); it('should create separator group if endof does not reference existing separator group', function() { @@ -150,10 +150,10 @@ describe('menu module', function() { assert.equal(menu.items[4].id, 'numbers'); assert.equal(menu.items[5].label, '1'); assert.equal(menu.items[6].label, '2'); - return assert.equal(menu.items[7].label, '3'); + assert.equal(menu.items[7].label, '3'); }); - return it('should continue inserting items at next index when no specifier is present', function() { + it('should continue inserting items at next index when no specifier is present', function() { var menu = Menu.buildFromTemplate([ { label: '4', @@ -177,13 +177,13 @@ describe('menu module', function() { assert.equal(menu.items[1].label, '2'); assert.equal(menu.items[2].label, '3'); assert.equal(menu.items[3].label, '4'); - return assert.equal(menu.items[4].label, '5'); + assert.equal(menu.items[4].label, '5'); }); }); }); describe('Menu.insert', function() { - return it('should store item in @items by its index', function() { + it('should store item in @items by its index', function() { var menu = Menu.buildFromTemplate([ { label: '1' @@ -200,27 +200,27 @@ describe('menu module', function() { assert.equal(menu.items[0].label, '1'); assert.equal(menu.items[1].label, 'inserted'); assert.equal(menu.items[2].label, '2'); - return assert.equal(menu.items[3].label, '3'); + assert.equal(menu.items[3].label, '3'); }); }); describe('MenuItem.click', function() { - return it('should be called with the item object passed', function(done) { + it('should be called with the item object passed', function(done) { var menu = Menu.buildFromTemplate([ { label: 'text', click: function(item) { assert.equal(item.constructor.name, 'MenuItem'); assert.equal(item.label, 'text'); - return done(); + done(); } } ]); - return menu.delegate.executeCommand(menu.items[0].commandId); + menu.delegate.executeCommand(menu.items[0].commandId); }); }); - return describe('MenuItem with checked property', function() { + describe('MenuItem with checked property', function() { it('clicking an checkbox item should flip the checked property', function() { var menu = Menu.buildFromTemplate([ { @@ -230,7 +230,7 @@ describe('menu module', function() { ]); assert.equal(menu.items[0].checked, false); menu.delegate.executeCommand(menu.items[0].commandId); - return assert.equal(menu.items[0].checked, true); + assert.equal(menu.items[0].checked, true); }); it('clicking an radio item should always make checked property true', function() { @@ -243,7 +243,7 @@ describe('menu module', function() { menu.delegate.executeCommand(menu.items[0].commandId); assert.equal(menu.items[0].checked, true); menu.delegate.executeCommand(menu.items[0].commandId); - return assert.equal(menu.items[0].checked, true); + assert.equal(menu.items[0].checked, true); }); it('at least have one item checked in each group', function() { @@ -267,7 +267,7 @@ describe('menu module', function() { menu = Menu.buildFromTemplate(template); menu.delegate.menuWillShow(); assert.equal(menu.items[0].checked, true); - return assert.equal(menu.items[12].checked, true); + assert.equal(menu.items[12].checked, true); }); it('should assign groupId automatically', function() { @@ -293,14 +293,12 @@ describe('menu module', function() { for (i = l = 0; l <= 10; i = ++l) { assert.equal(menu.items[i].groupId, groupId); } - results = []; for (i = m = 12; m <= 20; i = ++m) { - results.push(assert.equal(menu.items[i].groupId, groupId + 1)); + assert.equal(menu.items[i].groupId, groupId + 1); } - return results; }); - return it("setting 'checked' should flip other items' 'checked' property", function() { + it("setting 'checked' should flip other items' 'checked' property", function() { var i, j, k, l, m, menu, n, o, p, q, results, template; template = []; for (i = j = 0; j <= 10; i = ++j) { @@ -341,11 +339,9 @@ describe('menu module', function() { assert.equal(menu.items[i].checked, false); } assert.equal(menu.items[12].checked, true); - results = []; for (i = q = 13; q <= 20; i = ++q) { - results.push(assert.equal(menu.items[i].checked, false)); + assert.equal(menu.items[i].checked, false); } - return results; }); }); }); diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 6426e3312ec..a7de60d8c36 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -14,24 +14,24 @@ describe('protocol module', function() { }; afterEach(function(done) { - return protocol.unregisterProtocol(protocolName, function() { - return protocol.uninterceptProtocol('http', function() { - return done(); + protocol.unregisterProtocol(protocolName, function() { + protocol.uninterceptProtocol('http', function() { + done(); }); }); }); describe('protocol.register(Any)Protocol', function() { var emptyHandler = function(request, callback) { - return callback(); + callback(); }; it('throws error when scheme is already registered', function(done) { - return protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { + protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { assert.equal(error, null); - return protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { + protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { assert.notEqual(error, null); - return done(); + done(); }); }); }); @@ -40,34 +40,34 @@ describe('protocol module', function() { var doubleHandler = function(request, callback) { try { callback(text); - return callback(); + callback(); } catch (error) { // Ignore error } }; - return protocol.registerStringProtocol(protocolName, doubleHandler, function(error) { + protocol.registerStringProtocol(protocolName, doubleHandler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); it('sends error when callback is called with nothing', function(done) { - return protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { + protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { return done('request succeeded but it should not'); @@ -80,24 +80,24 @@ describe('protocol module', function() { }); }); - return it('does not crash when callback is called in next tick', function(done) { + it('does not crash when callback is called in next tick', function(done) { var handler = function(request, callback) { - return setImmediate(function() { - return callback(text); + setImmediate(function() { + callback(text); }); }; - return protocol.registerStringProtocol(protocolName, handler, function(error) { + protocol.registerStringProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -105,10 +105,10 @@ describe('protocol module', function() { }); describe('protocol.unregisterProtocol', function() { - return it('returns error when scheme does not exist', function(done) { - return protocol.unregisterProtocol('not-exist', function(error) { + it('returns error when scheme does not exist', function(done) { + protocol.unregisterProtocol('not-exist', function(error) { assert.notEqual(error, null); - return done(); + done(); }); }); }); @@ -116,9 +116,9 @@ describe('protocol module', function() { describe('protocol.registerStringProtocol', function() { it('sends string as response', function(done) { var handler = function(request, callback) { - return callback(text); + callback(text); }; - return protocol.registerStringProtocol(protocolName, handler, function(error) { + protocol.registerStringProtocol(protocolName, handler, function(error) { if (error) { return done(error); } @@ -126,10 +126,10 @@ describe('protocol module', function() { url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -137,21 +137,21 @@ describe('protocol module', function() { it('sets Access-Control-Allow-Origin', function(done) { var handler = function(request, callback) { - return callback(text); + callback(text); }; - return protocol.registerStringProtocol(protocolName, handler, function(error) { + protocol.registerStringProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data, status, request) { assert.equal(data, text); assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*'); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -159,44 +159,44 @@ describe('protocol module', function() { it('sends object as response', function(done) { var handler = function(request, callback) { - return callback({ + callback({ data: text, mimeType: 'text/html' }); }; - return protocol.registerStringProtocol(protocolName, handler, function(error) { + protocol.registerStringProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); - return it('fails when sending object other than string', function(done) { + it('fails when sending object other than string', function(done) { var handler = function(request, callback) { - return callback(new Date); + callback(new Date); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); @@ -208,20 +208,20 @@ describe('protocol module', function() { it('sends Buffer as response', function(done) { var handler = function(request, callback) { - return callback(buffer); + callback(buffer); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -229,22 +229,22 @@ describe('protocol module', function() { it('sets Access-Control-Allow-Origin', function(done) { var handler = function(request, callback) { - return callback(buffer); + callback(buffer); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data, status, request) { assert.equal(data, text); assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*'); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -252,44 +252,44 @@ describe('protocol module', function() { it('sends object as response', function(done) { var handler = function(request, callback) { - return callback({ + callback({ data: buffer, mimeType: 'text/html' }); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); - return it('fails when sending string', function(done) { + it('fails when sending string', function(done) { var handler = function(request, callback) { - return callback(text); + callback(text); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); @@ -304,9 +304,9 @@ describe('protocol module', function() { it('sends file path as response', function(done) { var handler = function(request, callback) { - return callback(filePath); + callback(filePath); }; - return protocol.registerFileProtocol(protocolName, handler, function(error) { + protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { return done(error); } @@ -327,42 +327,41 @@ describe('protocol module', function() { var handler = function(request, callback) { return callback(filePath); }; - return protocol.registerFileProtocol(protocolName, handler, function(error) { + protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data, status, request) { assert.equal(data, String(fileContent)); assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*'); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); it('sends object as response', function(done) { - var handler; - handler = function(request, callback) { + var handler = function(request, callback) { return callback({ path: filePath }); }; - return protocol.registerFileProtocol(protocolName, handler, function(error) { + protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, String(fileContent)); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -370,21 +369,21 @@ describe('protocol module', function() { it('can send normal file', function(done) { var handler = function(request, callback) { - return callback(normalPath); + callback(normalPath); }; - return protocol.registerFileProtocol(protocolName, handler, function(error) { + protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, String(normalContent)); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -393,41 +392,41 @@ describe('protocol module', function() { it('fails when sending unexist-file', function(done) { var fakeFilePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'not-exist'); var handler = function(request, callback) { - return callback(fakeFilePath); + callback(fakeFilePath); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); }); - return it('fails when sending unsupported content', function(done) { + it('fails when sending unsupported content', function(done) { var handler = function(request, callback) { - return callback(new Date); + callback(new Date); }; - return protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); @@ -439,29 +438,28 @@ describe('protocol module', function() { var server = http.createServer(function(req, res) { assert.notEqual(req.headers.accept, ''); res.end(text); - return server.close(); + server.close(); }); return server.listen(0, '127.0.0.1', function() { - var handler, port, url; - port = server.address().port; - url = "http://127.0.0.1:" + port; - handler = function(request, callback) { - return callback({ + var port = server.address().port; + var url = "http://127.0.0.1:" + port; + var handler = function(request, callback) { + callback({ url: url }); }; - return protocol.registerHttpProtocol(protocolName, handler, function(error) { + protocol.registerHttpProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -470,43 +468,43 @@ describe('protocol module', function() { it('fails when sending invalid url', function(done) { var handler = function(request, callback) { - return callback({ + callback({ url: 'url' }); }; - return protocol.registerHttpProtocol(protocolName, handler, function(error) { + protocol.registerHttpProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); }); - return it('fails when sending unsupported content', function(done) { + it('fails when sending unsupported content', function(done) { var handler = function(request, callback) { - return callback(new Date); + callback(new Date); }; - return protocol.registerHttpProtocol(protocolName, handler, function(error) { + protocol.registerHttpProtocol(protocolName, handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); @@ -515,55 +513,55 @@ describe('protocol module', function() { describe('protocol.isProtocolHandled', function() { it('returns true for file:', function(done) { - return protocol.isProtocolHandled('file', function(result) { + protocol.isProtocolHandled('file', function(result) { assert.equal(result, true); - return done(); + done(); }); }); it('returns true for http:', function(done) { - return protocol.isProtocolHandled('http', function(result) { + protocol.isProtocolHandled('http', function(result) { assert.equal(result, true); - return done(); + done(); }); }); it('returns true for https:', function(done) { - return protocol.isProtocolHandled('https', function(result) { + protocol.isProtocolHandled('https', function(result) { assert.equal(result, true); - return done(); + done(); }); }); it('returns false when scheme is not registred', function(done) { - return protocol.isProtocolHandled('no-exist', function(result) { + protocol.isProtocolHandled('no-exist', function(result) { assert.equal(result, false); - return done(); + done(); }); }); it('returns true for custom protocol', function(done) { var emptyHandler = function(request, callback) { - return callback(); + callback(); }; - return protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { + protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { assert.equal(error, null); - return protocol.isProtocolHandled(protocolName, function(result) { + protocol.isProtocolHandled(protocolName, function(result) { assert.equal(result, true); - return done(); + done(); }); }); }); - return it('returns true for intercepted protocol', function(done) { + it('returns true for intercepted protocol', function(done) { var emptyHandler = function(request, callback) { - return callback(); + callback(); }; - return protocol.interceptStringProtocol('http', emptyHandler, function(error) { + protocol.interceptStringProtocol('http', emptyHandler, function(error) { assert.equal(error, null); - return protocol.isProtocolHandled('http', function(result) { + protocol.isProtocolHandled('http', function(result) { assert.equal(result, true); - return done(); + done(); }); }); }); @@ -571,15 +569,15 @@ describe('protocol module', function() { describe('protocol.intercept(Any)Protocol', function() { var emptyHandler = function(request, callback) { - return callback(); + callback(); }; it('throws error when scheme is already intercepted', function(done) { - return protocol.interceptStringProtocol('http', emptyHandler, function(error) { + protocol.interceptStringProtocol('http', emptyHandler, function(error) { assert.equal(error, null); - return protocol.interceptBufferProtocol('http', emptyHandler, function(error) { + protocol.interceptBufferProtocol('http', emptyHandler, function(error) { assert.notEqual(error, null); - return done(); + done(); }); }); }); @@ -593,39 +591,39 @@ describe('protocol module', function() { // Ignore error } }; - return protocol.interceptStringProtocol('http', doubleHandler, function(error) { + protocol.interceptStringProtocol('http', doubleHandler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: 'http://fake-host', success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); - return it('sends error when callback is called with nothing', function(done) { + it('sends error when callback is called with nothing', function(done) { if (process.env.TRAVIS === 'true') { return done(); } - return protocol.interceptBufferProtocol('http', emptyHandler, function(error) { + protocol.interceptBufferProtocol('http', emptyHandler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: 'http://fake-host', success: function() { - return done('request succeeded but it should not'); + done('request succeeded but it should not'); }, error: function(xhr, errorType) { assert.equal(errorType, 'error'); - return done(); + done(); } }); }); @@ -635,20 +633,20 @@ describe('protocol module', function() { describe('protocol.interceptStringProtocol', function() { it('can intercept http protocol', function(done) { var handler = function(request, callback) { - return callback(text); + callback(text); }; - return protocol.interceptStringProtocol('http', handler, function(error) { + protocol.interceptStringProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: 'http://fake-host', success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -656,51 +654,50 @@ describe('protocol module', function() { it('can set content-type', function(done) { var handler = function(request, callback) { - return callback({ + callback({ mimeType: 'application/json', data: '{"value": 1}' }); }; - return protocol.interceptStringProtocol('http', handler, function(error) { + protocol.interceptStringProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: 'http://fake-host', success: function(data) { assert.equal(typeof data, 'object'); assert.equal(data.value, 1); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); - return it('can receive post data', function(done) { + it('can receive post data', function(done) { var handler = function(request, callback) { - var uploadData; - uploadData = request.uploadData[0].bytes.toString(); - return callback({ + var uploadData = request.uploadData[0].bytes.toString(); + callback({ data: uploadData }); }; - return protocol.interceptStringProtocol('http', handler, function(error) { + protocol.interceptStringProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: "http://fake-host", type: "POST", data: postData, success: function(data) { assert.deepEqual(qs.parse(data), postData); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -710,45 +707,44 @@ describe('protocol module', function() { describe('protocol.interceptBufferProtocol', function() { it('can intercept http protocol', function(done) { var handler = function(request, callback) { - return callback(new Buffer(text)); + callback(new Buffer(text)); }; - return protocol.interceptBufferProtocol('http', handler, function(error) { + protocol.interceptBufferProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: 'http://fake-host', success: function(data) { assert.equal(data, text); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); }); - return it('can receive post data', function(done) { + it('can receive post data', function(done) { var handler = function(request, callback) { - var uploadData; - uploadData = request.uploadData[0].bytes; - return callback(uploadData); + var uploadData = request.uploadData[0].bytes; + callback(uploadData); }; - return protocol.interceptBufferProtocol('http', handler, function(error) { + protocol.interceptBufferProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: "http://fake-host", type: "POST", data: postData, success: function(data) { assert.equal(data, $.param(postData)); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -756,24 +752,22 @@ describe('protocol module', function() { }); describe('protocol.interceptHttpProtocol', function() { - return it('can send POST request', function(done) { + it('can send POST request', function(done) { var server = http.createServer(function(req, res) { - var body; - body = ''; + var body = ''; req.on('data', function(chunk) { - return body += chunk; + body += chunk; }); req.on('end', function() { - return res.end(body); + res.end(body); }); - return server.close(); + server.close(); }); - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port = server.address().port; var url = "http://127.0.0.1:" + port; var handler = function(request, callback) { - var data; - data = { + var data = { url: url, method: 'POST', uploadData: { @@ -782,22 +776,22 @@ describe('protocol module', function() { }, session: null }; - return callback(data); + callback(data); }; - return protocol.interceptHttpProtocol('http', handler, function(error) { + protocol.interceptHttpProtocol('http', handler, function(error) { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: "http://fake-host", type: "POST", data: postData, success: function(data) { assert.deepEqual(qs.parse(data), postData); - return done(); + done(); }, error: function(xhr, errorType, error) { - return done(error); + done(error); } }); }); @@ -805,18 +799,18 @@ describe('protocol module', function() { }); }); - return describe('protocol.uninterceptProtocol', function() { + describe('protocol.uninterceptProtocol', function() { it('returns error when scheme does not exist', function(done) { - return protocol.uninterceptProtocol('not-exist', function(error) { + protocol.uninterceptProtocol('not-exist', function(error) { assert.notEqual(error, null); - return done(); + done(); }); }); - return it('returns error when scheme is not intercepted', function(done) { - return protocol.uninterceptProtocol('http', function(error) { + it('returns error when scheme is not intercepted', function(done) { + protocol.uninterceptProtocol('http', function(error) { assert.notEqual(error, null); - return done(); + done(); }); }); }); diff --git a/spec/api-screen-spec.js b/spec/api-screen-spec.js index 9329c01823d..34828e863e8 100644 --- a/spec/api-screen-spec.js +++ b/spec/api-screen-spec.js @@ -3,19 +3,19 @@ const screen = require('electron').screen; describe('screen module', function() { describe('screen.getCursorScreenPoint()', function() { - return it('returns a point object', function() { + it('returns a point object', function() { var point = screen.getCursorScreenPoint(); assert.equal(typeof point.x, 'number'); - return assert.equal(typeof point.y, 'number'); + assert.equal(typeof point.y, 'number'); }); }); - return describe('screen.getPrimaryDisplay()', function() { - return it('returns a display object', function() { + describe('screen.getPrimaryDisplay()', function() { + it('returns a display object', function() { var display = screen.getPrimaryDisplay(); assert.equal(typeof display.scaleFactor, 'number'); assert(display.size.width > 0); - return assert(display.size.height > 0); + assert(display.size.height > 0); }); }); }); diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index a4421a18ed0..049309eda58 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -18,7 +18,7 @@ describe('session module', function() { var url = "http://127.0.0.1"; beforeEach(function() { - return w = new BrowserWindow({ + w = new BrowserWindow({ show: false, width: 400, height: 400 @@ -26,7 +26,7 @@ describe('session module', function() { }); afterEach(function() { - return w.destroy(); + w.destroy(); }); describe('session.cookies', function() { @@ -35,14 +35,14 @@ describe('session module', function() { server = http.createServer(function(req, res) { res.setHeader('Set-Cookie', ['0=0']); res.end('finished'); - return server.close(); + server.close(); }); - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port; port = server.address().port; w.loadURL(url + ":" + port); - return w.webContents.on('did-finish-load', function() { - return w.webContents.session.cookies.get({ + w.webContents.on('did-finish-load', function() { + w.webContents.session.cookies.get({ url: url }, function(error, list) { var cookie, i, len; @@ -59,14 +59,14 @@ describe('session module', function() { } } } - return done('Can not find cookie'); + done('Can not find cookie'); }); }); }); }); it('should over-write the existent cookie', function(done) { - return session.defaultSession.cookies.set({ + session.defaultSession.cookies.set({ url: url, name: '1', value: '1' @@ -74,7 +74,7 @@ describe('session module', function() { if (error) { return done(error); } - return session.defaultSession.cookies.get({ + session.defaultSession.cookies.get({ url: url }, function(error, list) { var cookie, i, len; @@ -91,13 +91,13 @@ describe('session module', function() { } } } - return done('Can not find cookie'); + done('Can not find cookie'); }); }); }); it('should remove cookies', function(done) { - return session.defaultSession.cookies.set({ + session.defaultSession.cookies.set({ url: url, name: '2', value: '2' @@ -105,8 +105,8 @@ describe('session module', function() { if (error) { return done(error); } - return session.defaultSession.cookies.remove(url, '2', function() { - return session.defaultSession.cookies.get({ + session.defaultSession.cookies.remove(url, '2', function() { + session.defaultSession.cookies.get({ url: url }, function(error, list) { var cookie, i, len; @@ -119,7 +119,7 @@ describe('session module', function() { return done('Cookie not deleted'); } } - return done(); + done(); }); }); }); @@ -128,22 +128,22 @@ describe('session module', function() { describe('session.clearStorageData(options)', function() { fixtures = path.resolve(__dirname, 'fixtures'); - return it('clears localstorage data', function(done) { + it('clears localstorage data', function(done) { ipcMain.on('count', function(event, count) { ipcMain.removeAllListeners('count'); assert(!count); - return done(); + done(); }); w.loadURL('file://' + path.join(fixtures, 'api', 'localstorage.html')); - return w.webContents.on('did-finish-load', function() { + w.webContents.on('did-finish-load', function() { var options; options = { origin: "file://", storages: ['localstorage'], quotas: ['persistent'] }; - return w.webContents.session.clearStorageData(options, function() { - return w.webContents.send('getcount'); + w.webContents.session.clearStorageData(options, function() { + w.webContents.send('getcount'); }); }); }); @@ -161,7 +161,7 @@ describe('session module', function() { }); afterEach(function() { - return w.destroy(); + w.destroy(); }); it('can cancel default download behavior', function(done) { @@ -193,21 +193,20 @@ describe('session module', function() { }); }); - return describe('DownloadItem', function() { - var assertDownload, contentDisposition, downloadFilePath, downloadServer, mockPDF; - mockPDF = new Buffer(1024 * 1024 * 5); - contentDisposition = 'inline; filename="mock.pdf"'; - downloadFilePath = path.join(fixtures, 'mock.pdf'); - downloadServer = http.createServer(function(req, res) { + describe('DownloadItem', function() { + var mockPDF = new Buffer(1024 * 1024 * 5); + var contentDisposition = 'inline; filename="mock.pdf"'; + var downloadFilePath = path.join(fixtures, 'mock.pdf'); + var downloadServer = http.createServer(function(req, res) { res.writeHead(200, { 'Content-Length': mockPDF.length, 'Content-Type': 'application/pdf', 'Content-Disposition': contentDisposition }); res.end(mockPDF); - return downloadServer.close(); + downloadServer.close(); }); - assertDownload = function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port) { + var assertDownload = function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port) { assert.equal(state, 'completed'); assert.equal(filename, 'mock.pdf'); assert.equal(url, "http://127.0.0.1:" + port + "/"); @@ -216,55 +215,52 @@ describe('session module', function() { assert.equal(totalBytes, mockPDF.length); assert.equal(disposition, contentDisposition); assert(fs.existsSync(downloadFilePath)); - return fs.unlinkSync(downloadFilePath); + fs.unlinkSync(downloadFilePath); }; it('can download using BrowserWindow.loadURL', function(done) { - return downloadServer.listen(0, '127.0.0.1', function() { - var port; - port = downloadServer.address().port; + downloadServer.listen(0, '127.0.0.1', function() { + var port = downloadServer.address().port; ipcRenderer.sendSync('set-download-option', false, false); w.loadURL(url + ":" + port); - return ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { + ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { assertDownload(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port); - return done(); + done(); }); }); }); it('can download using WebView.downloadURL', function(done) { - return downloadServer.listen(0, '127.0.0.1', function() { - var port, webview; - port = downloadServer.address().port; + downloadServer.listen(0, '127.0.0.1', function() { + var port = downloadServer.address().port; ipcRenderer.sendSync('set-download-option', false, false); - webview = new WebView; + var webview = new WebView; webview.src = "file://" + fixtures + "/api/blank.html"; webview.addEventListener('did-finish-load', function() { - return webview.downloadURL(url + ":" + port + "/"); + webview.downloadURL(url + ":" + port + "/"); }); ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { assertDownload(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port); document.body.removeChild(webview); - return done(); + done(); }); - return document.body.appendChild(webview); + document.body.appendChild(webview); }); }); it('can cancel download', function(done) { - return downloadServer.listen(0, '127.0.0.1', function() { - var port; - port = downloadServer.address().port; + downloadServer.listen(0, '127.0.0.1', function() { + var port = downloadServer.address().port; ipcRenderer.sendSync('set-download-option', true, false); w.loadURL(url + ":" + port + "/"); - return ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { + ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { assert.equal(state, 'cancelled'); assert.equal(filename, 'mock.pdf'); assert.equal(mimeType, 'application/pdf'); assert.equal(receivedBytes, 0); assert.equal(totalBytes, mockPDF.length); assert.equal(disposition, contentDisposition); - return done(); + done(); }); }); }); diff --git a/spec/api-web-frame-spec.js b/spec/api-web-frame-spec.js index 1a3eca6d584..15f31aa8f09 100644 --- a/spec/api-web-frame-spec.js +++ b/spec/api-web-frame-spec.js @@ -4,15 +4,15 @@ const webFrame = require('electron').webFrame; describe('webFrame module', function() { var fixtures = path.resolve(__dirname, 'fixtures'); - return describe('webFrame.registerURLSchemeAsPrivileged', function() { - return it('supports fetch api', function(done) { + describe('webFrame.registerURLSchemeAsPrivileged', function() { + it('supports fetch api', function(done) { webFrame.registerURLSchemeAsPrivileged('file'); var url = "file://" + fixtures + "/assets/logo.png"; - return fetch(url).then(function(response) { + fetch(url).then(function(response) { assert(response.ok); - return done(); - })["catch"](function(err) { - return done('unexpected error : ' + err); + done(); + }).catch(function(err) { + done('unexpected error : ' + err); }); }); }); diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index e2a3a1ca38f..f64c91b610c 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -13,41 +13,41 @@ describe('webRequest module', function() { if (req.headers.accept === '*/*;test/header') { content += 'header/received'; } - return res.end(content); + res.end(content); }); var defaultURL = null; before(function(done) { - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port; port = server.address().port; defaultURL = "http://127.0.0.1:" + port + "/"; - return done(); + done(); }); }); after(function() { - return server.close(); + server.close(); }); describe('webRequest.onBeforeRequest', function() { afterEach(function() { - return ses.webRequest.onBeforeRequest(null); + ses.webRequest.onBeforeRequest(null); }); it('can cancel the request', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { - return callback({ + callback({ cancel: true }); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function() { - return done('unexpected success'); + done('unexpected success'); }, error: function() { - return done(); + done(); } }); }); @@ -57,26 +57,26 @@ describe('webRequest module', function() { urls: [defaultURL + "filter/*"] }; ses.webRequest.onBeforeRequest(filter, function(details, callback) { - return callback({ + callback({ cancel: true }); }); - return $.ajax({ + $.ajax({ url: defaultURL + "nofilter/test", success: function(data) { assert.equal(data, '/nofilter/test'); - return $.ajax({ + $.ajax({ url: defaultURL + "filter/test", success: function() { - return done('unexpected success'); + done('unexpected success'); }, error: function() { - return done(); + done(); } }); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -89,16 +89,16 @@ describe('webRequest module', function() { assert.equal(details.method, 'GET'); assert.equal(details.resourceType, 'xhr'); assert(!details.uploadData); - return callback({}); + callback({}); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -115,11 +115,11 @@ describe('webRequest module', function() { assert.equal(details.uploadData.length, 1); data = qs.parse(details.uploadData[0].bytes.toString()); assert.deepEqual(data, postData); - return callback({ + callback({ cancel: true }); }); - return $.ajax({ + $.ajax({ url: defaultURL, type: 'POST', data: postData, @@ -131,24 +131,24 @@ describe('webRequest module', function() { }); }); - return it('can redirect the request', function(done) { + it('can redirect the request', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { if (details.url === defaultURL) { - return callback({ + callback({ redirectURL: defaultURL + "redirect" }); } else { - return callback({}); + callback({}); } }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/redirect'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -156,22 +156,22 @@ describe('webRequest module', function() { describe('webRequest.onBeforeSendHeaders', function() { afterEach(function() { - return ses.webRequest.onBeforeSendHeaders(null); + ses.webRequest.onBeforeSendHeaders(null); }); it('receives details object', function(done) { ses.webRequest.onBeforeSendHeaders(function(details, callback) { assert.equal(typeof details.requestHeaders, 'object'); - return callback({}); + callback({}); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -181,40 +181,39 @@ describe('webRequest module', function() { var requestHeaders; requestHeaders = details.requestHeaders; requestHeaders.Accept = '*/*;test/header'; - return callback({ + callback({ requestHeaders: requestHeaders }); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/header/received'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); - return it('resets the whole headers', function(done) { - var requestHeaders; - requestHeaders = { + it('resets the whole headers', function(done) { + var requestHeaders = { Test: 'header' }; ses.webRequest.onBeforeSendHeaders(function(details, callback) { - return callback({ + callback({ requestHeaders: requestHeaders }); }); ses.webRequest.onSendHeaders(function(details) { assert.deepEqual(details.requestHeaders, requestHeaders); - return done(); + done(); }); - return $.ajax({ + $.ajax({ url: defaultURL, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -222,21 +221,21 @@ describe('webRequest module', function() { describe('webRequest.onSendHeaders', function() { afterEach(function() { - return ses.webRequest.onSendHeaders(null); + ses.webRequest.onSendHeaders(null); }); - return it('receives details object', function(done) { + it('receives details object', function(done) { ses.webRequest.onSendHeaders(function(details) { - return assert.equal(typeof details.requestHeaders, 'object'); + assert.equal(typeof details.requestHeaders, 'object'); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -244,7 +243,7 @@ describe('webRequest module', function() { describe('webRequest.onHeadersReceived', function() { afterEach(function() { - return ses.webRequest.onHeadersReceived(null); + ses.webRequest.onHeadersReceived(null); }); it('receives details object', function(done) { @@ -252,55 +251,54 @@ describe('webRequest module', function() { assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); assert.equal(details.statusCode, 200); assert.equal(details.responseHeaders['Custom'], 'Header'); - return callback({}); + callback({}); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); it('can change the response header', function(done) { ses.webRequest.onHeadersReceived(function(details, callback) { - var responseHeaders; - responseHeaders = details.responseHeaders; + var responseHeaders = details.responseHeaders; responseHeaders['Custom'] = ['Changed']; - return callback({ + callback({ responseHeaders: responseHeaders }); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data, status, xhr) { assert.equal(xhr.getResponseHeader('Custom'), 'Changed'); assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); - return it('does not change header by default', function(done) { + it('does not change header by default', function(done) { ses.webRequest.onHeadersReceived(function(details, callback) { - return callback({}); + callback({}); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data, status, xhr) { assert.equal(xhr.getResponseHeader('Custom'), 'Header'); assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -308,25 +306,25 @@ describe('webRequest module', function() { describe('webRequest.onResponseStarted', function() { afterEach(function() { - return ses.webRequest.onResponseStarted(null); + ses.webRequest.onResponseStarted(null); }); - return it('receives details object', function(done) { + it('receives details object', function(done) { ses.webRequest.onResponseStarted(function(details) { assert.equal(typeof details.fromCache, 'boolean'); assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); assert.equal(details.statusCode, 200); - return assert.equal(details.responseHeaders['Custom'], 'Header'); + assert.equal(details.responseHeaders['Custom'], 'Header'); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data, status, xhr) { assert.equal(xhr.getResponseHeader('Custom'), 'Header'); assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -335,35 +333,34 @@ describe('webRequest module', function() { describe('webRequest.onBeforeRedirect', function() { afterEach(function() { ses.webRequest.onBeforeRedirect(null); - return ses.webRequest.onBeforeRequest(null); + ses.webRequest.onBeforeRequest(null); }); - return it('receives details object', function(done) { - var redirectURL; - redirectURL = defaultURL + "redirect"; + it('receives details object', function(done) { + var redirectURL = defaultURL + "redirect"; ses.webRequest.onBeforeRequest(function(details, callback) { if (details.url === defaultURL) { - return callback({ + callback({ redirectURL: redirectURL }); } else { - return callback({}); + callback({}); } }); ses.webRequest.onBeforeRedirect(function(details) { assert.equal(typeof details.fromCache, 'boolean'); assert.equal(details.statusLine, 'HTTP/1.1 307 Internal Redirect'); assert.equal(details.statusCode, 307); - return assert.equal(details.redirectURL, redirectURL); + assert.equal(details.redirectURL, redirectURL); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/redirect'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); @@ -371,48 +368,48 @@ describe('webRequest module', function() { describe('webRequest.onCompleted', function() { afterEach(function() { - return ses.webRequest.onCompleted(null); + ses.webRequest.onCompleted(null); }); - return it('receives details object', function(done) { + it('receives details object', function(done) { ses.webRequest.onCompleted(function(details) { assert.equal(typeof details.fromCache, 'boolean'); assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); - return assert.equal(details.statusCode, 200); + assert.equal(details.statusCode, 200); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function(data) { assert.equal(data, '/'); - return done(); + done(); }, error: function(xhr, errorType) { - return done(errorType); + done(errorType); } }); }); }); - return describe('webRequest.onErrorOccurred', function() { + describe('webRequest.onErrorOccurred', function() { afterEach(function() { ses.webRequest.onErrorOccurred(null); - return ses.webRequest.onBeforeRequest(null); + ses.webRequest.onBeforeRequest(null); }); - return it('receives details object', function(done) { + it('receives details object', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { - return callback({ + callback({ cancel: true }); }); ses.webRequest.onErrorOccurred(function(details) { assert.equal(details.error, 'net::ERR_BLOCKED_BY_CLIENT'); - return done(); + done(); }); - return $.ajax({ + $.ajax({ url: defaultURL, success: function() { - return done('unexpected success'); + done('unexpected success'); } }); }); diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 064212e7c7e..d35cf186c65 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -23,121 +23,108 @@ describe('asar package', function() { }); it('reads a normal file', function() { - var file1, file2, file3; - file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); assert.equal(fs.readFileSync(file1).toString().trim(), 'file1'); - file2 = path.join(fixtures, 'asar', 'a.asar', 'file2'); + var file2 = path.join(fixtures, 'asar', 'a.asar', 'file2'); assert.equal(fs.readFileSync(file2).toString().trim(), 'file2'); - file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); - return assert.equal(fs.readFileSync(file3).toString().trim(), 'file3'); + var file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); + assert.equal(fs.readFileSync(file3).toString().trim(), 'file3'); }); it('reads from a empty file', function() { - var buffer, file; - file = path.join(fixtures, 'asar', 'empty.asar', 'file1'); - buffer = fs.readFileSync(file); + var file = path.join(fixtures, 'asar', 'empty.asar', 'file1'); + var buffer = fs.readFileSync(file); assert.equal(buffer.length, 0); - return assert.equal(buffer.toString(), ''); + assert.equal(buffer.toString(), ''); }); it('reads a linked file', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link1'); - return assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'link1'); + assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); }); it('reads a file from linked directory', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1'); assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); - return assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); + assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); }); it('throws ENOENT error when can not find file', function() { - var p, throws; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - throws = function() { - return fs.readFileSync(p); + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var throws = function() { + fs.readFileSync(p); }; - return assert.throws(throws, /ENOENT/); + assert.throws(throws, /ENOENT/); }); it('passes ENOENT error to callback when can not find file', function() { - var async, p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - async = false; + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + var async = false; fs.readFile(p, function(e) { assert(async); - return assert(/ENOENT/.test(e)); + assert(/ENOENT/.test(e)); }); - return async = true; + async = true; }); - return it('reads a normal file with unpacked files', function() { - var p; - p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); - return assert.equal(fs.readFileSync(p).toString().trim(), 'a'); + it('reads a normal file with unpacked files', function() { + var p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); + assert.equal(fs.readFileSync(p).toString().trim(), 'a'); }); }); describe('fs.readFile', function() { it('reads a normal file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'file1'); - return fs.readFile(p, function(err, content) { + var p = path.join(fixtures, 'asar', 'a.asar', 'file1'); + fs.readFile(p, function(err, content) { assert.equal(err, null); assert.equal(String(content).trim(), 'file1'); - return done(); + done(); }); }); it('reads from a empty file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'empty.asar', 'file1'); - return fs.readFile(p, function(err, content) { + var p = path.join(fixtures, 'asar', 'empty.asar', 'file1'); + fs.readFile(p, function(err, content) { assert.equal(err, null); assert.equal(String(content), ''); - return done(); + done(); }); }); it('reads a linked file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link1'); - return fs.readFile(p, function(err, content) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link1'); + fs.readFile(p, function(err, content) { assert.equal(err, null); assert.equal(String(content).trim(), 'file1'); - return done(); + done(); }); }); it('reads a file from linked directory', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); - return fs.readFile(p, function(err, content) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); + fs.readFile(p, function(err, content) { assert.equal(err, null); assert.equal(String(content).trim(), 'file1'); - return done(); + done(); }); }); - return it('throws ENOENT error when can not find file', function(done) { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return fs.readFile(p, function(err) { + it('throws ENOENT error when can not find file', function(done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + fs.readFile(p, function(err) { assert.equal(err.code, 'ENOENT'); - return done(); + done(); }); }); }); describe('fs.lstatSync', function() { it('handles path with trailing slash correctly', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); fs.lstatSync(p); - return fs.lstatSync(p + '/'); + fs.lstatSync(p + '/'); }); it('returns information of root', function() { @@ -147,7 +134,7 @@ describe('asar package', function() { assert.equal(stats.isFile(), false); assert.equal(stats.isDirectory(), true); assert.equal(stats.isSymbolicLink(), false); - return assert.equal(stats.size, 0); + assert.equal(stats.size, 0); }); it('returns information of a normal file', function() { @@ -163,7 +150,7 @@ describe('asar package', function() { assert.equal(stats.isSymbolicLink(), false); results.push(assert.equal(stats.size, 6)); } - return results; + results; }); it('returns information of a normal directory', function() { @@ -179,7 +166,7 @@ describe('asar package', function() { assert.equal(stats.isSymbolicLink(), false); results.push(assert.equal(stats.size, 0)); } - return results; + results; }); it('returns information of a linked file', function() { @@ -195,7 +182,7 @@ describe('asar package', function() { assert.equal(stats.isSymbolicLink(), true); results.push(assert.equal(stats.size, 0)); } - return results; + results; }); it('returns information of a linked directory', function() { @@ -211,29 +198,27 @@ describe('asar package', function() { assert.equal(stats.isSymbolicLink(), true); results.push(assert.equal(stats.size, 0)); } - return results; + results; }); - return it('throws ENOENT error when can not find file', function() { - var file, j, len, p, ref2, results, throws; + it('throws ENOENT error when can not find file', function() { + var file, j, len, p, ref2, throws; ref2 = ['file4', 'file5', path.join('dir1', 'file4')]; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); throws = function() { - return fs.lstatSync(p); + fs.lstatSync(p); }; - results.push(assert.throws(throws, /ENOENT/)); + assert.throws(throws, /ENOENT/); } - return results; }); }); describe('fs.lstat', function() { it('handles path with trailing slash correctly', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); - return fs.lstat(p + '/', done); + fs.lstat(p + '/', done); }); it('returns information of root', function(done) { @@ -244,7 +229,7 @@ describe('asar package', function() { assert.equal(stats.isDirectory(), true); assert.equal(stats.isSymbolicLink(), false); assert.equal(stats.size, 0); - return done(); + done(); }); }); @@ -256,7 +241,7 @@ describe('asar package', function() { assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), false); assert.equal(stats.size, 6); - return done(); + done(); }); }); @@ -268,7 +253,7 @@ describe('asar package', function() { assert.equal(stats.isDirectory(), true); assert.equal(stats.isSymbolicLink(), false); assert.equal(stats.size, 0); - return done(); + done(); }); }); @@ -280,7 +265,7 @@ describe('asar package', function() { assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), true); assert.equal(stats.size, 0); - return done(); + done(); }); }); @@ -292,15 +277,15 @@ describe('asar package', function() { assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), true); assert.equal(stats.size, 0); - return done(); + done(); }); }); - return it('throws ENOENT error when can not find file', function(done) { + it('throws ENOENT error when can not find file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'file4'); fs.lstat(p, function(err) { assert.equal(err.code, 'ENOENT'); - return done(); + done(); }); }); }); @@ -310,44 +295,44 @@ describe('asar package', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = 'a.asar'; var r = fs.realpathSync(path.join(parent, p)); - return assert.equal(r, path.join(parent, p)); + assert.equal(r, path.join(parent, p)); }); it('returns real path of a normal file', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'file1'); var r = fs.realpathSync(path.join(parent, p)); - return assert.equal(r, path.join(parent, p)); + assert.equal(r, path.join(parent, p)); }); it('returns real path of a normal directory', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'dir1'); var r = fs.realpathSync(path.join(parent, p)); - return assert.equal(r, path.join(parent, p)); + assert.equal(r, path.join(parent, p)); }); it('returns real path of a linked file', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'link2', 'link1'); var r = fs.realpathSync(path.join(parent, p)); - return assert.equal(r, path.join(parent, 'a.asar', 'file1')); + assert.equal(r, path.join(parent, 'a.asar', 'file1')); }); it('returns real path of a linked directory', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'link2', 'link2'); var r = fs.realpathSync(path.join(parent, p)); - return assert.equal(r, path.join(parent, 'a.asar', 'dir1')); + assert.equal(r, path.join(parent, 'a.asar', 'dir1')); }); - return it('throws ENOENT error when can not find file', function() { + it('throws ENOENT error when can not find file', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'not-exist'); var throws = function() { - return fs.realpathSync(path.join(parent, p)); + fs.realpathSync(path.join(parent, p)); }; - return assert.throws(throws, /ENOENT/); + assert.throws(throws, /ENOENT/); }); }); @@ -355,58 +340,58 @@ describe('asar package', function() { it('returns real path root', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = 'a.asar'; - return fs.realpath(path.join(parent, p), function(err, r) { + fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); - return done(); + done(); }); }); it('returns real path of a normal file', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'file1'); - return fs.realpath(path.join(parent, p), function(err, r) { + fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); - return done(); + done(); }); }); it('returns real path of a normal directory', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'dir1'); - return fs.realpath(path.join(parent, p), function(err, r) { + fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, p)); - return done(); + done(); }); }); it('returns real path of a linked file', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'link2', 'link1'); - return fs.realpath(path.join(parent, p), function(err, r) { + fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, 'a.asar', 'file1')); - return done(); + done(); }); }); it('returns real path of a linked directory', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'link2', 'link2'); - return fs.realpath(path.join(parent, p), function(err, r) { + fs.realpath(path.join(parent, p), function(err, r) { assert.equal(err, null); assert.equal(r, path.join(parent, 'a.asar', 'dir1')); - return done(); + done(); }); }); - return it('throws ENOENT error when can not find file', function(done) { + it('throws ENOENT error when can not find file', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'not-exist'); - return fs.realpath(path.join(parent, p), function(err) { + fs.realpath(path.join(parent, p), function(err) { assert.equal(err.code, 'ENOENT'); - return done(); + done(); }); }); }); @@ -414,27 +399,27 @@ describe('asar package', function() { it('reads dirs from root', function() { var p = path.join(fixtures, 'asar', 'a.asar'); var dirs = fs.readdirSync(p); - return assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); + assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); }); it('reads dirs from a normal dir', function() { var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); var dirs = fs.readdirSync(p); - return assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); + assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); }); it('reads dirs from a linked dir', function() { var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); var dirs = fs.readdirSync(p); - return assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); + assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); }); - return it('throws ENOENT error when can not find file', function() { + it('throws ENOENT error when can not find file', function() { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); var throws = function() { - return fs.readdirSync(p); + fs.readdirSync(p); }; - return assert.throws(throws, /ENOENT/); + assert.throws(throws, /ENOENT/); }); }); @@ -444,7 +429,7 @@ describe('asar package', function() { fs.readdir(p, function(err, dirs) { assert.equal(err, null); assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); - return done(); + done(); }); }); @@ -453,7 +438,7 @@ describe('asar package', function() { fs.readdir(p, function(err, dirs) { assert.equal(err, null); assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); - return done(); + done(); }); }); it('reads dirs from a linked dir', function(done) { @@ -461,15 +446,15 @@ describe('asar package', function() { fs.readdir(p, function(err, dirs) { assert.equal(err, null); assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); - return done(); + done(); }); }); - return it('throws ENOENT error when can not find file', function(done) { + it('throws ENOENT error when can not find file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return fs.readdir(p, function(err) { + fs.readdir(p, function(err) { assert.equal(err.code, 'ENOENT'); - return done(); + done(); }); }); }); @@ -478,7 +463,6 @@ describe('asar package', function() { it('opens a normal/linked/under-linked-directory file', function() { var buffer, fd, file, j, len, p, ref2, results; ref2 = ['file1', 'link1', path.join('link2', 'file1')]; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); @@ -486,59 +470,57 @@ describe('asar package', function() { buffer = new Buffer(6); fs.readSync(fd, buffer, 0, 6, 0); assert.equal(String(buffer).trim(), 'file1'); - results.push(fs.closeSync(fd)); + fs.closeSync(fd); } - return results; }); - return it('throws ENOENT error when can not find file', function() { + it('throws ENOENT error when can not find file', function() { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); var throws = function() { - return fs.openSync(p); + fs.openSync(p); }; - return assert.throws(throws, /ENOENT/); + assert.throws(throws, /ENOENT/); }); }); describe('fs.open', function() { it('opens a normal file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'file1'); - return fs.open(p, 'r', function(err, fd) { - var buffer; + fs.open(p, 'r', function(err, fd) { assert.equal(err, null); - buffer = new Buffer(6); - return fs.read(fd, buffer, 0, 6, 0, function(err) { + var buffer = new Buffer(6); + fs.read(fd, buffer, 0, 6, 0, function(err) { assert.equal(err, null); assert.equal(String(buffer).trim(), 'file1'); - return fs.close(fd, done); + fs.close(fd, done); }); }); }); - return it('throws ENOENT error when can not find file', function(done) { + it('throws ENOENT error when can not find file', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return fs.open(p, 'r', function(err) { + fs.open(p, 'r', function(err) { assert.equal(err.code, 'ENOENT'); - return done(); + done(); }); }); }); describe('fs.mkdir', function() { - return it('throws error when calling inside asar archive', function(done) { + it('throws error when calling inside asar archive', function(done) { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return fs.mkdir(p, function(err) { + fs.mkdir(p, function(err) { assert.equal(err.code, 'ENOTDIR'); - return done(); + done(); }); }); }); describe('fs.mkdirSync', function() { - return it('throws error when calling inside asar archive', function() { + it('throws error when calling inside asar archive', function() { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return assert.throws((function() { - return fs.mkdirSync(p); + assert.throws((function() { + fs.mkdirSync(p); }), new RegExp('ENOTDIR')); }); }); @@ -548,19 +530,19 @@ describe('asar package', function() { var child = child_process.fork(path.join(fixtures, 'asar', 'a.asar', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); - return it('supports asar in the forked js', function(done) { + it('supports asar in the forked js', function(done) { var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); var child = child_process.fork(path.join(fixtures, 'module', 'asar.js')); child.on('message', function(content) { assert.equal(content, fs.readFileSync(file).toString()); - return done(); + done(); }); - return child.send(file); + child.send(file); }); }); @@ -576,14 +558,13 @@ describe('asar package', function() { execFile(echo, ['test'], function(error, stdout) { assert.equal(error, null); assert.equal(stdout, 'test\n'); - return done(); + done(); }); }); - return xit('execFileSync executes binaries', function() { - var output; - output = execFileSync(echo, ['test']); - return assert.equal(String(output), 'test\n'); + xit('execFileSync executes binaries', function() { + var output = execFileSync(echo, ['test']); + assert.equal(String(output), 'test\n'); }); }); @@ -591,47 +572,45 @@ describe('asar package', function() { var internalModuleReadFile = process.binding('fs').internalModuleReadFile; it('read a normal file', function() { - var file1, file2, file3; - file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); assert.equal(internalModuleReadFile(file1).toString().trim(), 'file1'); - file2 = path.join(fixtures, 'asar', 'a.asar', 'file2'); + var file2 = path.join(fixtures, 'asar', 'a.asar', 'file2'); assert.equal(internalModuleReadFile(file2).toString().trim(), 'file2'); - file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); - return assert.equal(internalModuleReadFile(file3).toString().trim(), 'file3'); + var file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); + assert.equal(internalModuleReadFile(file3).toString().trim(), 'file3'); }); - return it('reads a normal file with unpacked files', function() { - var p; - p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); - return assert.equal(internalModuleReadFile(p).toString().trim(), 'a'); + it('reads a normal file with unpacked files', function() { + var p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); + assert.equal(internalModuleReadFile(p).toString().trim(), 'a'); }); }); - return describe('process.noAsar', function() { + describe('process.noAsar', function() { var errorName = process.platform === 'win32' ? 'ENOENT' : 'ENOTDIR'; beforeEach(function() { - return process.noAsar = true; + process.noAsar = true; }); afterEach(function() { - return process.noAsar = false; + process.noAsar = false; }); it('disables asar support in sync API', function() { var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); assert.throws((function() { - return fs.readFileSync(file); + fs.readFileSync(file); }), new RegExp(errorName)); assert.throws((function() { - return fs.lstatSync(file); + fs.lstatSync(file); }), new RegExp(errorName)); assert.throws((function() { - return fs.realpathSync(file); + fs.realpathSync(file); }), new RegExp(errorName)); - return assert.throws((function() { - return fs.readdirSync(dir); + assert.throws((function() { + fs.readdirSync(dir); }), new RegExp(errorName)); }); @@ -639,30 +618,29 @@ describe('asar package', function() { var dir, file; file = path.join(fixtures, 'asar', 'a.asar', 'file1'); dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); - return fs.readFile(file, function(error) { + fs.readFile(file, function(error) { assert.equal(error.code, errorName); - return fs.lstat(file, function(error) { + fs.lstat(file, function(error) { assert.equal(error.code, errorName); - return fs.realpath(file, function(error) { + fs.realpath(file, function(error) { assert.equal(error.code, errorName); - return fs.readdir(dir, function(error) { + fs.readdir(dir, function(error) { assert.equal(error.code, errorName); - return done(); + done(); }); }); }); }); }); - return it('treats *.asar as normal file', function() { - var asar, content1, content2, originalFs; - originalFs = require('original-fs'); - asar = path.join(fixtures, 'asar', 'a.asar'); - content1 = fs.readFileSync(asar); - content2 = originalFs.readFileSync(asar); + it('treats *.asar as normal file', function() { + var originalFs = require('original-fs'); + var asar = path.join(fixtures, 'asar', 'a.asar'); + var content1 = fs.readFileSync(asar); + var content2 = originalFs.readFileSync(asar); assert.equal(content1.compare(content2), 0); - return assert.throws((function() { - return fs.readdirSync(asar); + assert.throws((function() { + fs.readdirSync(asar); }), /ENOTDIR/); }); }); @@ -673,43 +651,43 @@ describe('asar package', function() { it('can request a file in package', function(done) { var p = path.resolve(fixtures, 'asar', 'a.asar', 'file1'); - return $.get("file://" + p, function(data) { + $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file1'); - return done(); + done(); }); }); it('can request a file in package with unpacked files', function(done) { var p = path.resolve(fixtures, 'asar', 'unpack.asar', 'a.txt'); - return $.get("file://" + p, function(data) { + $.get("file://" + p, function(data) { assert.equal(data.trim(), 'a'); - return done(); + done(); }); }); it('can request a linked file in package', function(done) { var p = path.resolve(fixtures, 'asar', 'a.asar', 'link2', 'link1'); - return $.get("file://" + p, function(data) { + $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file1'); - return done(); + done(); }); }); it('can request a file in filesystem', function(done) { var p = path.resolve(fixtures, 'asar', 'file'); - return $.get("file://" + p, function(data) { + $.get("file://" + p, function(data) { assert.equal(data.trim(), 'file'); - return done(); + done(); }); }); it('gets 404 when file is not found', function(done) { var p = path.resolve(fixtures, 'asar', 'a.asar', 'no-exist'); - return $.ajax({ + $.ajax({ url: "file://" + p, error: function(err) { assert.equal(err.status, 404); - return done(); + done(); } }); }); @@ -717,7 +695,7 @@ describe('asar package', function() { it('sets __dirname correctly', function(done) { after(function() { w.destroy(); - return ipcMain.removeAllListeners('dirname'); + ipcMain.removeAllListeners('dirname'); }); var w = new BrowserWindow({ @@ -733,15 +711,15 @@ describe('asar package', function() { }); ipcMain.once('dirname', function(event, dirname) { assert.equal(dirname, path.dirname(p)); - return done(); + done(); }); - return w.loadURL(u); + w.loadURL(u); }); - return it('loads script tag in html', function(done) { + it('loads script tag in html', function(done) { after(function() { w.destroy(); - return ipcMain.removeAllListeners('ping'); + ipcMain.removeAllListeners('ping'); }); var w = new BrowserWindow({ @@ -756,9 +734,9 @@ describe('asar package', function() { pathname: p }); w.loadURL(u); - return ipcMain.once('ping', function(event, message) { + ipcMain.once('ping', function(event, message) { assert.equal(message, 'pong'); - return done(); + done(); }); }); }); @@ -770,17 +748,17 @@ describe('asar package', function() { var file, stats; file = path.join(fixtures, 'asar', 'a.asar'); stats = originalFs.statSync(file); - return assert(stats.isFile()); + assert(stats.isFile()); }); - return it('is available in forked scripts', function(done) { + it('is available in forked scripts', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'original-fs.js')); child.on('message', function(msg) { assert.equal(msg, 'object'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); }); @@ -788,41 +766,39 @@ describe('asar package', function() { var gfs = require('graceful-fs'); it('recognize asar archvies', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'link1'); - return assert.equal(gfs.readFileSync(p).toString().trim(), 'file1'); + var p = path.join(fixtures, 'asar', 'a.asar', 'link1'); + assert.equal(gfs.readFileSync(p).toString().trim(), 'file1'); }); - return it('does not touch global fs object', function() { - return assert.notEqual(fs.readdir, gfs.readdir); + it('does not touch global fs object', function() { + assert.notEqual(fs.readdir, gfs.readdir); }); }); describe('mkdirp module', function() { var mkdirp = require('mkdirp'); - return it('throws error when calling inside asar archive', function() { - var p; - p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - return assert.throws((function() { - return mkdirp.sync(p); + it('throws error when calling inside asar archive', function() { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); + assert.throws((function() { + mkdirp.sync(p); }), new RegExp('ENOTDIR')); }); }); - return describe('native-image', function() { + describe('native-image', function() { it('reads image from asar archive', function() { var p = path.join(fixtures, 'asar', 'logo.asar', 'logo.png'); var logo = nativeImage.createFromPath(p); - return assert.deepEqual(logo.getSize(), { + assert.deepEqual(logo.getSize(), { width: 55, height: 55 }); }); - return it('reads image from asar archive with unpacked files', function() { + it('reads image from asar archive with unpacked files', function() { var p = path.join(fixtures, 'asar', 'unpack.asar', 'atom.png'); var logo = nativeImage.createFromPath(p); - return assert.deepEqual(logo.getSize(), { + assert.deepEqual(logo.getSize(), { width: 1024, height: 1024 }); diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 21cefb0b0bc..9efe22a263c 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -15,28 +15,27 @@ describe('chromium feature', function() { if (listener != null) { window.removeEventListener('message', listener); } - return listener = null; + listener = null; }); xdescribe('heap snapshot', function() { - return it('does not crash', function() { - return process.atomBinding('v8_util').takeHeapSnapshot(); + it('does not crash', function() { + process.atomBinding('v8_util').takeHeapSnapshot(); }); }); describe('sending request of http protocol urls', function() { - return it('does not crash', function(done) { - var server; + it('does not crash', function(done) { this.timeout(5000); - server = http.createServer(function(req, res) { + + var server = http.createServer(function(req, res) { res.end(); server.close(); - return done(); + done(); }); - return server.listen(0, '127.0.0.1', function() { - var port; - port = server.address().port; - return $.get("http://127.0.0.1:" + port); + server.listen(0, '127.0.0.1', function() { + var port = server.address().port; + $.get("http://127.0.0.1:" + port); }); }); }); @@ -46,7 +45,7 @@ describe('chromium feature', function() { var w = null; afterEach(function() { - return w != null ? w.destroy() : void 0; + w != null ? w.destroy() : void 0; }); it('is set correctly when window is not shown', function(done) { @@ -55,41 +54,42 @@ describe('chromium feature', function() { }); w.webContents.on('ipc-message', function(event, args) { assert.deepEqual(args, ['hidden', true]); - return done(); + done(); }); - return w.loadURL(url); + w.loadURL(url); }); - return it('is set correctly when window is inactive', function(done) { + it('is set correctly when window is inactive', function(done) { w = new BrowserWindow({ show: false }); w.webContents.on('ipc-message', function(event, args) { assert.deepEqual(args, ['hidden', false]); - return done(); + done(); }); w.showInactive(); - return w.loadURL(url); + w.loadURL(url); }); }); xdescribe('navigator.webkitGetUserMedia', function() { - return it('calls its callbacks', function(done) { + it('calls its callbacks', function(done) { this.timeout(5000); - return navigator.webkitGetUserMedia({ + + navigator.webkitGetUserMedia({ audio: true, video: false }, function() { - return done(); + done(); }, function() { - return done(); + done(); }); }); }); describe('navigator.language', function() { - return it('should not be empty', function() { - return assert.notEqual(navigator.language, ''); + it('should not be empty', function() { + assert.notEqual(navigator.language, ''); }); }); @@ -98,28 +98,28 @@ describe('chromium feature', function() { var w = null; afterEach(function() { - return w != null ? w.destroy() : void 0; + w != null ? w.destroy() : void 0; }); - return it('should register for file scheme', function(done) { + it('should register for file scheme', function(done) { w = new BrowserWindow({ show: false }); w.webContents.on('ipc-message', function(event, args) { if (args[0] === 'reload') { - return w.webContents.reload(); + w.webContents.reload(); } else if (args[0] === 'error') { - return done('unexpected error : ' + args[1]); + done('unexpected error : ' + args[1]); } else if (args[0] === 'response') { assert.equal(args[1], 'Hello from serviceWorker!'); - return session.defaultSession.clearStorageData({ + session.defaultSession.clearStorageData({ storages: ['serviceworkers'] }, function() { - return done(); + done(); }); } }); - return w.loadURL(url); + sw.loadURL(url); }); }); @@ -127,11 +127,10 @@ describe('chromium feature', function() { this.timeout(20000); it('returns a BrowserWindowProxy object', function() { - var b; - b = window.open('about:blank', '', 'show=no'); + var b = window.open('about:blank', '', 'show=no'); assert.equal(b.closed, false); assert.equal(b.constructor.name, 'BrowserWindowProxy'); - return b.close(); + b.close(); }); it('accepts "node-integration" as feature', function(done) { @@ -139,10 +138,10 @@ describe('chromium feature', function() { listener = function(event) { assert.equal(event.data, 'undefined'); b.close(); - return done(); + done(); }; window.addEventListener('message', listener); - return b = window.open("file://" + fixtures + "/pages/window-opener-node.html", '', 'nodeIntegration=no,show=no'); + b = window.open("file://" + fixtures + "/pages/window-opener-node.html", '', 'nodeIntegration=no,show=no'); }); it('inherit options of parent window', function(done) { @@ -152,13 +151,13 @@ describe('chromium feature', function() { ref1 = remote.getCurrentWindow().getSize(), width = ref1[0], height = ref1[1]; assert.equal(event.data, "size: " + width + " " + height); b.close(); - return done(); + done(); }; window.addEventListener('message', listener); - return b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', 'show=no'); + b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', 'show=no'); }); - return it('does not override child options', function(done) { + it('does not override child options', function(done) { var b, size; size = { width: 350, @@ -167,45 +166,48 @@ describe('chromium feature', function() { listener = function(event) { assert.equal(event.data, "size: " + size.width + " " + size.height); b.close(); - return done(); + done(); }; window.addEventListener('message', listener); - return b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', "show=no,width=" + size.width + ",height=" + size.height); + b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', "show=no,width=" + size.width + ",height=" + size.height); }); }); describe('window.opener', function() { - var url, w; this.timeout(10000); - url = "file://" + fixtures + "/pages/window-opener.html"; - w = null; + + var url = "file://" + fixtures + "/pages/window-opener.html"; + var w = null; + afterEach(function() { - return w != null ? w.destroy() : void 0; + w != null ? w.destroy() : void 0; }); + it('is null for main window', function(done) { w = new BrowserWindow({ show: false }); w.webContents.on('ipc-message', function(event, args) { assert.deepEqual(args, ['opener', null]); - return done(); + done(); }); - return w.loadURL(url); + w.loadURL(url); }); - return it('is not null for window opened by window.open', function(done) { + + it('is not null for window opened by window.open', function(done) { var b; listener = function(event) { assert.equal(event.data, 'object'); b.close(); - return done(); + done(); }; window.addEventListener('message', listener); - return b = window.open(url, '', 'show=no'); + b = window.open(url, '', 'show=no'); }); }); describe('window.postMessage', function() { - return it('sets the source and origin correctly', function(done) { + it('sets the source and origin correctly', function(done) { var b, sourceId; sourceId = remote.getCurrentWindow().id; listener = function(event) { @@ -218,47 +220,47 @@ describe('chromium feature', function() { assert.equal(message.sourceEqualsOpener, true); assert.equal(message.sourceId, sourceId); assert.equal(event.origin, 'file://'); - return done(); + done(); }; window.addEventListener('message', listener); b = window.open("file://" + fixtures + "/pages/window-open-postMessage.html", '', 'show=no'); - return BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { - return b.postMessage('testing', '*'); + BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { + b.postMessage('testing', '*'); }); }); }); describe('window.opener.postMessage', function() { - return it('sets source and origin correctly', function(done) { + it('sets source and origin correctly', function(done) { var b; listener = function(event) { window.removeEventListener('message', listener); b.close(); assert.equal(event.source, b); assert.equal(event.origin, 'file://'); - return done(); + done(); }; window.addEventListener('message', listener); - return b = window.open("file://" + fixtures + "/pages/window-opener-postMessage.html", '', 'show=no'); + b = window.open("file://" + fixtures + "/pages/window-opener-postMessage.html", '', 'show=no'); }); }); describe('creating a Uint8Array under browser side', function() { - return it('does not crash', function() { + it('does not crash', function() { var RUint8Array; RUint8Array = remote.getGlobal('Uint8Array'); - return new RUint8Array; + new RUint8Array; }); }); describe('webgl', function() { - return it('can be get as context in canvas', function() { + it('can be get as context in canvas', function() { var webgl; if (process.platform === 'linux') { return; } webgl = document.createElement('canvas').getContext('webgl'); - return assert.notEqual(webgl, null); + assert.notEqual(webgl, null); }); }); @@ -270,20 +272,20 @@ describe('chromium feature', function() { worker.onmessage = function(event) { assert.equal(event.data, message); worker.terminate(); - return done(); + done(); }; - return worker.postMessage(message); + worker.postMessage(message); }); - return it('SharedWorker can work', function(done) { + it('SharedWorker can work', function(done) { var message, worker; worker = new SharedWorker('../fixtures/workers/shared_worker.js'); message = 'ping'; worker.port.onmessage = function(event) { assert.equal(event.data, message); - return done(); + done(); }; - return worker.port.postMessage(message); + worker.port.postMessage(message); }); }); @@ -291,28 +293,28 @@ describe('chromium feature', function() { var iframe = null; beforeEach(function() { - return iframe = document.createElement('iframe'); + iframe = document.createElement('iframe'); }); afterEach(function() { - return document.body.removeChild(iframe); + document.body.removeChild(iframe); }); - return it('does not have node integration', function(done) { + it('does not have node integration', function(done) { iframe.src = "file://" + fixtures + "/pages/set-global.html"; document.body.appendChild(iframe); - return iframe.onload = function() { + iframe.onload = function() { assert.equal(iframe.contentWindow.test, 'undefined undefined undefined'); - return done(); + done(); }; }); }); describe('storage', function() { - return it('requesting persitent quota works', function(done) { - return navigator.webkitPersistentStorage.requestQuota(1024 * 1024, function(grantedBytes) { + it('requesting persitent quota works', function(done) { + navigator.webkitPersistentStorage.requestQuota(1024 * 1024, function(grantedBytes) { assert.equal(grantedBytes, 1048576); - return done(); + done(); }); }); }); @@ -324,12 +326,12 @@ describe('chromium feature', function() { afterEach(function() { wss.close(); - return server.close(); + server.close(); }); - return it('has user agent', function(done) { + it('has user agent', function(done) { server = http.createServer(); - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port = server.address().port; wss = new WebSocketServer({ server: server @@ -337,9 +339,9 @@ describe('chromium feature', function() { wss.on('error', done); wss.on('connection', function(ws) { if (ws.upgradeReq.headers['user-agent']) { - return done(); + done(); } else { - return done('user agent is empty'); + done('user agent is empty'); } }); new WebSocket("ws://127.0.0.1:" + port); @@ -347,7 +349,7 @@ describe('chromium feature', function() { }); }); - return describe('Promise', function() { + describe('Promise', function() { it('resolves correctly in Node.js calls', function(done) { document.registerElement('x-element', { prototype: Object.create(HTMLElement.prototype, { @@ -356,18 +358,17 @@ describe('chromium feature', function() { } }) }); - return setImmediate(function() { - var called; - called = false; + setImmediate(function() { + var called = false; Promise.resolve().then(function() { - return done(called ? void 0 : new Error('wrong sequence')); + done(called ? void 0 : new Error('wrong sequence')); }); document.createElement('x-element'); - return called = true; + called = true; }); }); - return it('resolves correctly in Electron calls', function(done) { + it('resolves correctly in Electron calls', function(done) { document.registerElement('y-element', { prototype: Object.create(HTMLElement.prototype, { createdCallback: { @@ -375,14 +376,14 @@ describe('chromium feature', function() { } }) }); - return remote.getGlobal('setImmediate')(function() { + remote.getGlobal('setImmediate')(function() { var called; called = false; Promise.resolve().then(function() { - return done(called ? void 0 : new Error('wrong sequence')); + done(called ? void 0 : new Error('wrong sequence')); }); document.createElement('y-element'); - return called = true; + called = true; }); }); }); diff --git a/spec/modules-spec.js b/spec/modules-spec.js index e3d5bd75c6d..fb53a90cf73 100644 --- a/spec/modules-spec.js +++ b/spec/modules-spec.js @@ -9,40 +9,37 @@ describe('third-party module', function() { if (process.platform !== 'win32' || process.execPath.toLowerCase().indexOf('\\out\\d\\') === -1) { describe('runas', function() { it('can be required in renderer', function() { - return require('runas'); + require('runas'); }); - return it('can be required in node binary', function(done) { - var child, runas; - runas = path.join(fixtures, 'module', 'runas.js'); - child = require('child_process').fork(runas); - return child.on('message', function(msg) { + it('can be required in node binary', function(done) { + var runas = path.join(fixtures, 'module', 'runas.js'); + var child = require('child_process').fork(runas); + child.on('message', function(msg) { assert.equal(msg, 'ok'); - return done(); + done(); }); }); }); describe('ffi', function() { - return it('does not crash', function() { - var ffi, libm; - ffi = require('ffi'); - libm = ffi.Library('libm', { + it('does not crash', function() { + var ffi = require('ffi'); + var libm = ffi.Library('libm', { ceil: ['double', ['double']] }); - return assert.equal(libm.ceil(1.5), 2); + assert.equal(libm.ceil(1.5), 2); }); }); } - return describe('q', function() { - var Q; - Q = require('q'); - return describe('Q.when', function() { - return it('emits the fullfil callback', function(done) { - return Q(true).then(function(val) { + describe('q', function() { + var Q = require('q'); + describe('Q.when', function() { + it('emits the fullfil callback', function(done) { + Q(true).then(function(val) { assert.equal(val, true); - return done(); + done(); }); }); }); diff --git a/spec/node-spec.js b/spec/node-spec.js index 9ead9202653..2961b14b02b 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -9,48 +9,45 @@ describe('node feature', function() { var fixtures = path.join(__dirname, 'fixtures'); describe('child_process', function() { - return describe('child_process.fork', function() { + describe('child_process.fork', function() { it('works in current process', function(done) { var child; child = child_process.fork(path.join(fixtures, 'module', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); it('preserves args', function(done) { - var args, child; - args = ['--expose_gc', '-test', '1']; - child = child_process.fork(path.join(fixtures, 'module', 'process_args.js'), args); + var args = ['--expose_gc', '-test', '1']; + var child = child_process.fork(path.join(fixtures, 'module', 'process_args.js'), args); child.on('message', function(msg) { assert.deepEqual(args, msg.slice(2)); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); it('works in forked process', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js')); + var child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); it('works in forked process when options.env is specifed', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js'), [], { + var child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js'), [], { path: process.env['PATH'] }); child.on('message', function(msg) { assert.equal(msg, 'message'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); it('works in browser process', function(done) { @@ -59,9 +56,9 @@ describe('node feature', function() { child = fork(path.join(fixtures, 'module', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); it('has String::localeCompare working in script', function(done) { @@ -69,19 +66,18 @@ describe('node feature', function() { child = child_process.fork(path.join(fixtures, 'module', 'locale-compare.js')); child.on('message', function(msg) { assert.deepEqual(msg, [0, -1, 1]); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); - return it('has setImmediate working in script', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'set-immediate.js')); + it('has setImmediate working in script', function(done) { + var child = child_process.fork(path.join(fixtures, 'module', 'set-immediate.js')); child.on('message', function(msg) { assert.equal(msg, 'ok'); - return done(); + done(); }); - return child.send('message'); + child.send('message'); }); }); }); @@ -92,18 +88,17 @@ describe('node feature', function() { return; } - return it('does not crash', function(done) { - return fs.readFile(__filename, function() { - return setTimeout(done, 0); + it('does not crash', function(done) { + fs.readFile(__filename, function() { + setTimeout(done, 0); }); }); }); describe('throw error in node context', function() { - return it('gets caught', function(done) { - var error, lsts; - error = new Error('boo!'); - lsts = process.listeners('uncaughtException'); + it('gets caught', function(done) { + var error = new Error('boo!'); + var lsts = process.listeners('uncaughtException'); process.removeAllListeners('uncaughtException'); process.on('uncaughtException', function() { var i, len, lst; @@ -112,28 +107,28 @@ describe('node feature', function() { lst = lsts[i]; process.on('uncaughtException', lst); } - return done(); + done(); }); - return fs.readFile(__filename, function() { + fs.readFile(__filename, function() { throw error; }); }); }); describe('setTimeout called under Chromium event loop in browser process', function() { - return it('can be scheduled in time', function(done) { - return remote.getGlobal('setTimeout')(done, 0); + it('can be scheduled in time', function(done) { + remote.getGlobal('setTimeout')(done, 0); }); }); - return describe('setInterval called under Chromium event loop in browser process', function() { - return it('can be scheduled in time', function(done) { + describe('setInterval called under Chromium event loop in browser process', function() { + it('can be scheduled in time', function(done) { var clear, interval; clear = function() { remote.getGlobal('clearInterval')(interval); - return done(); + done(); }; - return interval = remote.getGlobal('setInterval')(clear, 10); + interval = remote.getGlobal('setInterval')(clear, 10); }); }); }); @@ -141,27 +136,27 @@ describe('node feature', function() { describe('message loop', function() { describe('process.nextTick', function() { it('emits the callback', function(done) { - return process.nextTick(done); + process.nextTick(done); }); - return it('works in nested calls', function(done) { - return process.nextTick(function() { - return process.nextTick(function() { - return process.nextTick(done); + it('works in nested calls', function(done) { + process.nextTick(function() { + process.nextTick(function() { + process.nextTick(done); }); }); }); }); - return describe('setImmediate', function() { + describe('setImmediate', function() { it('emits the callback', function(done) { - return setImmediate(done); + setImmediate(done); }); - return it('works in nested calls', function(done) { - return setImmediate(function() { - return setImmediate(function() { - return setImmediate(done); + it('works in nested calls', function(done) { + setImmediate(function() { + setImmediate(function() { + setImmediate(done); }); }); }); @@ -173,18 +168,18 @@ describe('node feature', function() { return; } - return it('emit error when connect to a socket path without listeners', function(done) { + it('emit error when connect to a socket path without listeners', function(done) { var child, script, socketPath; socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock'); script = path.join(fixtures, 'module', 'create_socket.js'); child = child_process.fork(script, [socketPath]); - return child.on('exit', function(code) { + child.on('exit', function(code) { var client; assert.equal(code, 0); client = require('net').connect(socketPath); - return client.on('error', function(error) { + client.on('error', function(error) { assert.equal(error.code, 'ECONNREFUSED'); - return done(); + done(); }); }); }); @@ -197,16 +192,16 @@ describe('node feature', function() { p.innerText = '闲云潭影日悠悠,物换星移几度秋'; b = new Buffer(p.innerText); assert.equal(b.toString(), '闲云潭影日悠悠,物换星移几度秋'); - return assert.equal(Buffer.byteLength(p.innerText), 45); + assert.equal(Buffer.byteLength(p.innerText), 45); }); - return it('correctly parses external one-byte UTF8 string', function() { + it('correctly parses external one-byte UTF8 string', function() { var b, p; p = document.createElement('p'); p.innerText = 'Jøhänñéß'; b = new Buffer(p.innerText); assert.equal(b.toString(), 'Jøhänñéß'); - return assert.equal(Buffer.byteLength(p.innerText), 13); + assert.equal(Buffer.byteLength(p.innerText), 13); }); }); From 8a9395101e259e6cc16142793654bab16824362c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 17:45:18 -0800 Subject: [PATCH 242/688] Remove unused results --- spec/api-menu-spec.js | 4 ++-- spec/asar-spec.js | 26 +++++++++----------------- spec/chromium-spec.js | 2 +- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index 60464c73275..b27840ec4f2 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -271,7 +271,7 @@ describe('menu module', function() { }); it('should assign groupId automatically', function() { - var groupId, i, j, k, l, m, menu, results, template; + var groupId, i, j, k, l, m, menu, template; template = []; for (i = j = 0; j <= 10; i = ++j) { template.push({ @@ -299,7 +299,7 @@ describe('menu module', function() { }); it("setting 'checked' should flip other items' 'checked' property", function() { - var i, j, k, l, m, menu, n, o, p, q, results, template; + var i, j, k, l, m, menu, n, o, p, q, template; template = []; for (i = j = 0; j <= 10; i = ++j) { template.push({ diff --git a/spec/asar-spec.js b/spec/asar-spec.js index d35cf186c65..3bdff95ae3d 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -138,9 +138,8 @@ describe('asar package', function() { }); it('returns information of a normal file', function() { - var file, j, len, p, ref2, results, stats; + var file, j, len, p, ref2, stats; ref2 = ['file1', 'file2', 'file3', path.join('dir1', 'file1'), path.join('link2', 'file1')]; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); @@ -148,15 +147,13 @@ describe('asar package', function() { assert.equal(stats.isFile(), true); assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), false); - results.push(assert.equal(stats.size, 6)); + assert.equal(stats.size, 6); } - results; }); it('returns information of a normal directory', function() { - var file, j, len, p, ref2, results, stats; + var file, j, len, p, ref2, stats; ref2 = ['dir1', 'dir2', 'dir3']; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); @@ -164,15 +161,13 @@ describe('asar package', function() { assert.equal(stats.isFile(), false); assert.equal(stats.isDirectory(), true); assert.equal(stats.isSymbolicLink(), false); - results.push(assert.equal(stats.size, 0)); + assert.equal(stats.size, 0); } - results; }); it('returns information of a linked file', function() { - var file, j, len, p, ref2, results, stats; + var file, j, len, p, ref2, stats; ref2 = ['link1', path.join('dir1', 'link1'), path.join('link2', 'link2')]; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); @@ -180,15 +175,13 @@ describe('asar package', function() { assert.equal(stats.isFile(), false); assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), true); - results.push(assert.equal(stats.size, 0)); + assert.equal(stats.size, 0); } - results; }); it('returns information of a linked directory', function() { - var file, j, len, p, ref2, results, stats; + var file, j, len, p, ref2, stats; ref2 = ['link2', path.join('dir1', 'link2'), path.join('link2', 'link2')]; - results = []; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; p = path.join(fixtures, 'asar', 'a.asar', file); @@ -196,9 +189,8 @@ describe('asar package', function() { assert.equal(stats.isFile(), false); assert.equal(stats.isDirectory(), false); assert.equal(stats.isSymbolicLink(), true); - results.push(assert.equal(stats.size, 0)); + assert.equal(stats.size, 0); } - results; }); it('throws ENOENT error when can not find file', function() { @@ -461,7 +453,7 @@ describe('asar package', function() { describe('fs.openSync', function() { it('opens a normal/linked/under-linked-directory file', function() { - var buffer, fd, file, j, len, p, ref2, results; + var buffer, fd, file, j, len, p, ref2; ref2 = ['file1', 'link1', path.join('link2', 'file1')]; for (j = 0, len = ref2.length; j < len; j++) { file = ref2[j]; diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 9efe22a263c..4b894b4bbc8 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -119,7 +119,7 @@ describe('chromium feature', function() { }); } }); - sw.loadURL(url); + w.loadURL(url); }); }); From 54d7c580bdca5091bf5749058a16f1591bfcc34c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 16 Feb 2016 17:46:44 -0800 Subject: [PATCH 243/688] Remove unneeded returns --- spec/api-protocol-spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index a7de60d8c36..215868bfdc8 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -122,7 +122,7 @@ describe('protocol module', function() { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, text); @@ -310,7 +310,7 @@ describe('protocol module', function() { if (error) { return done(error); } - return $.ajax({ + $.ajax({ url: protocolName + "://fake-host", success: function(data) { assert.equal(data, String(fileContent)); @@ -325,7 +325,7 @@ describe('protocol module', function() { it('sets Access-Control-Allow-Origin', function(done) { var handler = function(request, callback) { - return callback(filePath); + callback(filePath); }; protocol.registerFileProtocol(protocolName, handler, function(error) { if (error) { @@ -346,7 +346,7 @@ describe('protocol module', function() { }); it('sends object as response', function(done) { var handler = function(request, callback) { - return callback({ + callback({ path: filePath }); }; @@ -440,7 +440,7 @@ describe('protocol module', function() { res.end(text); server.close(); }); - return server.listen(0, '127.0.0.1', function() { + server.listen(0, '127.0.0.1', function() { var port = server.address().port; var url = "http://127.0.0.1:" + port; var handler = function(request, callback) { @@ -586,7 +586,7 @@ describe('protocol module', function() { var doubleHandler = function(request, callback) { try { callback(text); - return callback(); + callback(); } catch (error) { // Ignore error } From 31028ab6366654d1b52d387d14054a5bd8e7c5bf Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 09:27:25 -0800 Subject: [PATCH 244/688] Update var declarations --- spec/api-app-spec.js | 7 +- spec/api-browser-window-spec.js | 57 ++++++--------- spec/api-crash-reporter-spec.js | 3 +- spec/api-ipc-spec.js | 10 ++- spec/api-session-spec.js | 9 +-- spec/api-web-request-spec.js | 12 ++-- spec/asar-spec.js | 18 ++--- spec/chromium-spec.js | 22 +++--- spec/node-spec.js | 31 ++++---- spec/webview-spec.js | 122 ++++++++++++-------------------- 10 files changed, 110 insertions(+), 181 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 7b2535d5404..cbf8223401c 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -66,11 +66,10 @@ describe('app module', function() { }); it('emits a process exit event with the code', function(done) { - var appPath, electronPath, output; - appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app'); - electronPath = remote.getGlobal('process').execPath; + var appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app'); + var electronPath = remote.getGlobal('process').execPath; + var output = ''; appProcess = ChildProcess.spawn(electronPath, [appPath]); - output = ''; appProcess.stdout.on('data', function(data) { output += data; }); diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index b64ef6145b7..58cf57cc8d0 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -42,9 +42,8 @@ describe('browser-window module', function() { w.close(); }); w.on('closed', function() { - var content, test; - test = path.join(fixtures, 'api', 'unload'); - content = fs.readFileSync(test); + var test = path.join(fixtures, 'api', 'unload'); + var content = fs.readFileSync(test); fs.unlinkSync(test); assert.equal(String(content), 'unload'); done(); @@ -66,9 +65,8 @@ describe('browser-window module', function() { describe('window.close()', function() { it('should emit unload handler', function(done) { w.on('closed', function() { - var content, test; - test = path.join(fixtures, 'api', 'close'); - content = fs.readFileSync(test); + var test = path.join(fixtures, 'api', 'close'); + var content = fs.readFileSync(test); fs.unlinkSync(test); assert.equal(String(content), 'close'); done(); @@ -86,8 +84,7 @@ describe('browser-window module', function() { describe('BrowserWindow.destroy()', function() { it('prevents users to access methods of webContents', function() { - var webContents; - webContents = w.webContents; + var webContents = w.webContents; w.destroy(); assert.throws((function() { webContents.getId(); @@ -178,8 +175,7 @@ describe('browser-window module', function() { it('sets the window position', function(done) { var pos = [10, 10]; w.once('move', function() { - var newPos; - newPos = w.getPosition(); + var newPos = w.getPosition(); assert.equal(newPos[0], pos[0]); assert.equal(newPos[1], pos[1]); done(); @@ -190,16 +186,14 @@ describe('browser-window module', function() { describe('BrowserWindow.setContentSize(width, height)', function() { it('sets the content size', function() { - var after, size; - size = [400, 400]; + var size = [400, 400]; w.setContentSize(size[0], size[1]); - after = w.getContentSize(); + var after = w.getContentSize(); assert.equal(after[0], size[0]); assert.equal(after[1], size[1]); }); it('works for framless window', function() { - var after, size; w.destroy(); w = new BrowserWindow({ show: false, @@ -207,9 +201,9 @@ describe('browser-window module', function() { width: 400, height: 400 }); - size = [400, 400]; + var size = [400, 400]; w.setContentSize(size[0], size[1]); - after = w.getContentSize(); + var after = w.getContentSize(); assert.equal(after[0], size[0]); assert.equal(after[1], size[1]); }); @@ -223,7 +217,6 @@ describe('browser-window module', function() { describe('"useContentSize" option', function() { it('make window created with content size when used', function() { - var contentSize; w.destroy(); w = new BrowserWindow({ show: false, @@ -231,7 +224,7 @@ describe('browser-window module', function() { height: 400, useContentSize: true }); - contentSize = w.getContentSize(); + var contentSize = w.getContentSize(); assert.equal(contentSize[0], 400); assert.equal(contentSize[1], 400); }); @@ -243,7 +236,6 @@ describe('browser-window module', function() { }); it('works for framless window', function() { - var contentSize, size; w.destroy(); w = new BrowserWindow({ show: false, @@ -252,10 +244,10 @@ describe('browser-window module', function() { height: 400, useContentSize: true }); - contentSize = w.getContentSize(); + var contentSize = w.getContentSize(); assert.equal(contentSize[0], 400); assert.equal(contentSize[1], 400); - size = w.getSize(); + var size = w.getSize(); assert.equal(size[0], 400); assert.equal(size[1], 400); }); @@ -270,7 +262,6 @@ describe('browser-window module', function() { } it('creates browser window with hidden title bar', function() { - var contentSize; w.destroy(); w = new BrowserWindow({ show: false, @@ -278,12 +269,11 @@ describe('browser-window module', function() { height: 400, titleBarStyle: 'hidden' }); - contentSize = w.getContentSize(); + var contentSize = w.getContentSize(); assert.equal(contentSize[1], 400); }); it('creates browser window with hidden inset title bar', function() { - var contentSize; w.destroy(); w = new BrowserWindow({ show: false, @@ -291,7 +281,7 @@ describe('browser-window module', function() { height: 400, titleBarStyle: 'hidden-inset' }); - contentSize = w.getContentSize(); + var contentSize = w.getContentSize(); assert.equal(contentSize[1], 400); }); }); @@ -312,20 +302,18 @@ describe('browser-window module', function() { }); it('can move the window out of screen', function() { - var after; w.setPosition(-10, -10); - after = w.getPosition(); + var after = w.getPosition(); assert.equal(after[0], -10); assert.equal(after[1], -10); }); it('can set the window larger than screen', function() { - var after, size; - size = screen.getPrimaryDisplay().size; + var size = screen.getPrimaryDisplay().size; size.width += 100; size.height += 100; w.setSize(size.width, size.height); - after = w.getSize(); + var after = w.getSize(); assert.equal(after[0], size.width); assert.equal(after[1], size.height); }); @@ -338,8 +326,7 @@ describe('browser-window module', function() { describe('"preload" option', function() { it('loads the script before other scripts in window', function(done) { - var preload; - preload = path.join(fixtures, 'module', 'set-global.js'); + var preload = path.join(fixtures, 'module', 'set-global.js'); ipcMain.once('answer', function(event, test) { assert.equal(test, 'preload'); done(); @@ -357,8 +344,7 @@ describe('browser-window module', function() { describe('"node-integration" option', function() { it('disables node integration when specified to false', function(done) { - var preload; - preload = path.join(fixtures, 'module', 'send-later.js'); + var preload = path.join(fixtures, 'module', 'send-later.js'); ipcMain.once('answer', function(event, test) { assert.equal(test, 'undefined'); done(); @@ -532,10 +518,9 @@ describe('browser-window module', function() { describe('BrowserWindow options argument is optional', function() { it('should create a window with default size (800x600)', function() { - var size; w.destroy(); w = new BrowserWindow(); - size = w.getSize(); + var size = w.getSize(); assert.equal(size[0], 800); assert.equal(size[1], 600); }); diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index 43830dd4ee1..68dc1375fc3 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -37,9 +37,8 @@ describe('crash-reporter module', function() { var called = false; var server = http.createServer(function(req, res) { - var form; server.close(); - form = new multiparty.Form(); + var form = new multiparty.Form(); form.parse(req, function(error, fields) { if (called) { return; diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 25d8c925688..2c8bc28f156 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -20,9 +20,8 @@ describe('ipc module', function() { describe('remote.require', function() { it('should returns same object for the same module', function() { - var dialog1, dialog2; - dialog1 = remote.require('electron'); - dialog2 = remote.require('electron'); + var dialog1 = remote.require('electron'); + var dialog2 = remote.require('electron'); assert.equal(dialog1, dialog2); }); @@ -58,9 +57,8 @@ describe('ipc module', function() { }); it('can construct an object from its member', function() { - var call, obj; - call = remote.require(path.join(fixtures, 'module', 'call.js')); - obj = new call.constructor; + var call = remote.require(path.join(fixtures, 'module', 'call.js')); + var obj = new call.constructor; assert.equal(obj.test, 'test'); }); }); diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index 049309eda58..9fedcc29e77 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -31,15 +31,13 @@ describe('session module', function() { describe('session.cookies', function() { it('should get cookies', function(done) { - var server; - server = http.createServer(function(req, res) { + var server = http.createServer(function(req, res) { res.setHeader('Set-Cookie', ['0=0']); res.end('finished'); server.close(); }); server.listen(0, '127.0.0.1', function() { - var port; - port = server.address().port; + var port = server.address().port; w.loadURL(url + ":" + port); w.webContents.on('did-finish-load', function() { w.webContents.session.cookies.get({ @@ -136,8 +134,7 @@ describe('session module', function() { }); w.loadURL('file://' + path.join(fixtures, 'api', 'localstorage.html')); w.webContents.on('did-finish-load', function() { - var options; - options = { + var options = { origin: "file://", storages: ['localstorage'], quotas: ['persistent'] diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index f64c91b610c..77f160a2004 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -7,9 +7,8 @@ const session = remote.session; describe('webRequest module', function() { var ses = session.defaultSession; var server = http.createServer(function(req, res) { - var content; res.setHeader('Custom', ['Header']); - content = req.url; + var content = req.url; if (req.headers.accept === '*/*;test/header') { content += 'header/received'; } @@ -19,8 +18,7 @@ describe('webRequest module', function() { before(function(done) { server.listen(0, '127.0.0.1', function() { - var port; - port = server.address().port; + var port = server.address().port; defaultURL = "http://127.0.0.1:" + port + "/"; done(); }); @@ -109,11 +107,10 @@ describe('webRequest module', function() { type: 'string' }; ses.webRequest.onBeforeRequest(function(details, callback) { - var data; assert.equal(details.url, defaultURL); assert.equal(details.method, 'POST'); assert.equal(details.uploadData.length, 1); - data = qs.parse(details.uploadData[0].bytes.toString()); + var data = qs.parse(details.uploadData[0].bytes.toString()); assert.deepEqual(data, postData); callback({ cancel: true @@ -178,8 +175,7 @@ describe('webRequest module', function() { it('can change the request headers', function(done) { ses.webRequest.onBeforeSendHeaders(function(details, callback) { - var requestHeaders; - requestHeaders = details.requestHeaders; + var requestHeaders = details.requestHeaders; requestHeaders.Accept = '*/*;test/header'; callback({ requestHeaders: requestHeaders diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 3bdff95ae3d..060074390f1 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -128,9 +128,8 @@ describe('asar package', function() { }); it('returns information of root', function() { - var p, stats; - p = path.join(fixtures, 'asar', 'a.asar'); - stats = fs.lstatSync(p); + var p = path.join(fixtures, 'asar', 'a.asar'); + var stats = fs.lstatSync(p); assert.equal(stats.isFile(), false); assert.equal(stats.isDirectory(), true); assert.equal(stats.isSymbolicLink(), false); @@ -607,9 +606,8 @@ describe('asar package', function() { }); it('disables asar support in async API', function(done) { - var dir, file; - file = path.join(fixtures, 'asar', 'a.asar', 'file1'); - dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); + var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); + var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); fs.readFile(file, function(error) { assert.equal(error.code, errorName); fs.lstat(file, function(error) { @@ -737,15 +735,13 @@ describe('asar package', function() { var originalFs = require('original-fs'); it('treats .asar as file', function() { - var file, stats; - file = path.join(fixtures, 'asar', 'a.asar'); - stats = originalFs.statSync(file); + var file = path.join(fixtures, 'asar', 'a.asar'); + var stats = originalFs.statSync(file); assert(stats.isFile()); }); it('is available in forked scripts', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'original-fs.js')); + var child = child_process.fork(path.join(fixtures, 'module', 'original-fs.js')); child.on('message', function(msg) { assert.equal(msg, 'object'); done(); diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 4b894b4bbc8..e4444f55b11 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -211,10 +211,9 @@ describe('chromium feature', function() { var b, sourceId; sourceId = remote.getCurrentWindow().id; listener = function(event) { - var message; window.removeEventListener('message', listener); b.close(); - message = JSON.parse(event.data); + var message = JSON.parse(event.data); assert.equal(message.data, 'testing'); assert.equal(message.origin, 'file://'); assert.equal(message.sourceEqualsOpener, true); @@ -247,28 +246,25 @@ describe('chromium feature', function() { describe('creating a Uint8Array under browser side', function() { it('does not crash', function() { - var RUint8Array; - RUint8Array = remote.getGlobal('Uint8Array'); + var RUint8Array = remote.getGlobal('Uint8Array'); new RUint8Array; }); }); describe('webgl', function() { it('can be get as context in canvas', function() { - var webgl; if (process.platform === 'linux') { return; } - webgl = document.createElement('canvas').getContext('webgl'); + var webgl = document.createElement('canvas').getContext('webgl'); assert.notEqual(webgl, null); }); }); describe('web workers', function() { it('Worker can work', function(done) { - var message, worker; - worker = new Worker('../fixtures/workers/worker.js'); - message = 'ping'; + var worker = new Worker('../fixtures/workers/worker.js'); + var message = 'ping'; worker.onmessage = function(event) { assert.equal(event.data, message); worker.terminate(); @@ -278,9 +274,8 @@ describe('chromium feature', function() { }); it('SharedWorker can work', function(done) { - var message, worker; - worker = new SharedWorker('../fixtures/workers/shared_worker.js'); - message = 'ping'; + var worker = new SharedWorker('../fixtures/workers/shared_worker.js'); + var message = 'ping'; worker.port.onmessage = function(event) { assert.equal(event.data, message); done(); @@ -377,8 +372,7 @@ describe('chromium feature', function() { }) }); remote.getGlobal('setImmediate')(function() { - var called; - called = false; + var called = false; Promise.resolve().then(function() { done(called ? void 0 : new Error('wrong sequence')); }); diff --git a/spec/node-spec.js b/spec/node-spec.js index 2961b14b02b..83f685d95f0 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -11,8 +11,7 @@ describe('node feature', function() { describe('child_process', function() { describe('child_process.fork', function() { it('works in current process', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'ping.js')); + var child = child_process.fork(path.join(fixtures, 'module', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); done(); @@ -51,9 +50,8 @@ describe('node feature', function() { }); it('works in browser process', function(done) { - var child, fork; - fork = remote.require('child_process').fork; - child = fork(path.join(fixtures, 'module', 'ping.js')); + var fork = remote.require('child_process').fork; + var child = fork(path.join(fixtures, 'module', 'ping.js')); child.on('message', function(msg) { assert.equal(msg, 'message'); done(); @@ -62,8 +60,7 @@ describe('node feature', function() { }); it('has String::localeCompare working in script', function(done) { - var child; - child = child_process.fork(path.join(fixtures, 'module', 'locale-compare.js')); + var child = child_process.fork(path.join(fixtures, 'module', 'locale-compare.js')); child.on('message', function(msg) { assert.deepEqual(msg, [0, -1, 1]); done(); @@ -169,14 +166,12 @@ describe('node feature', function() { } it('emit error when connect to a socket path without listeners', function(done) { - var child, script, socketPath; - socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock'); - script = path.join(fixtures, 'module', 'create_socket.js'); - child = child_process.fork(script, [socketPath]); + var socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock'); + var script = path.join(fixtures, 'module', 'create_socket.js'); + var child = child_process.fork(script, [socketPath]); child.on('exit', function(code) { - var client; assert.equal(code, 0); - client = require('net').connect(socketPath); + var client = require('net').connect(socketPath); client.on('error', function(error) { assert.equal(error.code, 'ECONNREFUSED'); done(); @@ -187,19 +182,17 @@ describe('node feature', function() { describe('Buffer', function() { it('can be created from WebKit external string', function() { - var b, p; - p = document.createElement('p'); + var p = document.createElement('p'); p.innerText = '闲云潭影日悠悠,物换星移几度秋'; - b = new Buffer(p.innerText); + var b = new Buffer(p.innerText); assert.equal(b.toString(), '闲云潭影日悠悠,物换星移几度秋'); assert.equal(Buffer.byteLength(p.innerText), 45); }); it('correctly parses external one-byte UTF8 string', function() { - var b, p; - p = document.createElement('p'); + var p = document.createElement('p'); p.innerText = 'Jøhänñéß'; - b = new Buffer(p.innerText); + var b = new Buffer(p.innerText); assert.equal(b.toString(), 'Jøhänñéß'); assert.equal(Buffer.byteLength(p.innerText), 13); }); diff --git a/spec/webview-spec.js b/spec/webview-spec.js index a18e152ea6a..54b544def0d 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -95,8 +95,7 @@ describe(' tag', function() { describe('preload attribute', function() { it('loads the script before other scripts in window', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.message, 'function object object'); webview.removeEventListener('console-message', listener); done(); @@ -118,15 +117,14 @@ describe(' tag', function() { }); it('receives ipc message in preload script', function(done) { - var listener, listener2, message; - message = 'boom!'; - listener = function(e) { + var message = 'boom!'; + var listener = function(e) { assert.equal(e.channel, 'pong'); assert.deepEqual(e.args, [message]); webview.removeEventListener('ipc-message', listener); done(); }; - listener2 = function() { + var listener2 = function() { webview.send('ping', message); webview.removeEventListener('did-finish-load', listener2); }; @@ -140,9 +138,8 @@ describe(' tag', function() { describe('httpreferrer attribute', function() { it('sets the referrer url', function(done) { - var listener, referrer; - referrer = 'http://github.com/'; - listener = function(e) { + var referrer = 'http://github.com/'; + var listener = function(e) { assert.equal(e.message, referrer); webview.removeEventListener('console-message', listener); done(); @@ -156,9 +153,8 @@ describe(' tag', function() { describe('useragent attribute', function() { it('sets the user agent', function(done) { - var listener, referrer; - referrer = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'; - listener = function(e) { + var referrer = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'; + var listener = function(e) { assert.equal(e.message, referrer); webview.removeEventListener('console-message', listener); done(); @@ -172,10 +168,9 @@ describe(' tag', function() { describe('disablewebsecurity attribute', function() { it('does not disable web security when not set', function(done) { - var encoded, listener, src; - src = " "; - encoded = btoa(unescape(encodeURIComponent(src))); - listener = function(e) { + var src = " "; + var encoded = btoa(unescape(encodeURIComponent(src))); + var listener = function(e) { assert(/Not allowed to load local resource/.test(e.message)); webview.removeEventListener('console-message', listener); done(); @@ -186,10 +181,9 @@ describe(' tag', function() { }); it('disables web security when set', function(done) { - var encoded, listener, src; - src = " "; - encoded = btoa(unescape(encodeURIComponent(src))); - listener = function(e) { + var src = " "; + var encoded = btoa(unescape(encodeURIComponent(src))); + var listener = function(e) { assert.equal(e.message, 'ok'); webview.removeEventListener('console-message', listener); done(); @@ -223,8 +217,7 @@ describe(' tag', function() { }); it('isolates storage for different id', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.message, " 0"); webview.removeEventListener('console-message', listener); done(); @@ -237,8 +230,7 @@ describe(' tag', function() { }); it('uses current session storage when no id is provided', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.message, "one 1"); webview.removeEventListener('console-message', listener); done(); @@ -252,8 +244,7 @@ describe(' tag', function() { describe('allowpopups attribute', function() { it('can not open new window when not set', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.message, 'null'); webview.removeEventListener('console-message', listener); done(); @@ -264,8 +255,7 @@ describe(' tag', function() { }); it('can open new window when set', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.message, 'window'); webview.removeEventListener('console-message', listener); done(); @@ -327,9 +317,8 @@ describe(' tag', function() { describe('page-favicon-updated event', function() { it('emits when favicon urls are received', function(done) { webview.addEventListener('page-favicon-updated', function(e) { - var pageUrl; assert.equal(e.favicons.length, 2); - pageUrl = process.platform === 'win32' ? 'file:///C:/favicon.png' : 'file:///favicon.png'; + var pageUrl = process.platform === 'win32' ? 'file:///C:/favicon.png' : 'file:///favicon.png'; assert.equal(e.favicons[0], pageUrl); done(); }); @@ -350,10 +339,9 @@ describe(' tag', function() { }); describe('did-navigate event', function() { - var p, pageUrl; - p = path.join(fixtures, 'pages', 'webview-will-navigate.html'); + var p = path.join(fixtures, 'pages', 'webview-will-navigate.html'); p = p.replace(/\\/g, '/'); - pageUrl = url.format({ + var pageUrl = url.format({ protocol: 'file', slashes: true, pathname: p @@ -370,10 +358,9 @@ describe(' tag', function() { }); describe('did-navigate-in-page event', function() { it('emits when an anchor link is clicked', function(done) { - var p, pageUrl; - p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page.html'); + var p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page.html'); p = p.replace(/\\/g, '/'); - pageUrl = url.format({ + var pageUrl = url.format({ protocol: 'file', slashes: true, pathname: p @@ -396,10 +383,9 @@ describe(' tag', function() { }); it('emits when window.location.hash is changed', function(done) { - var p, pageUrl; - p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page-with-hash.html'); + var p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page-with-hash.html'); p = p.replace(/\\/g, '/'); - pageUrl = url.format({ + var pageUrl = url.format({ protocol: 'file', slashes: true, pathname: p @@ -425,8 +411,7 @@ describe(' tag', function() { describe('devtools-opened event', function() { it('should fire when webview.openDevTools() is called', function(done) { - var listener; - listener = function() { + var listener = function() { webview.removeEventListener('devtools-opened', listener); webview.closeDevTools(); done(); @@ -442,12 +427,11 @@ describe(' tag', function() { describe('devtools-closed event', function() { it('should fire when webview.closeDevTools() is called', function(done) { - var listener, listener2; - listener2 = function() { + var listener2 = function() { webview.removeEventListener('devtools-closed', listener2); done(); }; - listener = function() { + var listener = function() { webview.removeEventListener('devtools-opened', listener); webview.closeDevTools(); }; @@ -463,8 +447,7 @@ describe(' tag', function() { describe('devtools-focused event', function() { it('should fire when webview.openDevTools() is called', function(done) { - var listener; - listener = function() { + var listener = function() { webview.removeEventListener('devtools-focused', listener); webview.closeDevTools(); done(); @@ -480,13 +463,12 @@ describe(' tag', function() { describe('.reload()', function() { it('should emit beforeunload handler', function(done) { - var listener, listener2; - listener = function(e) { + var listener = function(e) { assert.equal(e.channel, 'onbeforeunload'); webview.removeEventListener('ipc-message', listener); done(); }; - listener2 = function() { + var listener2 = function() { webview.reload(); webview.removeEventListener('did-finish-load', listener2); }; @@ -500,8 +482,7 @@ describe(' tag', function() { describe('.clearHistory()', function() { it('should clear the navigation history', function(done) { - var listener; - listener = function(e) { + var listener = function(e) { assert.equal(e.channel, 'history'); assert.equal(e.args[0], 2); assert(webview.canGoBack()); @@ -518,14 +499,12 @@ describe(' tag', function() { }); describe('basic auth', function() { - var auth; - auth = require('basic-auth'); + var auth = require('basic-auth'); + it('should authenticate with correct credentials', function(done) { - var message, server; - message = 'Authenticated'; - server = http.createServer(function(req, res) { - var credentials; - credentials = auth(req); + var message = 'Authenticated'; + var server = http.createServer(function(req, res) { + var credentials = auth(req); if (credentials.name === 'test' && credentials.pass === 'test') { res.end(message); } else { @@ -534,8 +513,7 @@ describe(' tag', function() { server.close(); }); server.listen(0, '127.0.0.1', function() { - var port; - port = server.address().port; + var port = server.address().port; webview.addEventListener('ipc-message', function(e) { assert.equal(e.channel, message); done(); @@ -549,11 +527,9 @@ describe(' tag', function() { describe('dom-ready event', function() { it('emits when document is loaded', function(done) { - var server; - server = http.createServer(function() {}); + var server = http.createServer(function() {}); server.listen(0, '127.0.0.1', function() { - var port; - port = server.address().port; + var port = server.address().port; webview.addEventListener('dom-ready', function() { done(); }); @@ -575,14 +551,12 @@ describe(' tag', function() { } it('should support user gesture', function(done) { - var listener, listener2; - listener = function() { + var listener = function() { webview.removeEventListener('enter-html-full-screen', listener); done(); }; - listener2 = function() { - var jsScript; - jsScript = 'document.getElementsByTagName("video")[0].webkitRequestFullScreen()'; + var listener2 = function() { + var jsScript = 'document.getElementsByTagName("video")[0].webkitRequestFullScreen()'; webview.executeJavaScript(jsScript, true); webview.removeEventListener('did-finish-load', listener2); }; @@ -634,8 +608,7 @@ describe(' tag', function() { describe('media-started-playing media-paused events', function() { it('emits when audio starts and stops playing', function(done) { - var audioPlayed; - audioPlayed = false; + var audioPlayed = false; webview.addEventListener('media-started-playing', function() { audioPlayed = true; }); @@ -650,9 +623,8 @@ describe(' tag', function() { describe('found-in-page event', function() { it('emits when a request is made', function(done) { - var listener, listener2, requestId; - requestId = null; - listener = function(e) { + var requestId = null; + var listener = function(e) { assert.equal(e.result.requestId, requestId); if (e.result.finalUpdate) { assert.equal(e.result.matches, 3); @@ -660,7 +632,7 @@ describe(' tag', function() { done(); } }; - listener2 = function() { + var listener2 = function() { requestId = webview.findInPage("virtual"); }; webview.addEventListener('found-in-page', listener); From a252b9b5702ae171af8a56d9ca73d3c20814d8c2 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 17 Feb 2016 16:31:26 -0500 Subject: [PATCH 245/688] Initial ISSUE_TEMPLATE draft --- ISSUE_TEMPLATE.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 00000000000..b19649cad84 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,24 @@ +### Flow + +* [ ] Bug + * [ ] Did you create a code snippet that reliably reproduces the issue in an isolated environment? + * [ ] Did you include what operating system you were on? + * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already reported? + * For more information on how to write a good bug report [look at the CONTRIBUTING guide](https://github.com/atom/electron/blob/master/CONTRIBUTING.md#submitting-issues). +* [ ] Enhancement + * [ ] Are you running the [latest version of Electron](https://github.com/atom/electron/releases)? + * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already requested? + +### Description + +[Description of the bug or feature] + +### Repro Steps + +1. [First Step] +2. [Second Step] +3. [and so on...] + +**Expected:** [What you expected to happen] + +**Actual:** [What actually happened] From 7bf17f2541680835fa60f9666becb6224061ae41 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 18 Feb 2016 01:15:00 +0100 Subject: [PATCH 246/688] Improved frame subscriber - now we only use framesubscription events as an event, and we copy from the backing store directly (instead of accessing it through a videoframe) --- atom/browser/api/atom_api_web_contents.cc | 2 +- atom/browser/api/frame_subscriber.cc | 63 ++++++++++++++--------- atom/browser/api/frame_subscriber.h | 10 ++-- 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index b04553e654b..6531874e6a9 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1065,7 +1065,7 @@ void WebContents::BeginFrameSubscription( const auto view = web_contents()->GetRenderWidgetHostView(); if (view) { FrameSubscriber* frame_subscriber = new FrameSubscriber( - isolate(), view->GetVisibleViewportSize(), callback); + isolate(), view, callback); scoped_ptr del_frame_subscriber( frame_subscriber->GetSubscriber()); view->BeginFrameSubscription(del_frame_subscriber.Pass()); diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 7d973892405..60bf84c0eb9 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -8,6 +8,8 @@ #include "base/bind.h" #include "media/base/video_frame.h" #include "media/base/yuv_convert.h" +#include "content/public/browser/render_widget_host.h" +#include "ui/gfx/screen.h" namespace atom { @@ -16,10 +18,11 @@ namespace api { using Subscriber = FrameSubscriber::Subscriber; FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, - const gfx::Size& size, + content::RenderWidgetHostView* view, const FrameCaptureCallback& callback) - : isolate_(isolate), size_(size), callback_(callback), pending_frames(0) { + : isolate_(isolate), callback_(callback), pending_frames(0), view_(view) { subscriber_ = new Subscriber(this); + size_ = view->GetVisibleViewportSize(); } Subscriber::Subscriber( @@ -36,14 +39,32 @@ bool Subscriber::ShouldCaptureFrame( base::TimeTicks present_time, scoped_refptr* storage, DeliverFrameCallback* callback) { - *storage = media::VideoFrame::CreateFrame( - media::PIXEL_FORMAT_YV12, - frame_subscriber_->size_, gfx::Rect(frame_subscriber_->size_), - frame_subscriber_->size_, base::TimeDelta()); - *callback = base::Bind(&FrameSubscriber::OnFrameDelivered, - base::Unretained(frame_subscriber_), *storage); + const auto view = frame_subscriber_->view_; + const auto host = view ? view->GetRenderWidgetHost() : nullptr; + if (!view || !host) { + return false; + } + + const gfx::Size view_size = view->GetViewBounds().size(); + + gfx::Size bitmap_size = view_size; + const gfx::NativeView native_view = view->GetNativeView(); + gfx::Screen* const screen = gfx::Screen::GetScreenFor(native_view); + const float scale = + screen->GetDisplayNearestWindow(native_view).device_scale_factor(); + if (scale > 1.0f) + bitmap_size = gfx::ScaleToCeiledSize(view_size, scale); + + host->CopyFromBackingStore( + gfx::Rect(view_size), + bitmap_size, + base::Bind(&FrameSubscriber::OnFrameDelivered, + base::Unretained(frame_subscriber_), + frame_subscriber_->callback_), + kBGRA_8888_SkColorType); + frame_subscriber_->pending_frames++; - return true; + return false; } Subscriber* FrameSubscriber::GetSubscriber() { @@ -60,33 +81,25 @@ bool FrameSubscriber::RequestDestruct() { return deletable; } -void FrameSubscriber::OnFrameDelivered( - scoped_refptr frame, base::TimeTicks, bool result) { +void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback, + const SkBitmap& bitmap, content::ReadbackResponse response){ pending_frames--; - if (RequestDestruct() || subscriber_ == NULL || !result) + if (RequestDestruct() || subscriber_ == NULL || bitmap.computeSize64() == 0) return; v8::Locker locker(isolate_); v8::HandleScope handle_scope(isolate_); - gfx::Rect rect = frame->visible_rect(); - size_t rgb_arr_size = rect.width() * rect.height() * 4; + size_t rgb_arr_size = bitmap.width() * bitmap.height() * + bitmap.bytesPerPixel(); v8::MaybeLocal buffer = node::Buffer::New(isolate_, rgb_arr_size); if (buffer.IsEmpty()) return; - // Convert a frame of YUV to 32 bit ARGB. - media::ConvertYUVToRGB32(frame->data(media::VideoFrame::kYPlane), - frame->data(media::VideoFrame::kUPlane), - frame->data(media::VideoFrame::kVPlane), - reinterpret_cast( - node::Buffer::Data(buffer.ToLocalChecked())), - rect.width(), rect.height(), - frame->stride(media::VideoFrame::kYPlane), - frame->stride(media::VideoFrame::kUVPlane), - rect.width() * 4, - media::YV12); + bitmap.copyPixelsTo( + reinterpret_cast(node::Buffer::Data(buffer.ToLocalChecked())), + rgb_arr_size); callback_.Run(buffer.ToLocalChecked()); } diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h index 6f6d66b6be8..745cf382adb 100644 --- a/atom/browser/api/frame_subscriber.h +++ b/atom/browser/api/frame_subscriber.h @@ -6,7 +6,10 @@ #define ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_ #include "base/callback.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/render_widget_host_view_frame_subscriber.h" +#include "content/public/browser/readback_types.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/geometry/size.h" #include "v8/include/v8.h" @@ -35,19 +38,20 @@ class FrameSubscriber { }; FrameSubscriber(v8::Isolate* isolate, - const gfx::Size& size, + content::RenderWidgetHostView* view, const FrameCaptureCallback& callback); Subscriber* GetSubscriber(); private: - void OnFrameDelivered( - scoped_refptr frame, base::TimeTicks, bool); + void OnFrameDelivered(const FrameCaptureCallback& callback, + const SkBitmap& bitmap, content::ReadbackResponse response); bool RequestDestruct(); v8::Isolate* isolate_; gfx::Size size_; + content::RenderWidgetHostView* view_; FrameCaptureCallback callback_; Subscriber* subscriber_; int pending_frames; From 2610aa60e955cb34271d57c062e5962e58325652 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 18 Feb 2016 01:19:41 +0100 Subject: [PATCH 247/688] :art: lint fix --- atom/browser/api/frame_subscriber.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 60bf84c0eb9..ec3bcd05ab7 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -41,9 +41,8 @@ bool Subscriber::ShouldCaptureFrame( DeliverFrameCallback* callback) { const auto view = frame_subscriber_->view_; const auto host = view ? view->GetRenderWidgetHost() : nullptr; - if (!view || !host) { + if (!view || !host) return false; - } const gfx::Size view_size = view->GetViewBounds().size(); @@ -82,7 +81,7 @@ bool FrameSubscriber::RequestDestruct() { } void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback, - const SkBitmap& bitmap, content::ReadbackResponse response){ + const SkBitmap& bitmap, content::ReadbackResponse response) { pending_frames--; if (RequestDestruct() || subscriber_ == NULL || bitmap.computeSize64() == 0) From f81f4479b62b02a2dab8804ba8968c76b29dfa4f Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 17 Feb 2016 21:29:36 -0500 Subject: [PATCH 248/688] Drastically simplify the template [ci skip] --- ISSUE_TEMPLATE.md | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index b19649cad84..4b32023e925 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1,24 +1,11 @@ -### Flow +### Prerequisites -* [ ] Bug - * [ ] Did you create a code snippet that reliably reproduces the issue in an isolated environment? - * [ ] Did you include what operating system you were on? - * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already reported? - * For more information on how to write a good bug report [look at the CONTRIBUTING guide](https://github.com/atom/electron/blob/master/CONTRIBUTING.md#submitting-issues). -* [ ] Enhancement - * [ ] Are you running the [latest version of Electron](https://github.com/atom/electron/releases)? - * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already requested? +* [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already reported? ### Description -[Description of the bug or feature] +[Description of the bug or feature, for example, what you were doing when the issue arose and what you expected to happen] -### Repro Steps +Electron version: -1. [First Step] -2. [Second Step] -3. [and so on...] - -**Expected:** [What you expected to happen] - -**Actual:** [What actually happened] +Operating system: From 1f248e6ea6e966c3023c5520aa3d91c07b393564 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 17 Feb 2016 21:41:14 -0500 Subject: [PATCH 249/688] :memo: Move Electron and OS versions above the description [ci skip] --- ISSUE_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 4b32023e925..d2d66066f40 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -4,8 +4,8 @@ ### Description -[Description of the bug or feature, for example, what you were doing when the issue arose and what you expected to happen] - Electron version: Operating system: + +[Description of the bug or feature, for example, what you were doing when the issue arose and what you expected to happen] From 651264d098f05735473fde1dae2636fb0af35268 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 18 Feb 2016 11:39:35 +0800 Subject: [PATCH 250/688] spec: Fix failing tests on Windows --- spec/api-debugger-spec.js | 4 +++- vendor/node | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index 714d5fda48c..56b642e76e4 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -95,7 +95,9 @@ describe('debugger module', function() { }); it('fires message event', function(done) { - var url = 'file://' + path.join(fixtures, 'pages', 'a.html'); + var url = process.platform != 'win32' ? + 'file://' + path.join(fixtures, 'pages', 'a.html') : + 'file:///' + path.join(fixtures, 'pages', 'a.html').replace(/\\/g, '/'); w.webContents.loadURL(url); try { w.webContents.debugger.attach(); diff --git a/vendor/node b/vendor/node index a130651f868..a507a3c3816 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit a130651f868f5ad23cb366abacea02f9ed50b769 +Subproject commit a507a3c3816d6ac085ed46250c489a3d76ab8b3c From 1e894df102f685f0959f8137d83176c93d457930 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 18 Feb 2016 12:14:25 +0800 Subject: [PATCH 251/688] Update libchromiumcontent, fix #3666 --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index 004e87dd070..02e06948866 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '1be1a55abba527d6fb0fc2a589cbaef2f5a6a79e' +LIBCHROMIUMCONTENT_COMMIT = 'fc5174471ccccce7030d0960f5228e73ca7c2ac6' PLATFORM = { 'cygwin': 'win32', From 9c9759a683436a8d35ec593ecc18512d47512fb9 Mon Sep 17 00:00:00 2001 From: Jacob Page Date: Wed, 17 Feb 2016 21:30:01 -0800 Subject: [PATCH 252/688] Link to Menu documentation Added link to documentation about `Menu` objects --- docs/api/app.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/app.md b/docs/api/app.md index f88d0297994..b5f8e919b82 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -515,7 +515,7 @@ Shows the dock icon. ### `app.dock.setMenu(menu)` _OS X_ -* `menu` Menu +* `menu` [Menu](menu.md) Sets the application's [dock menu][dock-menu]. From 12569f2c9d7a21eda65fd0656f92d2aedea35f68 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 18 Feb 2016 18:32:13 +0800 Subject: [PATCH 253/688] mac: Simulate the behavior of cmd+~ when OS X didn't handle it --- atom/browser/native_window_mac.mm | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 7967a177173..9d9f2a2392d 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -892,12 +892,25 @@ void NativeWindowMac::HandleKeyboardEvent( return; BOOL handled = [[NSApp mainMenu] performKeyEquivalent:event.os_event]; - if (!handled && event.os_event.window != window_.get()) { - // The event comes from detached devtools view, and it has already been - if (!handled && (event.os_event.modifierFlags & NSCommandKeyMask) && - (event.os_event.keyCode == 50 /* ~ key */)) { - // Handle the cmd+~ shortcut. - Focus(true); + if (!handled && event.os_event.window) { + // Handle the cmd+~ shortcut. + if ((event.os_event.modifierFlags & NSCommandKeyMask) /* cmd */ && + (event.os_event.keyCode == 50 /* ~ */)) { + // Switch to next visible window. + NSArray* windows = [NSApp windows]; + NSIndexSet* indexes = [windows indexesOfObjectsPassingTest: + ^BOOL(id window, NSUInteger idx, BOOL* stop) { + return [window isVisible]; + }]; + if ([indexes count] == 0) + return; + NSUInteger current = [windows indexOfObject:event.os_event.window]; + if (current == NSNotFound) // Some faked event. + return; + NSUInteger next = [indexes indexGreaterThanIndex:current]; + if (next == NSNotFound) + next = [indexes firstIndex]; + [[windows objectAtIndex:next] makeKeyAndOrderFront:nil]; } } } From 35815387abd1bbbc147a73a8161a99f7111e8691 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 18 Feb 2016 18:57:31 +0800 Subject: [PATCH 254/688] Ship ffmpeg in dist, close #4536 --- script/create-dist.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script/create-dist.py b/script/create-dist.py index a619e04d3ea..2ec67d4f6c5 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -38,6 +38,7 @@ TARGET_BINARIES = { 'libGLESv2.dll', 'msvcp120.dll', 'msvcr120.dll', + 'ffmpeg.dll', 'node.dll', 'pdf.dll', 'content_resources_200_percent.pak', @@ -51,6 +52,7 @@ TARGET_BINARIES = { PROJECT_NAME, # 'electron' 'content_shell.pak', 'icudtl.dat', + 'libffmpeg.so', 'libnode.so', 'natives_blob.bin', 'snapshot_blob.bin', From 0d77fd4a2c7af3ac05d7c4a023e28c8420e6c20c Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 17 Feb 2016 13:27:46 +0530 Subject: [PATCH 255/688] remote: return webcontents instance from cache --- atom/renderer/api/lib/remote.js | 7 +++++++ spec/api-ipc-spec.js | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/atom/renderer/api/lib/remote.js b/atom/renderer/api/lib/remote.js index ad01e77ac51..d8a5508621e 100644 --- a/atom/renderer/api/lib/remote.js +++ b/atom/renderer/api/lib/remote.js @@ -1,11 +1,14 @@ const ipcRenderer = require('electron').ipcRenderer; const CallbacksRegistry = require('electron').CallbacksRegistry; const v8Util = process.atomBinding('v8_util'); +const IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap; const callbacksRegistry = new CallbacksRegistry; var includes = [].includes; +var remoteObjectCache = new IDWeakMap; + // Check for circular reference. var isCircular = function(field, visited) { if (typeof field === 'object') { @@ -154,6 +157,9 @@ var metaToValue = function(meta) { } } + if (remoteObjectCache.has(meta.id)) + return remoteObjectCache.get(meta.id); + // Track delegate object's life time, and tell the browser to clean up // when the object is GCed. v8Util.setDestructor(ret, function() { @@ -162,6 +168,7 @@ var metaToValue = function(meta) { // Remember object's id. v8Util.setHiddenValue(ret, 'atomId', meta.id); + remoteObjectCache.set(meta.id, ret); return ret; } }; diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 2c8bc28f156..9cf741412b0 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -90,6 +90,14 @@ describe('ipc module', function() { }); }); + describe('remote webContents', function() { + it('can return same object with different getters', function() { + var contents1 = remote.getCurrentWindow().webContents; + var contents2 = remote.getCurrentWebContents(); + assert(contents1 == contents2); + }); + }); + describe('ipc.sender.send', function() { it('should work when sending an object containing id property', function(done) { var obj = { From 68f48c9456dbca1d5e84b92f3d93ffa8e0808c7a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 18 Feb 2016 23:28:19 +0800 Subject: [PATCH 256/688] docs: Add note on Chrome version when using widevine Refs #4519. --- docs/tutorial/using-widevine-cdm-plugin.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/tutorial/using-widevine-cdm-plugin.md b/docs/tutorial/using-widevine-cdm-plugin.md index 340dad343c8..630c18ab8e5 100644 --- a/docs/tutorial/using-widevine-cdm-plugin.md +++ b/docs/tutorial/using-widevine-cdm-plugin.md @@ -8,6 +8,10 @@ Electron doesn't ship with the Widevine CDM plugin for license reasons, to get it, you need to install the official Chrome browser first, which should match the architecture and Chrome version of the Electron build you use. +__Note:__ The major version of Chrome browser has to be the same with the Chrome +version used by Electron, otherwise the plugin will not work even though +`navigator.plugins` would show it has been loaded. + ### Windows & OS X Open `chrome://components/` in Chrome browser, find `WidevineCdm` and make From 8ce3ab1e262ef4ab641d3083ce5be711ea8afd0d Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 17 Feb 2016 22:46:36 +0900 Subject: [PATCH 257/688] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 2 +- docs-translations/ko-KR/api/session.md | 9 ++++++++- docs-translations/ko-KR/api/shell.md | 8 ++++++-- docs-translations/ko-KR/api/tray.md | 7 +++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 32412d13180..89cc1732263 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -523,7 +523,7 @@ dock 아이콘을 표시합니다. ### `app.dock.setMenu(menu)` _OS X_ -* `menu` Menu +* `menu` [Menu](menu.md) 어플리케이션의 [dock menu][dock-menu]를 설정합니다. diff --git a/docs-translations/ko-KR/api/session.md b/docs-translations/ko-KR/api/session.md index 5598fb6eb26..5bb4867eda0 100644 --- a/docs-translations/ko-KR/api/session.md +++ b/docs-translations/ko-KR/api/session.md @@ -59,7 +59,8 @@ var ses = session.fromPartition('persist:name'); Electron의 `webContents`에서 `item`을 다운로드할 때 발생하는 이벤트입니다. -`event.preventDefault()` 메서드를 호출하면 다운로드를 취소합니다. +`event.preventDefault()` 메서드를 호출하면 다운로드를 취소하고, 프로세스의 다음 +틱부터 `item`을 사용할 수 없게 됩니다. ```javascript session.defaultSession.on('will-download', function(event, item, webContents) { @@ -313,6 +314,12 @@ session.fromPartition(partition).setPermissionRequestHandler(function(webContent }); ``` +#### `ses.clearHostResolverCache([callback])` + +* `callback` Function (optional) - 작업이 완료되면 호출됩니다. + +호스트 리소버(resolver) 캐시를 지웁니다. + #### `ses.webRequest` `webRequest` API는 생명주기의 다양한 단계에 맞춰 요청 컨텐츠를 가로채거나 변경할 수 diff --git a/docs-translations/ko-KR/api/shell.md b/docs-translations/ko-KR/api/shell.md index 4183d3b2502..c4831092f3c 100644 --- a/docs-translations/ko-KR/api/shell.md +++ b/docs-translations/ko-KR/api/shell.md @@ -25,12 +25,16 @@ shell.openExternal('https://github.com'); 지정한 파일을 데스크톱 기본 프로그램으로 엽니다. -### `shell.openExternal(url)` +### `shell.openExternal(url[, options])` * `url` String +* `options` Object (optional) _OS X_ + * `activate` Boolean - `true`로 설정하면 어플리케이션을 바로 활성화 상태로 + 실행합니다. 기본값은 `true`입니다. 제공된 외부 프로토콜 URL을 기반으로 데스크톱의 기본 프로그램으로 엽니다. (예를 들어 -mailto: URL은 유저의 기본 이메일 에이전트로 URL을 엽니다.) +mailto: URL은 유저의 기본 이메일 에이전트로 URL을 엽니다.) 어플리케이션이 해당 URL을 +열 수 있을 때 `true`를 반환합니다. 아니라면 `false`를 반환합니다. 역주: 폴더는 'file:\\\\C:\\'와 같이 지정하여 열 수 있습니다. (Windows의 경우) diff --git a/docs-translations/ko-KR/api/tray.md b/docs-translations/ko-KR/api/tray.md index e182f6471e7..d82b0a9d7e4 100644 --- a/docs-translations/ko-KR/api/tray.md +++ b/docs-translations/ko-KR/api/tray.md @@ -32,6 +32,13 @@ __플랫폼별 한계:__ 트레이 아이콘이 작동하도록 만들 수 있습니다. * 앱 알림 표시기는 컨텍스트 메뉴를 가지고 있을 때만 보입니다. * Linux에서 앱 표시기가 사용될 경우, `click` 이벤트는 무시됩니다. +* Linux에서 각각 개별 `MenuItem`의 변경을 적용하려면 `setContextMenu`를 다시 + 호출해야 합니다. 예를 들면: + +```javascript +contextMenu.items[2].checked = false; +appIcon.setContextMenu(contextMenu); +``` 이러한 이유로 Tray API가 모든 플랫폼에서 똑같이 작동하게 하고 싶다면 `click` 이벤트에 의존해선 안되며 언제나 컨텍스트 메뉴를 포함해야 합니다. From cc6ba0fd10e852d17fb46fbf37ad2f62c1238935 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 18 Feb 2016 08:57:31 -0800 Subject: [PATCH 258/688] Remove all but prompts for version numbers --- ISSUE_TEMPLATE.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index d2d66066f40..a78e30d8620 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1,11 +1,2 @@ -### Prerequisites - -* [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Felectron) to see if it is already reported? - -### Description - -Electron version: - -Operating system: - -[Description of the bug or feature, for example, what you were doing when the issue arose and what you expected to happen] +* Electron version: +* Operating system: From c4859c3dc6a7167936db275a1e58398d46757807 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 09:51:24 -0800 Subject: [PATCH 259/688] Use colors from Electron site --- atom/browser/default_app/index.html | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/atom/browser/default_app/index.html b/atom/browser/default_app/index.html index ec16a38bc42..95080867bcd 100644 --- a/atom/browser/default_app/index.html +++ b/atom/browser/default_app/index.html @@ -3,23 +3,23 @@ Electron From 9b373f2e152d3642af0fe613185edde9735237fa Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 10:10:36 -0800 Subject: [PATCH 266/688] on -> to learn --- atom/browser/default_app/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/default_app/index.html b/atom/browser/default_app/index.html index 915a38fe792..3abcefd914b 100644 --- a/atom/browser/default_app/index.html +++ b/atom/browser/default_app/index.html @@ -121,7 +121,7 @@ `docs` ); - on how to write one. + to learn how to write one.

From 1c377310651144de398cb93c477b0d755bfdcc7a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 10:11:35 -0800 Subject: [PATCH 267/688] under -> in --- atom/browser/default_app/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/default_app/index.html b/atom/browser/default_app/index.html index 3abcefd914b..c5672466bcc 100644 --- a/atom/browser/default_app/index.html +++ b/atom/browser/default_app/index.html @@ -98,7 +98,7 @@

- To run your app with Electron, execute the following command under your + To run your app with Electron, execute the following command in your Console (or Terminal):

From d3c6075841ec280cd14e9c4fa73a8ad1cff4e1f3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 17 Feb 2016 10:21:05 -0800 Subject: [PATCH 268/688] Use background color as border color --- atom/browser/default_app/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/default_app/index.html b/atom/browser/default_app/index.html index c5672466bcc..80c347eff6d 100644 --- a/atom/browser/default_app/index.html +++ b/atom/browser/default_app/index.html @@ -33,7 +33,7 @@ pre, code { font-family: "Menlo","Lucida Console",monospace; - border: 1px solid #ddd; + border: 1px solid #076274; background-color: #076274; color: #C5F3FC; border-radius: 3px; From 2a6fcf48e51b1d9125a8cf42c3a348028d73237f Mon Sep 17 00:00:00 2001 From: Brad Metcalf Date: Thu, 18 Feb 2016 13:41:22 -0600 Subject: [PATCH 269/688] Changed session to app to reflect rest of document --- docs/api/app.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/app.md b/docs/api/app.md index b5f8e919b82..bdf0a8a5587 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -156,7 +156,7 @@ certificate you should prevent the default behavior with `event.preventDefault()` and call `callback(true)`. ```javascript -session.on('certificate-error', function(event, webContents, url, error, certificate, callback) { +app.on('certificate-error', function(event, webContents, url, error, certificate, callback) { if (url == "https://github.com") { // Verification logic. event.preventDefault(); From 632c18ab370b7fab418a8cdfc301b8f1beb7f855 Mon Sep 17 00:00:00 2001 From: Rafael G Firmino Date: Thu, 18 Feb 2016 22:51:23 -0200 Subject: [PATCH 270/688] Translated --- docs-translations/pt-BR/api/window-open.md | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 docs-translations/pt-BR/api/window-open.md diff --git a/docs-translations/pt-BR/api/window-open.md b/docs-translations/pt-BR/api/window-open.md new file mode 100644 index 00000000000..eb2b31cd0e4 --- /dev/null +++ b/docs-translations/pt-BR/api/window-open.md @@ -0,0 +1,67 @@ +# The `window.open` function + +Qunado `window.open` é chamado para criar uma nova janela de uma pagina web uma nova instância de `BrowserWindow` será criado para a `url` e um proxy será devolvido para o `windows.open`, para permitir que a página tenha limitado controle sobre ele. + +O proxy tem funcionalidade limitada padrão implementada para ser compatível com as páginas web tradicionais. +Para controle total da nova janela você deveria criar um `BrowserWindow` diretamente + + +The newly created `BrowserWindow` will inherit parent window's options by +default, to override inherited options you can set them in the `features` +string. + +O recém-criado `BrowserWindow` herdará as opções da janela pai por padrão, para substituir as opções herdadas você pode definilos no `features`(string). +### `window.open(url[, frameName][, features])` + +* `url` String +* `frameName` String (opcional) +* `features` String (opcional) + +Cria uma nova janela e retorna uma instância da classe `BrowserWindowProxy'. + +A string `features` segue o formato padrão do browser, mas cada recurso (feature) tem que ser um campo de opções do `BrowserWindow`. + +### `window.opener.postMessage(message, targetOrigin)` + +* `message` String +* `targetOrigin` String + +Envia uma mensagem para a janela pai com a origem especificada ou `*` preferência de origem não especificada. +Sends a message to the parent window with the specified origin or `*` +origin preference. + +## Class: BrowserWindowProxy + +O objeto `BrowserWindowProxy` é retornado de `window.open` e fornece uma funcionalidade limitada para a janela filha. + +### `BrowserWindowProxy.blur()` + +Remove o foco da janela filha. + +### `BrowserWindowProxy.close()` + +Forçadamente fecha a janela filha sem chamar o evento de descarregamento. + +### `BrowserWindowProxy.closed` + +Define como true após a janela filha ficar fechada. + +### `BrowserWindowProxy.eval(code)` + +* `code` String + +Avalia o código na jánela filha. + +### `BrowserWindowProxy.focus()` + +Concentra-se a janela filha (traz a janela para frente) +### `BrowserWindowProxy.postMessage(message, targetOrigin)` + +* `message` String +* `targetOrigin` String + +Sends a message to the child window with the specified origin or `*` for no +origin preference. + +In addition to these methods, the child window implements `window.opener` object +with no properties and a single method. From cd303087110f76d3232498456b02958ea03fea17 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 19 Feb 2016 10:01:39 +0800 Subject: [PATCH 271/688] Update libchromiumcontent with free version of ffmpeg --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index 02e06948866..e3404918ce4 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'fc5174471ccccce7030d0960f5228e73ca7c2ac6' +LIBCHROMIUMCONTENT_COMMIT = '599c8941e1884e155218ec1013cba9fc5c7c7072' PLATFORM = { 'cygwin': 'win32', From daffb4881ee72c2299a407d78a6d9296e5050bec Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 19 Feb 2016 10:26:18 +0800 Subject: [PATCH 272/688] Create and upload free version of ffmpeg --- script/create-dist.py | 19 +++++++++++++++++++ script/upload.py | 12 ++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/script/create-dist.py b/script/create-dist.py index 2ec67d4f6c5..32d8f52aff3 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -99,6 +99,7 @@ def main(): create_dist_zip() create_chrome_binary_zip('chromedriver', get_chromedriver_version()) create_chrome_binary_zip('mksnapshot', ATOM_SHELL_VERSION) + create_ffmpeg_zip() create_symbols_zip() @@ -205,6 +206,24 @@ def create_chrome_binary_zip(binary, version): make_zip(zip_file, files, []) +def create_ffmpeg_zip(): + dist_name = 'ffmpeg-{0}-{1}-{2}.zip'.format( + ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) + zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name) + + if PLATFORM == 'darwin': + ffmpeg_name = 'libffmpeg.dylib' + elif PLATFORM == 'linux': + ffmpeg_name = 'libffmpeg.so' + elif PLATFORM == 'win32': + ffmpeg_name = 'ffmpeg.dll' + + shutil.copy2(os.path.join(CHROMIUM_DIR, '..', 'ffmpeg', ffmpeg_name), + DIST_DIR) + with scoped_cwd(DIST_DIR): + make_zip(zip_file, [ffmpeg_name, 'LICENSE', 'LICENSES.chromium.html'], []) + + def create_symbols_zip(): dist_name = '{0}-{1}-{2}-{3}-symbols.zip'.format(PROJECT_NAME, ATOM_SHELL_VERSION, diff --git a/script/upload.py b/script/upload.py index 3245d9caaa7..d23bc554c3c 100755 --- a/script/upload.py +++ b/script/upload.py @@ -35,9 +35,6 @@ DSYM_NAME = '{0}-{1}-{2}-{3}-dsym.zip'.format(PROJECT_NAME, ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) -MKSNAPSHOT_NAME = 'mksnapshot-{0}-{1}-{2}.zip'.format(ATOM_SHELL_VERSION, - get_platform_key(), - get_target_arch()) def main(): @@ -89,12 +86,19 @@ def main(): if PLATFORM == 'darwin': upload_atom_shell(github, release, os.path.join(DIST_DIR, DSYM_NAME)) + # Upload free version of ffmpeg. + ffmpeg = 'ffmpeg-{0}-{1}-{2}.zip'.format( + ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) + upload_atom_shell(github, release, os.path.join(DIST_DIR, ffmpeg)) + # Upload chromedriver and mksnapshot for minor version update. if parse_version(args.version)[2] == '0': chromedriver = 'chromedriver-{0}-{1}-{2}.zip'.format( get_chromedriver_version(), get_platform_key(), get_target_arch()) upload_atom_shell(github, release, os.path.join(DIST_DIR, chromedriver)) - upload_atom_shell(github, release, os.path.join(DIST_DIR, MKSNAPSHOT_NAME)) + mksnapshot = 'mksnapshot-{0}-{1}-{2}.zip'.format( + ATOM_SHELL_VERSION, get_platform_key(), get_target_arch()) + upload_atom_shell(github, release, os.path.join(DIST_DIR, mksnapshot)) if PLATFORM == 'win32' and not tag_exists: # Upload node headers. From 4b18317e7c2a05e440e8a04c3ab4a12f4b573dcd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 19 Feb 2016 10:27:04 +0800 Subject: [PATCH 273/688] Bump v0.36.8 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index c8c714858b4..68a30cc637f 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.36.7', + 'version%': '0.36.8', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 74725c94dc5..e1a5694d27a 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.36.7 + 0.36.8 CFBundleShortVersionString - 0.36.7 + 0.36.8 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 298d0bce73c..ff125b3edf7 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,36,7,0 - PRODUCTVERSION 0,36,7,0 + FILEVERSION 0,36,8,0 + PRODUCTVERSION 0,36,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.36.7" + VALUE "FileVersion", "0.36.8" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.36.7" + VALUE "ProductVersion", "0.36.8" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index a4f886c7e7d..b464ebdae4f 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 36 -#define ATOM_PATCH_VERSION 7 +#define ATOM_PATCH_VERSION 8 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index f684386269e..a7eaa1a9420 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.36.7", + "version": "0.36.8", "devDependencies": { "asar": "^0.9.0", "eslint": "^2.1.0", From 85800256deb7c2eb543bba8d28eb369e3521eb54 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 19 Feb 2016 19:39:01 +0530 Subject: [PATCH 274/688] protocol: respect requests from partition --- atom/browser/api/atom_api_protocol.cc | 70 +++++++++++---------------- atom/browser/api/atom_api_protocol.h | 11 +++-- atom/browser/api/atom_api_session.cc | 10 ++++ atom/browser/api/atom_api_session.h | 2 + atom/browser/api/lib/protocol.js | 9 +++- atom/common/node_bindings.cc | 1 - spec/api-protocol-spec.js | 51 +++++++++++++++++++ 7 files changed, 105 insertions(+), 49 deletions(-) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 09da9c71cad..335c20e11e3 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -28,33 +28,6 @@ Protocol::Protocol(AtomBrowserContext* browser_context) CHECK(job_factory_); } -mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return mate::ObjectTemplateBuilder(isolate) - .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes) - .SetMethod("registerServiceWorkerSchemes", - &Protocol::RegisterServiceWorkerSchemes) - .SetMethod("registerStringProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerBufferProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerFileProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerHttpProtocol", - &Protocol::RegisterProtocol) - .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) - .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) - .SetMethod("interceptStringProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptBufferProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptFileProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptHttpProtocol", - &Protocol::InterceptProtocol) - .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); -} - void Protocol::RegisterStandardSchemes( const std::vector& schemes) { atom::AtomBrowserClient::SetCustomSchemes(schemes); @@ -153,21 +126,34 @@ mate::Handle Protocol::Create( return mate::CreateHandle(isolate, new Protocol(browser_context)); } +// static +void Protocol::BuildPrototype(v8::Isolate* isolate, + v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes) + .SetMethod("registerServiceWorkerSchemes", + &Protocol::RegisterServiceWorkerSchemes) + .SetMethod("registerStringProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerBufferProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerFileProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerHttpProtocol", + &Protocol::RegisterProtocol) + .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) + .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) + .SetMethod("interceptStringProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptBufferProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptFileProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptHttpProtocol", + &Protocol::InterceptProtocol) + .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); +} + } // namespace api } // namespace atom - -namespace { - -void Initialize(v8::Local exports, v8::Local unused, - v8::Local context, void* priv) { - v8::Isolate* isolate = context->GetIsolate(); - mate::Dictionary dict(isolate, exports); - auto browser_context = static_cast( - atom::AtomBrowserMainParts::Get()->browser_context()); - dict.Set("protocol", atom::api::Protocol::Create(isolate, browser_context)); -} - -} // namespace - -NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_protocol, Initialize) diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index 8aef406fbc3..36ab46ba823 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -9,6 +9,7 @@ #include #include +#include "atom/browser/api/trackable_object.h" #include "atom/browser/net/atom_url_request_job_factory.h" #include "base/callback.h" #include "base/containers/scoped_ptr_hash_map.h" @@ -30,7 +31,7 @@ class AtomURLRequestJobFactory; namespace api { -class Protocol : public mate::Wrappable { +class Protocol : public mate::TrackableObject { public: using Handler = base::Callback)>; @@ -40,13 +41,13 @@ class Protocol : public mate::Wrappable { static mate::Handle Create( v8::Isolate* isolate, AtomBrowserContext* browser_context); + // mate::TrackableObject: + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + protected: explicit Protocol(AtomBrowserContext* browser_context); - // mate::Wrappable implementations: - virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate); - private: // Possible errors. enum ProtocolError { diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index e5c5198f034..51f7c1bb811 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -9,6 +9,7 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/api/atom_api_download_item.h" +#include "atom/browser/api/atom_api_protocol.h" #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_request.h" #include "atom/browser/api/save_page_handler.h" @@ -443,6 +444,14 @@ v8::Local Session::Cookies(v8::Isolate* isolate) { return v8::Local::New(isolate, cookies_); } +v8::Local Session::Protocol(v8::Isolate* isolate) { + if (protocol_.IsEmpty()) { + auto handle = atom::api::Protocol::Create(isolate, browser_context()); + protocol_.Reset(isolate, handle.ToV8()); + } + return v8::Local::New(isolate, protocol_); +} + v8::Local Session::WebRequest(v8::Isolate* isolate) { if (web_request_.IsEmpty()) { auto handle = atom::api::WebRequest::Create(isolate, browser_context()); @@ -490,6 +499,7 @@ void Session::BuildPrototype(v8::Isolate* isolate, &Session::SetPermissionRequestHandler) .SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache) .SetProperty("cookies", &Session::Cookies) + .SetProperty("protocol", &Session::Protocol) .SetProperty("webRequest", &Session::WebRequest); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 02d8ba5cdec..63c4cfc612b 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -80,10 +80,12 @@ class Session: public mate::TrackableObject, mate::Arguments* args); void ClearHostResolverCache(mate::Arguments* args); v8::Local Cookies(v8::Isolate* isolate); + v8::Local Protocol(v8::Isolate* isolate); v8::Local WebRequest(v8::Isolate* isolate); // Cached object. v8::Global cookies_; + v8::Global protocol_; v8::Global web_request_; scoped_refptr browser_context_; diff --git a/atom/browser/api/lib/protocol.js b/atom/browser/api/lib/protocol.js index 41cb48db09b..caef0ad646b 100644 --- a/atom/browser/api/lib/protocol.js +++ b/atom/browser/api/lib/protocol.js @@ -4,7 +4,10 @@ if (!app.isReady()) { throw new Error('Can not initialize protocol module before app is ready'); } -const protocol = process.atomBinding('protocol').protocol; +const session = require('electron').session; + +// Returns the protocol property for default session. +const protocol = session.defaultSession.protocol; // Warn about removed APIs. var logAndThrow = function(callback, message) { @@ -16,6 +19,10 @@ var logAndThrow = function(callback, message) { } }; +protocol.fromPartition = function(partition) { + return session.fromPartition(partition).protocol; +}; + protocol.registerProtocol = function(scheme, handler, callback) { return logAndThrow(callback, 'registerProtocol API has been replaced by the register[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.'); }; diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 69e7906ffbb..4af3ba5b64b 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -41,7 +41,6 @@ REFERENCE_MODULE(atom_browser_download_item); REFERENCE_MODULE(atom_browser_menu); 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_session); REFERENCE_MODULE(atom_browser_tray); diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 215868bfdc8..483155b7065 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -3,6 +3,7 @@ const http = require('http'); const path = require('path'); const qs = require('querystring'); const remote = require('electron').remote; +const BrowserWindow = remote.require('electron').BrowserWindow; const protocol = remote.require('electron').protocol; describe('protocol module', function() { @@ -814,4 +815,54 @@ describe('protocol module', function() { }); }); }); + + describe('protocol.fromPartition', function() { + var partitionName = 'temp'; + var tempProtocol = protocol.fromPartition(partitionName); + var w = null; + + beforeEach(function() { + if (w != null) { + w.destroy(); + } + w = new BrowserWindow({ + show: false, + width: 400, + height: 400, + webPreferences: { + partition: partitionName + } + }); + }); + + afterEach(function() { + if (w != null) { + w.destroy(); + } + w = null; + }); + + it('handles requests from a partition', function(done) { + var handler = function(error, callback) { + callback({ + data: text + }); + }; + tempProtocol.registerStringProtocol(protocolName, handler, function(error) { + if (error) { + return done(error); + } + protocol.isProtocolHandled(protocolName, function(result) { + assert.equal(result, false); + }); + tempProtocol.isProtocolHandled(protocolName, function(result) { + assert.equal(result, true); + }); + }); + w.webContents.on('did-finish-load', function() { + done(); + }); + w.loadURL(protocolName + "://fake-host"); + }); + }); }); From e45e2460275fafd965aab20354d17c86d01f5b35 Mon Sep 17 00:00:00 2001 From: cesine Date: Fri, 19 Feb 2016 23:24:56 -0500 Subject: [PATCH 275/688] a new version of asar is out 0.10.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f684386269e..78618c06bd9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "electron", "version": "0.36.7", "devDependencies": { - "asar": "^0.9.0", + "asar": "^0.10.0", "eslint": "^2.1.0", "request": "*" }, From a737e15ddba97227a83a6cd3bf3cacafb0935ee2 Mon Sep 17 00:00:00 2001 From: Magica Date: Sat, 20 Feb 2016 16:09:56 +0800 Subject: [PATCH 276/688] Update README.md to 45739ce434ec3c3eb190d35d3948b702b54706cd --- docs-translations/zh-CN/README.md | 76 +++++++++++++++++-------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/docs-translations/zh-CN/README.md b/docs-translations/zh-CN/README.md index 5c4303a0a6f..d7a8442ad4a 100644 --- a/docs-translations/zh-CN/README.md +++ b/docs-translations/zh-CN/README.md @@ -1,13 +1,19 @@ +## 常见问题 + ++ [Electron 常见问题](faq/electron-faq.md) + ## 向导 * [支持平台](tutorial/supported-platforms.md) -* [应用部署](tutorial/application-distribution.md) -* [应用打包](tutorial/application-packaging.md) -* [使用原生模块](tutorial/using-native-node-modules.md) +* [分发应用](tutorial/application-distribution.md) +* [提交应用到 Mac App Store](tutorial/mac-app-store-submission-guide.md) +* [打包应用](tutorial/application-packaging.md) +* [使用 Node 原生模块](tutorial/using-native-node-modules.md) * [主进程调试](tutorial/debugging-main-process.md) * [使用 Selenium 和 WebDriver](tutorial/using-selenium-and-webdriver.md) -* [调试工具扩展](tutorial/devtools-extension.md) -* [使用 PepperFlash 插件](tutorial/using-pepper-flash-plugin.md) +* [使用开发人员工具扩展](tutorial/devtools-extension.md) +* [使用 Pepper Flash 插件](tutorial/using-pepper-flash-plugin.md) +* [使用 Widevine CDM 插件](tutorial/using-widevine-cdm-plugin.md) ## 教程 @@ -19,53 +25,55 @@ * [简介](api/synopsis.md) * [进程对象](api/process.md) -* [支持的Chrome命令行开关](api/chrome-command-line-switches.md) +* [支持的 Chrome 命令行开关](api/chrome-command-line-switches.md) +* [环境变量](api/environment-variables.md) -定制的DOM元素: +自定义的 DOM 元素: -* [`File`对象](api/file-object.md) -* [``标签](api/web-view-tag.md) -* [`window.open`函数](api/window-open.md) +* [`File` 对象](api/file-object.md) +* [`` 标签](api/web-view-tag.md) +* [`window.open` 函数](api/window-open.md) -主进程可用的模块: +在主进程内可用的模块: * [app](api/app.md) -* [auto-updater](api/auto-updater.md) -* [browser-window](api/browser-window.md) -* [content-tracing](api/content-tracing.md) +* [autoUpdater](api/auto-updater.md) +* [BrowserWindow](api/browser-window.md) +* [contentTracing](api/content-tracing.md) * [dialog](api/dialog.md) -* [global-shortcut](api/global-shortcut.md) -* [ipc (main process)](api/ipc-main-process.md) -* [menu](api/menu.md) -* [menu-item](api/menu-item.md) -* [power-monitor](api/power-monitor.md) -* [power-save-blocker](api/power-save-blocker.md) +* [globalShortcut](api/global-shortcut.md) +* [ipcMain](api/ipc-main.md) +* [Menu](api/menu.md) +* [MenuItem](api/menu-item.md) +* [powerMonitor](api/power-monitor.md) +* [powerSaveBlocker](api/power-save-blocker.md) * [protocol](api/protocol.md) * [session](api/session.md) * [webContents](api/web-contents.md) -* [tray](api/tray.md) +* [Tray](api/tray.md) -渲染进程(网页)可用的模块: +在渲染进程(网页)内可用的模块: -* [ipc (renderer)](api/ipc-renderer.md) +* [desktopCapturer](api/desktop-capturer.md) +* [ipcRenderer](api/ipc-renderer.md) * [remote](api/remote.md) -* [web-frame](api/web-frame.md) +* [webFrame](api/web-frame.md) -两种进程都可用的模块: +在两种进程中都可用的模块: * [clipboard](api/clipboard.md) -* [crash-reporter](api/crash-reporter.md) -* [native-image](api/native-image.md) +* [crashReporter](api/crash-reporter.md) +* [nativeImage](api/native-image.md) * [screen](api/screen.md) * [shell](api/shell.md) ## 开发 -* [编码规范](development/coding-style.md) +* [代码规范](development/coding-style.md) * [源码目录结构](development/source-code-directory-structure.md) -* [与 NW.js (原名 node-webkit) 在技术上的差异](development/atom-shell-vs-node-webkit.md) -* [构建系统概况](development/build-system-overview.md) -* [构建步骤 (Mac)](development/build-instructions-mac.md) -* [构建步骤 (Windows)](development/build-instructions-windows.md) -* [构建步骤 (Linux)](development/build-instructions-linux.md) -* [在调试中使用 SymbolServer](development/setting-up-symbol-server.md) +* [与 NW.js(原 node-webkit)在技术上的差异](development/atom-shell-vs-node-webkit.md) +* [构建系统概览](development/build-system-overview.md) +* [构建步骤(Mac)](development/build-instructions-mac.md) +* [构建步骤(Windows)](development/build-instructions-windows.md) +* [构建步骤(Linux)](development/build-instructions-linux.md) +* [在调试中使用 Symbol Server](development/setting-up-symbol-server.md) From 060d06d39676049d66b6598b8773604864a87dca Mon Sep 17 00:00:00 2001 From: Magica Date: Sat, 20 Feb 2016 17:00:58 +0800 Subject: [PATCH 277/688] Translate electron-faq.md#45739ce434ec3c3eb190d35d3948b702b54706cd --- docs-translations/zh-CN/faq/electron-faq.md | 139 ++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 docs-translations/zh-CN/faq/electron-faq.md diff --git a/docs-translations/zh-CN/faq/electron-faq.md b/docs-translations/zh-CN/faq/electron-faq.md new file mode 100644 index 00000000000..3431c6018ab --- /dev/null +++ b/docs-translations/zh-CN/faq/electron-faq.md @@ -0,0 +1,139 @@ +# Electron 常见问题 + +## Electron 会在什么时候升级到最新版本的 Chrome? + +通常来说,在稳定版的 Chrome 发布后两周内,我们会更新 Electron 内的 Chrome 版本。 + +我们只会使用 stable 版本的 Chrome。但如果在 beta 或 dev 版本中有一个重要的更新,我们会把补丁应用到现版本的 Chrome 上。 + +## Electron 会在什么时候升级到最新版本的 Node.js? + +我们通常会在最新版的 Node.js 发布后一个月左右将 Electron 更新到这个版本的 Node.js。我们通过这种方式来避免新版本的 Node.js +带来的 bug(这种 bug 太常见了)。 + +Node.js 的新特性通常是由新版本的 V8 带来的。由于 Electron 使用的是 Chrome 浏览器中附带的 V8 引擎,所以 Electron 内往往已经 +有了部分新版本 Node.js 才有的崭新特性。 + +## 如何在两个网页间共享数据? + +在两个网页(渲染进程)间共享数据最简单的方法是使用浏览器中已经实现的 HTML5 API,比较好的方案是用 [Storage API][storage], +[`localStorage`][local-storage],[`sessionStorage`][session-storage] 或者 [IndexedDB][indexed-db]。 + +你还可以用 Electron 内的 IPC 机制实现。将数据存在主进程的某个全局变量中,然后在多个渲染进程中使用 `remote` 模块来访问它。 + +```javascript +// 在主进程中 +global.sharedObject = { + someProperty: 'default value' +}; +``` + +```javascript +// 在第一个页面中 +require('remote').getGlobal('sharedObject').someProperty = 'new value'; +``` + +```javascript +// 在第二个页面中 +console.log(require('remote').getGlobal('sharedObject').someProperty); +``` + +## 为什么应用的窗口、托盘在一段时间后不见了? + +这通常是因为用来存放窗口、托盘的变量被垃圾收集了。 + +你可以参考以下两篇文章来了解为什么会遇到这个问题。 + +* [内存管理][memory-management] +* [变量作用域][variable-scope] + +如果你只是要一个快速的修复方案,你可以用下面的方式改变变量的作用域,防止这个变量被垃圾收集。 + +从 + +```javascript +app.on('ready', function() { + var tray = new Tray('/path/to/icon.png'); +}) +``` + +改为 + +```javascript +var tray = null; +app.on('ready', function() { + tray = new Tray('/path/to/icon.png'); +}) +``` + +## 在 Electron 中,我为什么不能用 jQuery、RequireJS、Meteor、AngularJS? + +因为 Electron 在运行环境中引入了 Node.js,所以在 DOM 中有一些额外的变量,比如 `module`、`exports` 和 `require`。这导致 +了许多库不能正常运行,因为它们也需要将同名的变量加入运行环境中。 + +我们可以通过禁用 Node.js 来解决这个问题,用如下的方式: + +```javascript +// 在主进程中 +var mainWindow = new BrowserWindow({ + webPreferences: { + nodeIntegration: false + } +}); +``` + +假如你依然需要使用 Node.js 和 Electron 提供的 API,你需要在引入那些库之前将这些变量重命名,比如: + +```html + + + + +``` + +## 为什么 `require('electron').xxx` 的结果是 undefined? + +在使用 Electron 的提供的模块时,你可能会遇到和以下类似的错误: + +``` +> require('electron').webFrame.setZoomFactor(1.0); +Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined +``` + +这是因为你在项目中或者在全局中安装了[npm 上获取的 `electron` 模块][electron-module],它把 Electron 的内置模块覆写了。 + +你可以通过以下方式输出 `electron` 模块的路径来确认你是否使用了正确的模块。 + +```javascript +console.log(require.resolve('electron')); +``` + +确认以下它是不是像下面这样的: + +``` +"/path/to/Electron.app/Contents/Resources/atom.asar/renderer/api/lib/exports/electron.js" +``` + +假如输出的路径类似于 `node_modules/electron/index.js`,那么你需要移除或者重命名 npm 上的 `electron` 模块。 + +```bash +npm uninstall electron +npm uninstall -g electron +``` + +如果你依然遇到了这个问题,你可能需要检查一下拼写或者是否在错误的进程中调用了这个模块。比如, +`require('electron').app` 只能在主进程中使用, 然而 `require('electron').webFrame` 只能在渲染进程中使用。 + +[memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management +[variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx +[electron-module]: https://www.npmjs.com/package/electron +[storage]: https://developer.mozilla.org/en-US/docs/Web/API/Storage +[local-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage +[session-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage +[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API From 1db72f8010e46567e16182e3f6cddf0155239c6c Mon Sep 17 00:00:00 2001 From: Magica Date: Sat, 20 Feb 2016 18:51:04 +0800 Subject: [PATCH 278/688] Translate accelerator.md of 45739ce434ec3c3eb190d35d3948b702b54706cd --- docs-translations/zh-CN/api/accelerator.md | 47 ++++++++++------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/docs-translations/zh-CN/api/accelerator.md b/docs-translations/zh-CN/api/accelerator.md index 8858d18e856..06e7397c849 100644 --- a/docs-translations/zh-CN/api/accelerator.md +++ b/docs-translations/zh-CN/api/accelerator.md @@ -1,46 +1,43 @@ # Accelerator -An accelerator is a string that represents a keyboard shortcut. It can contain -multiple modifiers and key codes, combined by the `+` character. +一个 `Accelerator` 是一个表示某个快捷键组合的字符串。它包含了用 `+` 连接的若干个按键。 -Examples: +例如: * `Command+A` * `Ctrl+Shift+Z` -## Platform notice +## 运行平台相关的提示 -On Linux and Windows, the `Command` key does not have any effect so -use `CommandOrControl` which represents `Command` on OS X and `Control` on -Linux and Windows to define some accelerators. +在 Linux 和 Windows 上,`Command` 键并不存在,因此我们通常用 `CommandOrControl` 来表示“在 OS X 下为 `Command` 键,但在 +Linux 和 Windows 下为 `Control` 键。 -The `Super` key is mapped to the `Windows` key on Windows and Linux and -`Cmd` on OS X. +`Super` 键是指 Linux 和 Windows 上的 `Windows` 键,但是在 OS X 下为 `Command` 键。 -## Available modifiers +## 可用的功能按键 -* `Command` (or `Cmd` for short) -* `Control` (or `Ctrl` for short) -* `CommandOrControl` (or `CmdOrCtrl` for short) +* `Command`(缩写为 `Cmd`) +* `Control`(缩写为 `Ctrl`) +* `CommandOrControl`(缩写为 `CmdOrCtrl`) * `Alt` * `Shift` * `Super` -## Available key codes +## 可用的普通按键 -* `0` to `9` -* `A` to `Z` -* `F1` to `F24` -* Punctuations like `~`, `!`, `@`, `#`, `$`, etc. +* `0` 到 `9` +* `A` 到 `Z` +* `F1` 到 `F24` +* 类似与 `~`、`!`、`@`、`#`、`$` 的标点符号。 * `Plus` * `Space` * `Backspace` * `Delete` * `Insert` -* `Return` (or `Enter` as alias) -* `Up`, `Down`, `Left` and `Right` -* `Home` and `End` -* `PageUp` and `PageDown` -* `Escape` (or `Esc` for short) -* `VolumeUp`, `VolumeDown` and `VolumeMute` -* `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` and `MediaPlayPause` +* `Return`(和 `Enter` 等同) +* `Up`、`Down`、`Left` 和 `Right` +* `Home` 和 `End` +* `PageUp` 和 `PageDown` +* `Escape`(缩写为 `Esc`) +* `VolumeUp`、`VolumeDown` 和 `VolumeMute` +* `MediaNextTrack`、`MediaPreviousTrack`、`MediaStop` 和 `MediaPlayPause` From f64dc5f57d1d11a5701b4391a9fbb5f679d28358 Mon Sep 17 00:00:00 2001 From: Magica Date: Sun, 21 Feb 2016 13:49:51 +0800 Subject: [PATCH 279/688] Translate app.md in commit 45739ce434ec3c3eb190d35d3948b702b54706cd --- docs-translations/zh-CN/api/app.md | 301 ++++++++++++++--------------- 1 file changed, 146 insertions(+), 155 deletions(-) diff --git a/docs-translations/zh-CN/api/app.md b/docs-translations/zh-CN/api/app.md index 448a5a373e9..dd8d6bcfdf6 100644 --- a/docs-translations/zh-CN/api/app.md +++ b/docs-translations/zh-CN/api/app.md @@ -11,11 +11,11 @@ app.on('window-all-closed', function() { }); ``` -## 事件 +## 事件列表 `app` 对象会触发以下的事件: -### 事件: 'will-finish-launching' +### 事件:'will-finish-launching' 当应用程序完成基础的启动的时候被触发。在 Windows 和 Linux 中, `will-finish-launching` 事件与 `ready` 事件是相同的; 在 OS X 中, @@ -24,11 +24,11 @@ app.on('window-all-closed', function() { 在大多数的情况下,你应该只在 `ready` 事件处理器中完成所有的业务。 -### 事件: 'ready' +### 事件:'ready' 当 Electron 完成初始化时被触发。 -### 事件: 'window-all-closed' +### 事件:'window-all-closed' 当所有的窗口都被关闭时触发。 @@ -36,20 +36,20 @@ app.on('window-all-closed', function() { 或者开发者调用了 `app.quit()` ,Electron 将会先尝试关闭所有的窗口再触发 `will-quit` 事件, 在这种情况下 `window-all-closed` 不会被触发。 -### 事件: 'before-quit' +### 事件:'before-quit' 返回: -* `event` 事件 +* `event` Event 在应用程序开始关闭它的窗口的时候被触发。 调用 `event.preventDefault()` 将会阻止终止应用程序的默认行为。 -### 事件: 'will-quit' +### 事件:'will-quit' 返回: -* `event` 事件 +* `event` Event 当所有的窗口已经被关闭,应用即将退出时被触发。 调用 `event.preventDefault()` 将会阻止终止应用程序的默认行为。 @@ -57,20 +57,20 @@ app.on('window-all-closed', function() { 你可以在 `window-all-closed` 事件的描述中看到 `will-quit` 事件 和 `window-all-closed` 事件的区别。 -### 事件: 'quit' +### 事件:'quit' 返回: -* `event` 事件 -* `exitCode` 整数 +* `event` Event +* `exitCode` Integer 当应用程序正在退出时触发。 -### 事件: 'open-file' _OS X_ +### 事件:'open-file' _OS X_ 返回: -* `event` 事件 -* `path` 字符串 +* `event` Event +* `path` String 当用户想要在应用中打开一个文件时触发。`open-file` 事件常常在应用已经打开并且系统想要再次使用应用打开文件时被触发。 `open-file` 也会在一个文件被拖入 dock 且应用还没有运行的时候被触发。 @@ -78,73 +78,74 @@ app.on('window-all-closed', function() { 如果你想处理这个事件,你应该调用 `event.preventDefault()` 。 在 Windows系统中, 你需要通过解析 process.argv 来获取文件路径。 -### 事件: 'open-url' _OS X_ + +### 事件:'open-url' _OS X_ 返回: -* `event` 事件 -* `url` 字符串 +* `event` Event +* `url` String 当用户想要在应用中打开一个url的时候被触发。URL格式必须要提前标识才能被你的应用打开。 如果你想处理这个事件,你应该调用 `event.preventDefault()` 。 -### 事件: 'activate' _OS X_ +### 事件:'activate' _OS X_ 返回: -* `event` 事件 -* `hasVisibleWindows` 布尔值 +* `event` Event +* `hasVisibleWindows` Boolean 当应用被激活时触发,常用于点击应用的 dock 图标的时候。 -### 事件: 'browser-window-blur' +### 事件:'browser-window-blur' 返回: -* `event` 事件 -* `window` 浏览器窗口 +* `event` Event +* `window` BrowserWindow -当一个 [浏览器窗口](browser-window.md) 失去焦点的时候触发。 +当一个 [BrowserWindow](browser-window.md) 失去焦点的时候触发。 -### 事件: 'browser-window-focus' +### 事件:'browser-window-focus' 返回: -* `event` 事件 -* `window` 浏览器窗口 +* `event` Event +* `window` BrowserWindow -当一个 [浏览器窗口](browser-window.md) 获得焦点的时候触发。 +当一个 [BrowserWindow](browser-window.md) 获得焦点的时候触发。 -### 事件: 'browser-window-created' +### 事件:'browser-window-created' 返回: -* `event` 事件 -* `window` 浏览器窗口 +* `event` Event +* `window` BrowserWindow -当一个 [浏览器窗口](browser-window.md) 被创建的时候触发。 +当一个 [BrowserWindow](browser-window.md) 被创建的时候触发。 -### 事件: 'certificate-error' +### 事件:'certificate-error' 返回: -* `event` 事件 -* `webContents` [web组件](web-contents.md) -* `url` 字符串 -* `certificateList` 对象 - * `data` PEM 编码数据 - * `issuerName` 发行者的公有名称 -* `callback` 函数 +* `event` Event +* `webContents` [WebContents](web-contents.md) +* `url` String - URL 地址 +* `error` String - 错误码 +* `certificate` Object + * `data` Buffer - PEM 编码数据 + * `issuerName` String - 发行者的公有名称 +* `callback` Function -Emitted when failed to verify the `certificate` for `url`, to trust the -certificate you should prevent the default behavior with -`event.preventDefault()` and call `callback(true)`. +当对 `url` 验证 `certificate` 证书失败的时候触发,如果需要信任这个证书,你需要阻止默认行为 `event.preventDefault()` 并且 +调用 `callback(true)`。 ```javascript session.on('certificate-error', function(event, webContents, url, error, certificate, callback) { if (url == "https://github.com") { - // Verification logic. + // 验证逻辑。 event.preventDefault(); callback(true); } else { @@ -153,37 +154,37 @@ session.on('certificate-error', function(event, webContents, url, error, certifi }); ``` -### 事件: 'select-client-certificate' +### 事件:'select-client-certificate' 返回: -* `event` 事件 -* `webContents` [web组件](web-contents.md) -* `url` 字符串 -* `certificateList` 对象 - * `data` PEM 编码数据 - * `issuerName` 发行者的公有名称 -* `callback` 函数 +* `event` Event +* `webContents` [WebContents](web-contents.md) +* `url` String - URL 地址 +* `certificateList` [Object] + * `data` Buffer - PEM 编码数据 + * `issuerName` String - 发行者的公有名称 +* `callback` Function 当一个客户端认证被请求的时候被触发。 -The `url` corresponds to the navigation entry requesting the client certificate -and `callback` needs to be called with an entry filtered from the list. -Using `event.preventDefault()` prevents the application from using the first -certificate from the store. +`url` 指的是请求客户端认证的网页地址,调用 `callback` 时需要传入一个证书列表中的证书。 + +需要通过调用 `event.preventDefault()` 来防止应用自动使用第一个证书进行验证。如下所示: + ```javascript app.on('select-certificate', function(event, host, url, list, callback) { event.preventDefault(); callback(list[0]); }) ``` -### Event: 'login' +### 事件: 'login' -Returns: +返回: * `event` Event -* `webContents` [Web组件](web-contents.md) +* `webContents` [WebContents](web-contents.md) * `request` Object * `method` String * `url` URL @@ -196,11 +197,10 @@ Returns: * `realm` String * `callback` Function -当 `webContents` 要做验证时被触发。 +当 `webContents` 要做进行一次 HTTP 登陆验证时被触发。 -The default behavior is to cancel all authentications, to override this you -should prevent the default behavior with `event.preventDefault()` and call -`callback(username, password)` with the credentials. +默认情况下,Electron 会取消所有的验证行为,如果需要重写这个行为,你需要用 `event.preventDefault()` 来阻止默认行为,并且 +用 `callback(username, password)` 来进行验证。 ```javascript app.on('login', function(event, webContents, request, authInfo, callback) { @@ -208,22 +208,22 @@ app.on('login', function(event, webContents, request, authInfo, callback) { callback('username', 'secret'); }) ``` -### 事件: 'gpu-process-crashed' +### 事件:'gpu-process-crashed' -当GPU进程崩溃时触发。 +当 GPU 进程崩溃时触发。 -## 方法 +## 方法列表 `app` 对象拥有以下的方法: -**提示:** 有的方法只能用于特定的操作系统。 +**请注意** 有的方法只能用于特定的操作系统。 ### `app.quit()` -试图关掉所有的窗口。`before-quit` 事件将会被最先触发。如果所有的窗口都被成功关闭了, +试图关掉所有的窗口。`before-quit` 事件将会最先被触发。如果所有的窗口都被成功关闭了, `will-quit` 事件将会被触发,默认下应用将会被关闭。 -这个方法保证了所有的 `beforeunload` 和 `unload` 事件处理器被正确执行。会存在一个窗口被 `beforeunload` 事件处理器返回 `false` 取消退出的可能性。 +这个方法保证了所有的 `beforeunload` 和 `unload` 事件处理器被正确执行。假如一个窗口的 `beforeunload` 事件处理器返回 `false`,那么整个应用可能会取消退出。 ### `app.hide()` _OS X_ @@ -241,30 +241,29 @@ app.on('login', function(event, webContents, request, authInfo, callback) { 所有的窗口会被立刻关闭,不会询问用户。`before-quit` 和 `will-quit` 这2个事件不会被触发 - ### `app.getAppPath()` 返回当前应用所在的文件路径。 ### `app.getPath(name)` -* `name` 字符串 +* `name` String 返回一个与 `name` 参数相关的特殊文件夹或文件路径。当失败时抛出一个 `Error` 。 你可以通过名称请求以下的路径: -* `home` 用户的 home 文件夹。 -* `appData` 所有用户的应用数据文件夹,默认对应: +* `home` 用户的 home 文件夹(主目录) +* `appData` 当前用户的应用数据文件夹,默认对应: * `%APPDATA%` Windows 中 * `$XDG_CONFIG_HOME` or `~/.config` Linux 中 * `~/Library/Application Support` OS X 中 -* `userData` 储存你应用程序设置文件的文件夹,默认是 `appData` 文件夹附加应用的名称。 -* `temp` 临时文件夹。 +* `userData` 储存你应用程序设置文件的文件夹,默认是 `appData` 文件夹附加应用的名称 +* `temp` 临时文件夹 * `exe` 当前的可执行文件 -* `module` `libchromiumcontent` 库. -* `desktop` 当前用户的桌面文件夹。 -* `documents` "我的文件夹"的路径. +* `module` `libchromiumcontent` 库 +* `desktop` 当前用户的桌面文件夹 +* `documents` 用户文档目录的路径 * `downloads` 用户下载目录的路径. * `music` 用户音乐目录的路径. * `pictures` 用户图片目录的路径. @@ -272,14 +271,14 @@ app.on('login', function(event, webContents, request, authInfo, callback) { ### `app.setPath(name, path)` -* `name` 字符串 -* `path` 字符串 +* `name` String +* `path` String -重写 `path` 参数到一个特别的文件夹或者是一个和 `name` 参数有关系的文件。 +重写某个 `name` 的路径为 `path`,`path` 可以是一个文件夹或者一个文件,这个和 `name` 的类型有关。 如果这个路径指向的文件夹不存在,这个文件夹将会被这个方法创建。 -如果错误则抛出 `Error` 。 +如果错误则会抛出 `Error`。 -你只可以指向 `app.getPath` 中定义过 `name` 的路径。 +`name` 参数只能使用 `app.getPath` 中定义过 `name`。 默认情况下,网页的 cookie 和缓存都会储存在 `userData` 文件夹。 如果你想要改变这个位置,你需要在 `app` 模块中的 `ready` 事件被触发之前重写 `userData` 的路径。 @@ -293,22 +292,20 @@ app.on('login', function(event, webContents, request, authInfo, callback) { 返回当前应用程序的 `package.json` 文件中的名称。 -通常 `name` 字段是一个短的小写字符串,其命名规则按照 npm 中的模块命名规则。你应该单独列举一个 -`productName` 字段,用于表示你的应用程序的完整名称,这个名称将会被 Electron 优先采用。 +由于 npm 的命名规则,通常 `name` 字段是一个短的小写字符串。但是应用名的完整名称通常是首字母大写的,你应该单独使用一个 +`productName` 字段,用于表示你的应用程序的完整名称。Electron 会优先使用这个字段作为应用名。 ### `app.getLocale()` -返回当前应用程序的语言种类。 - - +返回当前应用程序的语言。 ### `app.addRecentDocument(path)` _OS X_ _Windows_ -* `path` 字符串 +* `path` String -为最近访问的文档列表中添加 `path` 。 +在最近访问的文档列表中添加 `path`。 -这个列表由操作系统进行管理。在 Windows 中您可以通过任务条进行访问,在 OS X 中你可以通过dock 菜单进行访问。 +这个列表由操作系统进行管理。在 Windows 中您可以通过任务条进行访问,在 OS X 中你可以通过 dock 菜单进行访问。 ### `app.clearRecentDocuments()` _OS X_ _Windows_ @@ -316,66 +313,55 @@ app.on('login', function(event, webContents, request, authInfo, callback) { ### `app.setUserTasks(tasks)` _Windows_ -* `tasks` 由 `Task` 对象构成的数组 +* `tasks` [Task] - 一个由 Task 对象构成的数组 将 `tasks` 添加到 Windows 中 JumpList 功能的 [Tasks][tasks] 分类中。 `tasks` 中的 `Task` 对象格式如下: -`Task` 对象 -* `program` 字符串 - 执行程序的路径,通常你应该说明当前程序的路径为 `process.execPath` 字段。 -* `arguments` 字符串 - 当 `program` 执行时的命令行参数。 -* `title` 字符串 - JumpList 中显示的标题。 -* `description` 字符串 - 对这个任务的描述。 -* `iconPath` 字符串 - JumpList 中显示的 icon 的绝对路径,可以是一个任意包含一个icon的资源文件。你通常可以通过指明 `process.execPath` 来显示程序中的icon。 -* `iconIndex` 整数 - icon文件中的icon目录。如果一个icon文件包括了两个或多个icon,就需要设置这个值以确定icon。如果一个文件仅包含一个icon,那么这个值为0。 +`Task` Object +* `program` String - 执行程序的路径,通常你应该说明当前程序的路径为 `process.execPath` 字段。 +* `arguments` String - 当 `program` 执行时的命令行参数。 +* `title` String - JumpList 中显示的标题。 +* `description` String - 对这个任务的描述。 +* `iconPath` String - JumpList 中显示的图标的绝对路径,可以是一个任意包含一个图标的资源文件。通常来说,你可以通过指明 `process.execPath` 来显示程序中的图标。 +* `iconIndex` Integer - 图标文件中的采用的图标位置。如果一个图标文件包括了多个图标,就需要设置这个值以确定使用的是哪一个图标。 +如果这个图标文件中只包含一个图标,那么这个值为 0。 ### `app.allowNTLMCredentialsForAllDomains(allow)` * `allow` Boolean -Dynamically sets whether to always send credentials for HTTP NTLM or Negotiate -authentication - normally, Electron will only send NTLM/Kerberos credentials for -URLs that fall under "Local Intranet" sites (i.e. are in the same domain as you). -However, this detection often fails when corporate networks are badly configured, -so this lets you co-opt this behavior and enable it for all URLs. +动态设置是否总是为 HTTP NTLM 或 Negotiate 认证发送证书。通常来说,Electron 只会对本地网络(比如和你处在一个域中的计算机)发 +送 NTLM / Kerberos 证书。但是假如网络设置得不太好,可能这个自动探测会失效,所以你可以通过这个接口自定义 Electron 对所有 URL +的行为。 + ### `app.makeSingleInstance(callback)` * `callback` Function -This method makes your application a Single Instance Application - instead of -allowing multiple instances of your app to run, this will ensure that only a -single instance of your app is running, and other instances signal this -instance and exit. +这个方法可以让你的应用在同一时刻最多只会有一个实例,否则你的应用可以被运行多次并产生多个实例。你可以利用这个接口保证只有一个实例正 +常运行,其余的实例全部会被终止并退出。 -`callback` will be called with `callback(argv, workingDirectory)` when a second -instance has been executed. `argv` is an Array of the second instance's command -line arguments, and `workingDirectory` is its current working directory. Usually -applications respond to this by making their primary window focused and -non-minimized. +如果多个实例同时运行,那么第一个被运行的实例中 `callback` 会以 `callback(argv, workingDirectory)` 的形式被调用。其余的实例 +会被终止。 +`argv` 是一个包含了这个实例的命令行参数列表的数组,`workingDirectory` 是这个实例目前的运行目录。通常来说,我们会用通过将应用在 +主屏幕上激活,并且取消最小化,来提醒用户这个应用已经被打开了。 -The `callback` is guaranteed to be executed after the `ready` event of `app` -gets emitted. +在 `app` 的 `ready` 事件后,`callback` 才有可能被调用。 -This method returns `false` if your process is the primary instance of the -application and your app should continue loading. And returns `true` if your -process has sent its parameters to another instance, and you should immediately -quit. +如果当前实例为第一个实例,那么在这个方法将会返回 `false` 来保证它继续运行。否则将会返回 `true` 来让它立刻退出。 -On OS X the system enforces single instance automatically when users try to open -a second instance of your app in Finder, and the `open-file` and `open-url` -events will be emitted for that. However when users start your app in command -line the system's single instance machanism will be bypassed and you have to -use this method to ensure single instance. +在 OS X 中,如果用户通过 Finder、`open-file` 或者 `open-url` 打开应用,系统会强制确保只有一个实例在运行。但是如果用户是通过 +命令行打开,这个系统机制会被忽略,所以你仍然需要靠这个方法来保证应用为单实例运行的。 -An example of activating the window of primary instance when a second instance -starts: +下面是一个简单的例子。我们可以通过这个例子了解如何确保应用为单实例运行状态。 ```js var myWindow = null; var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) { - // Someone tried to run a second instance, we should focus our window. + // 当另一个实例运行的时候,这里将会被调用,我们需要激活应用的窗口 if (myWindow) { if (myWindow.isMinimized()) myWindow.restore(); myWindow.focus(); @@ -383,104 +369,109 @@ var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) return true; }); +// 这个实例是多余的实例,需要退出 if (shouldQuit) { app.quit(); return; } -// Create myWindow, load the rest of the app, etc... +// 创建窗口、继续加载应用、应用逻辑等…… app.on('ready', function() { }); + ``` ### `app.setAppUserModelId(id)` _Windows_ * `id` String -改变 [Application User Model ID][app-user-model-id] 的 `id`. +改变当前应用的 [Application User Model ID][app-user-model-id] 为 `id`. ### `app.isAeroGlassEnabled()` _Windows_ -This method returns `true` if [DWM composition](https://msdn.microsoft.com/en-us/library/windows/desktop/aa969540.aspx) -(Aero Glass) is enabled, and `false` otherwise. You can use it to determine if -you should create a transparent window or not (transparent windows won't work -correctly when DWM composition is disabled). +如果 [DWM composition](https://msdn.microsoft.com/en-us/library/windows/desktop/aa969540.aspx)(Aero Glass) 启用 +了,那么这个方法会返回 `true`,否则是 `false`。你可以用这个方法来决定是否要开启透明窗口特效,因为如果用户没开启 DWM,那么透明窗 +口特效是无效的。 -Usage example: +举个例子: ```js let browserOptions = {width: 1000, height: 800}; -// Make the window transparent only if the platform supports it. +// 只有平台支持的时候才使用透明窗口 if (process.platform !== 'win32' || app.isAeroGlassEnabled()) { browserOptions.transparent = true; browserOptions.frame = false; } -// Create the window. +// 创建窗口 win = new BrowserWindow(browserOptions); -// Navigate. +// 转到某个网页 if (browserOptions.transparent) { win.loadURL('file://' + __dirname + '/index.html'); } else { - // No transparency, so we load a fallback that uses basic styles. + // 没有透明特效,我们应该用某个只包含基本样式的替代解决方案。 win.loadURL('file://' + __dirname + '/fallback.html'); } ``` ### `app.commandLine.appendSwitch(switch[, value])` -通过可选的参数 `value` 给 Chromium 命令行中添加一个开关。 -Append a switch (with optional `value`) to Chromium's command line. +通过可选的参数 `value` 给 Chromium 中添加一个命令行开关。 -**贴士:** 这不会影响 `process.argv` ,这个方法主要被开发者用于控制一些低层级的 Chromium 行为。 +**注意** 这个方法不会影响 `process.argv`,我们通常用这个方法控制一些底层 Chromium 行为。 ### `app.commandLine.appendArgument(value)` -给 Chromium 命令行中加入一个参数。这个参数是当前正在被引用的。 +给 Chromium 中直接添加一个命令行参数,这个参数 `value` 的引号和格式必须正确。 -**贴士:** 这不会影响 `process.argv`。 +**注意** 这个方法不会影响 `process.argv`。 ### `app.dock.bounce([type])` _OS X_ -* `type` 字符串 (可选的) - 可以是 `critical` 或 `informational`。默认下是 `informational` +* `type` String - 可选参数,可以是 `critical` 或 `informational`。默认为 `informational`。 -当输入 `critical` 时,dock 中的 icon 将会开始弹跳直到应用被激活或者这个请求被取消。 +当传入的是 `critical` 时,dock 中的应用将会开始弹跳,直到这个应用被激活或者这个请求被取消。 -当输入 `informational` 时,dock 中的 icon 只会弹跳一秒钟。 -然而,这个请求仍然会激活,直到应用被激活或者请求被取消。 +当传入的是 `informational` 时,dock 中的图标只会弹跳一秒钟。但是,这个请求仍然会激活,直到应用被激活或者请求被取消。 -返回一个表示这个请求的 ID。 +这个方法返回的返回值表示这个请求的 ID。 ### `app.dock.cancelBounce(id)` _OS X_ -* `id` 整数 +* `id` Integer 取消这个 `id` 对应的请求。 ### `app.dock.setBadge(text)` _OS X_ -* `text` 字符串 +* `text` String -设置 dock 中显示的字符。 +设置应用在 dock 中显示的字符串。 ### `app.dock.getBadge()` _OS X_ -返回 dock 中显示的字符。 +返回应用在 dock 中显示的字符串。 ### `app.dock.hide()` _OS X_ -隐藏 dock 中的 icon。 +隐藏应用在 dock 中的图标。 ### `app.dock.show()` _OS X_ -显示 dock 中的 icon。 +显示应用在 dock 中的图标。 ### `app.dock.setMenu(menu)` _OS X_ -* `menu` 菜单 +* `menu` [Menu](menu.md) 设置应用的 [dock 菜单][dock-menu]. +### `app.dock.setIcon(image)` _OS X_ + +* `image` [NativeImage](native-image.md) + +设置应用在 dock 中显示的图标。 + [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx From a05e98f4638909bf1557755a0d9838d4988328b9 Mon Sep 17 00:00:00 2001 From: Magica Date: Sun, 21 Feb 2016 14:09:34 +0800 Subject: [PATCH 280/688] Translate auto-updater.md in commit 45739ce434ec3c3eb190d35d3948b702b54706cd --- docs-translations/zh-CN/api/auto-updater.md | 88 +++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 docs-translations/zh-CN/api/auto-updater.md diff --git a/docs-translations/zh-CN/api/auto-updater.md b/docs-translations/zh-CN/api/auto-updater.md new file mode 100644 index 00000000000..f027fbc6e50 --- /dev/null +++ b/docs-translations/zh-CN/api/auto-updater.md @@ -0,0 +1,88 @@ +# autoUpdater + +这个模块提供了一个到 `Squirrel` 自动更新框架的接口。 + +## 平台相关的提示 + +虽然 `autoUpdater` 模块提供了一套各平台通用的接口,但是在每个平台间依然会有一些微小的差异。 + +### OS X + +在 OS X 上,`autoUpdater` 模块依靠的是内置的 [Squirrel.Mac][squirrel-mac],这意味着你不需要依靠其他的设置就能使用。关于 +更新服务器的配置,你可以通过阅读 [Server Support][server-support] 这篇文章来了解。 + +### Windows + +在 Windows 上,你必须使用安装程序将你的应用装到用户的计算机上,所以比较推荐的方法是用 [grunt-electron-installer][installer] 这个模块来自动生成一个 Windows 安装向导。 + +Squirrel 自动生成的安装向导会生成一个带 [Application User Model ID][app-user-model-id] 的快捷方式。 +Application User Model ID 的格式是 `com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE`, 比如 +像 `com.squirrel.slack.Slack` 和 `com.squirrel.code.Code` 这样的。你应该在自己的应用中使用 `app.setAppUserModelId` 方法设置相同的 API,不然 Windows 将不能正确地把你的应用固定在任务栏上。 + +服务器端的配置和 OS X 也是不一样的,你可以阅读 [Squirrel.Windows][squirrel-windows] 这个文档来获得详细信息。 + +### Linux + +Linux 下没有任何的自动更新支持,所以我们推荐用各个 Linux 发行版的包管理器来分发你的应用。 + +## 事件列表 + +`autoUpdater` 对象会触发以下的事件: + +### 事件:'error' + +返回: + +* `error` Error + +当更新发生错误的时候触发。 + +### 事件:'checking-for-update' + +当开始检查更新的时候触发。 + +### 事件:'update-available' + +当发现一个可用更新的时候触发,更新包下载会自动开始。 + +### 事件:'update-not-available' + +当没有可用更新的时候触发。 + +### 事件:'update-downloaded' + +返回: + +* `event` Event +* `releaseNotes` String - 新版本更新公告 +* `releaseName` String - 新的版本号 +* `releaseDate` Date - 新版本发布的日期 +* `updateURL` String - 更新地址 + +在更新下载完成的时候触发。 + +在 Windows 上只有 `releaseName` 是有效的。 + +## 方法列表 + +`autoUpdater` 对象有以下的方法: + +### `autoUpdater.setFeedURL(url)` + +* `url` String + +设置检查更新的 `url`,并且初始化自动更新。这个 `url` 一旦设置就无法更改。 + +### `autoUpdater.checkForUpdates()` + +向服务端查询现在是否有可用的更新。在调用这个方法之前,必须要先调用 `setFeedURL`。 + +### `autoUpdater.quitAndInstall()` + +在下载完成后,重启当前的应用并且安装更新。这个方法应该仅在 `update-downloaded` 事件触发后被调用。 + +[squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac +[server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support +[squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows +[installer]: https://github.com/atom/grunt-electron-installer +[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx From 078c7bf8ab2293ebb1a5b0bde489a5f6da42c443 Mon Sep 17 00:00:00 2001 From: Dongjoon Hyun Date: Sun, 21 Feb 2016 00:14:34 -0800 Subject: [PATCH 281/688] Rename constant `PERSIST_PERFIX` to `PERSIST_PREFIX` in `session.js`. --- atom/browser/api/lib/session.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/lib/session.js b/atom/browser/api/lib/session.js index dc65264349f..8662759192d 100644 --- a/atom/browser/api/lib/session.js +++ b/atom/browser/api/lib/session.js @@ -1,6 +1,6 @@ const EventEmitter = require('events').EventEmitter; const bindings = process.atomBinding('session'); -const PERSIST_PERFIX = 'persist:'; +const PERSIST_PREFIX = 'persist:'; // Returns the Session from |partition| string. exports.fromPartition = function(partition) { @@ -10,8 +10,8 @@ exports.fromPartition = function(partition) { if (partition === '') { return exports.defaultSession; } - if (partition.startsWith(PERSIST_PERFIX)) { - return bindings.fromPartition(partition.substr(PERSIST_PERFIX.length), false); + if (partition.startsWith(PERSIST_PREFIX)) { + return bindings.fromPartition(partition.substr(PERSIST_PREFIX.length), false); } else { return bindings.fromPartition(partition, true); } From f63532fa9558dc435764ea8b94f4acdb38ae8469 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 19 Feb 2016 09:39:43 +0900 Subject: [PATCH 282/688] :memo: Update as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 2 +- docs-translations/ko-KR/tutorial/using-widevine-cdm-plugin.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 89cc1732263..048026e0d59 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -164,7 +164,7 @@ Returns: 기본 동작을 방지하고 인증을 승인할 수 있습니다. ```javascript -session.on('certificate-error', function(event, webContents, url, error, certificate, callback) { +app.on('certificate-error', function(event, webContents, url, error, certificate, callback) { if (url == "https://github.com") { // Verification logic. event.preventDefault(); diff --git a/docs-translations/ko-KR/tutorial/using-widevine-cdm-plugin.md b/docs-translations/ko-KR/tutorial/using-widevine-cdm-plugin.md index d729c0efc08..b9fec886769 100644 --- a/docs-translations/ko-KR/tutorial/using-widevine-cdm-plugin.md +++ b/docs-translations/ko-KR/tutorial/using-widevine-cdm-plugin.md @@ -8,6 +8,10 @@ Electron은 라이센스상의 문제로 Widevine CDM 플러그인을 직접 제 따라서 플러그인을 얻으려면 먼저 사용할 Electron 빌드의 아키텍쳐와 버전에 맞춰 공식 Chrome 브라우저를 설치해야 합니다. +__참고:__ Chrome 브라우저의 메이저 버전은 Electron에서 사용하는 Chrome 버전과 +같습니다, 만약 그렇지 않다면 `navigator.plugins`가 로드됐더라도 정상적으로 작동하지 +않습니다. + ### Windows & OS X Chrome 브라우저에서 `chrome://components/`를 열고 `WidevineCdm`을 찾은 후 확실히 From 9e1da8f097bf22b3cef4d0a4d4b3dee1c179d428 Mon Sep 17 00:00:00 2001 From: Takahito Yamatoya Date: Mon, 22 Feb 2016 00:59:18 +0900 Subject: [PATCH 283/688] Update as upstream --- docs-translations/jp/faq/electron-faq.md | 25 +++++++++++++++ .../desktop-environment-integration.md | 32 +++++++++++++++---- docs-translations/jp/tutorial/quick-start.md | 4 +++ .../tutorial/using-selenium-and-webdriver.md | 2 +- .../jp/tutorial/using-widevine-cdm-plugin.md | 2 ++ 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/docs-translations/jp/faq/electron-faq.md b/docs-translations/jp/faq/electron-faq.md index c8a65227717..eef30c013a3 100644 --- a/docs-translations/jp/faq/electron-faq.md +++ b/docs-translations/jp/faq/electron-faq.md @@ -12,6 +12,27 @@ Node.js の新しいバージョンがリリースされたとき、私たちは 通常、Node.js の新しい機能は V8 のアップグレードによってもたらされますが、Electron は Chrome ブラウザーに搭載されている V8 を使用しているので、新しい Node.js に入ったばかりのピカピカに新しい JavaScript 機能は Electron ではたいてい既に導入されています。 +## ウェブページ間のデータを共有する方法は? + +ウェブページ(レンダラープロセス)間のデータを共有するために最も単純な方法は、ブラウザで、すでに提供されているHTML5 APIを使用することです。もっとも良い方法は、[Storage API][storage]、[`localStorage`][local-storage]、[`sessionStorage`][session-storage]、[IndexedDB][indexed-db]です。 + +```javascript +// In the main process. +global.sharedObject = { + someProperty: 'default value' +}; +``` + +```javascript +// In page 1. +require('remote').getGlobal('sharedObject').someProperty = 'new value'; +``` + +```javascript +// In page 2. +console.log(require('remote').getGlobal('sharedObject').someProperty); +``` + ## 何分か経つと、アプリの Window/tray が消えてしまいます これは、Window/trayを格納するのに使用している変数がガベージコレクトされたときに発生します。 @@ -104,3 +125,7 @@ npm uninstall -g electron [memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx [electron-module]: https://www.npmjs.com/package/electron +[storage]: https://developer.mozilla.org/en-US/docs/Web/API/Storage +[local-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage +[session-storage]: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage +[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API diff --git a/docs-translations/jp/tutorial/desktop-environment-integration.md b/docs-translations/jp/tutorial/desktop-environment-integration.md index 0ef44b2f47c..96bf76d7370 100644 --- a/docs-translations/jp/tutorial/desktop-environment-integration.md +++ b/docs-translations/jp/tutorial/desktop-environment-integration.md @@ -210,6 +210,23 @@ var window = new BrowserWindow({...}); window.setProgressBar(0.5); ``` +## タスクバーでアイコンをオーバーレイする (Windows) + +Windowsで、タスクバーボタンはアプリケーションステータスを表示するために小さなオーバーレイを使うことができます。MSDNから引用します。 + +> アイコン オーバーレイは、状況に応じた状態通知として機能し、通知領域に状態アイコンを個別に表示する必要性をなくして、情報をユーザーに伝えることを目的としています。たとえば、現在、通知領域に表示される Microsoft Office Outlook の新着メールの通知は、タスク バー ボタンのオーバーレイとして表示できるようになります。ここでも、開発サイクルの間に、アプリケーションに最適な方法を決定する必要があります。アイコン オーバーレイは、重要で長期にわたる状態や通知 (ネットワークの状態、メッセンジャーの状態、新着メールなど) を提供することを目的としています。ユーザーに対して、絶えず変化するオーバーレイやアニメーションを表示しないようにしてください。 + +__タスクバーボタンでのオーバーレイ:__ + +![Overlay on taskbar button](https://i-msdn.sec.s-msft.com/dynimg/IC420441.png) + +ウィンドウでオーバーレイアイコンを設定するために、[BrowserWindow.setOverlayIcon][setoverlayicon] APIを使用できます。 + +```javascript +var window = new BrowserWindow({...}); +window.setOverlayIcon('path/to/overlay.png', 'Description for overlay'); +``` + ## Windowのファイル表示 (OS X) OS Xでは、ウィンドウがrepresented fileを設定でき、タイトルバー上にファイルのアイコンを表示でき、タイトル上でCommand-クリックまたはControl-クリックをすると、パスがポップアップ表示されます。 @@ -228,15 +245,16 @@ window.setRepresentedFilename('/etc/passwd'); window.setDocumentEdited(true); ``` -[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath -[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments -[setusertaskstasks]: ../api/app.md#appsetusertaskstasks -[setprogressbar]: ../api/browser-window.md#browserwindowsetprogressbarprogress -[setrepresentedfilename]: ../api/browser-window.md#browserwindowsetrepresentedfilenamefilename -[setdocumentedited]: ../api/browser-window.md#browserwindowsetdocumenteditededited +[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath-os-x-windows +[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-os-x-windows +[setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows +[setprogressbar]: ../api/browser-window.md#winsetprogressbarprogress +[setoverlayicon]: ../api/browser-window.md#winsetoverlayiconoverlay-description-windows-7 +[setrepresentedfilename]: ../api/browser-window.md#winsetrepresentedfilenamefilename-os-x +[setdocumentedited]: ../api/browser-window.md#winsetdocumenteditededited-os-x [app-registration]: http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx [unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher -[setthumbarbuttons]: ../api/browser-window.md#browserwindowsetthumbarbuttonsbuttons +[setthumbarbuttons]: ../api/browser-window.md#winsetthumbarbuttonsbuttons-windows-7 [tray-balloon]: ../api/tray.md#traydisplayballoonoptions-windows [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx [notification-spec]: https://developer.gnome.org/notification-spec/ diff --git a/docs-translations/jp/tutorial/quick-start.md b/docs-translations/jp/tutorial/quick-start.md index bfb6e2a51f7..4f2e5c9a52e 100644 --- a/docs-translations/jp/tutorial/quick-start.md +++ b/docs-translations/jp/tutorial/quick-start.md @@ -24,6 +24,8 @@ Electron はウェブページを表示させるために Chromium を使用し Electron では、メインプロセスとレンダラープロセスとのコミュニケーションをするために [ipc](../api/ipc-renderer.md) モジュールを提供しています。またそれと、RPC 形式の通信を行う [remote](../api/remote.md) モジュールもあります。 +Electron では、メインプロセスとレンダラープロセスとのコミュニケーションをするには幾つかのほうほうがあります。メッセージを送信する[`ipcRenderer`](../api/ipc-renderer.md)モジュールと[`ipcMain`](../api/ipc-main.md)モジュールのように、RPC 形式の通信を行う[remote](../api/remote.md)モジュールです。[ウェブページ間のデータを共有する方法][share-data]にFAQエントリーがあります。 + ## Electronアプリを作成する 一般的に Electron アプリの構成は次のようになります: @@ -169,3 +171,5 @@ $ cd electron-quick-start # Install dependencies and run the app $ npm install && npm start ``` + +[share-data]: ../faq/electron-faq.md#how-to-share-data-between-web-pages diff --git a/docs-translations/jp/tutorial/using-selenium-and-webdriver.md b/docs-translations/jp/tutorial/using-selenium-and-webdriver.md index 3202028ebf5..a1fd0f21d7f 100644 --- a/docs-translations/jp/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/jp/tutorial/using-selenium-and-webdriver.md @@ -41,7 +41,7 @@ var driver = new webdriver.Builder() .withCapabilities({ chromeOptions: { // Here is the path to your Electron binary. - binary: '/Path-to-Your-App.app/Contents/MacOS/Atom', + binary: '/Path-to-Your-App.app/Contents/MacOS/Electron', } }) .forBrowser('electron') diff --git a/docs-translations/jp/tutorial/using-widevine-cdm-plugin.md b/docs-translations/jp/tutorial/using-widevine-cdm-plugin.md index 5cee7f26dc6..55f9d039f61 100644 --- a/docs-translations/jp/tutorial/using-widevine-cdm-plugin.md +++ b/docs-translations/jp/tutorial/using-widevine-cdm-plugin.md @@ -6,6 +6,8 @@ Electronで、Chromeブラウザーに同梱される Widevine CDMプラグイ Electronは、ライセンス的な理由でWidevine CDMプラグインは同梱されません。Widevine CDMプラグインを取得するために、最初に、使用するElectronビルドのChromバージョンとアーキテクチャを合わせた公式のChromeブラウザーをインストールする必要があります。 +__Note:__ Chromeブラウザの主要バージョンは、Electronが使用するChromeバージョンと同じでなければなりません。そうでなければ、プラグインは、`navigator.plugins`経由でロードされて表示されるにも関わらず動作しません。 + ### Windows & OS X Chromeブラウザーで、`chrome://components/`を開き、 `WidevineCdm` を探し、それが最新であることを確認し、`APP_DATA/Google/Chrome/WidevineCDM/VERSION/_platform_specific/PLATFORM_ARCH/`ディレクトリからすべてのプラグインバイナリを探します。 From 67324ce732f7cf88d4850f1584d048387bb8385b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 10:52:21 +0800 Subject: [PATCH 284/688] Keep the prototype chain in remote objects --- atom/browser/lib/rpc-server.js | 57 ++++++++--- atom/renderer/api/lib/remote.js | 173 +++++++++++++++----------------- 2 files changed, 127 insertions(+), 103 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index 976a42331b6..64785879b3f 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -6,11 +6,52 @@ const objectsRegistry = require('./objects-registry'); const v8Util = process.atomBinding('v8_util'); const IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap; +// The internal properties of Function. +const FUNCTION_PROPERTIES = [ + 'length', 'name', 'arguments', 'caller', 'prototype', +]; + var slice = [].slice; +// Return the description of object's members: +let getObjectMemebers = function(object) { + let names = Object.getOwnPropertyNames(object); + // For Function, we should not override following properties even though they + // are "own" properties. + if (typeof object === 'function') { + names = names.filter((name) => { + return !FUNCTION_PROPERTIES.includes(name); + }); + } + // Map properties to descriptors. + return names.map((name) => { + let descriptor = Object.getOwnPropertyDescriptor(object, name); + let member = {name, enumerable: descriptor.enumerable, writable: false}; + if (descriptor.get === undefined && typeof object[name] === 'function') { + member.type = 'method'; + } else { + if (descriptor.set || descriptor.writable) + member.writable = true; + member.type = 'get'; + } + return member; + }); +}; + +// Return the description of object's prototype. +let getObjectPrototype = function(object) { + let proto = Object.getPrototypeOf(object); + if (proto === null || proto === Object.prototype) + return null; + return { + members: getObjectMemebers(proto), + proto: getObjectPrototype(proto), + }; +}; + // Convert a real value into meta data. var valueToMeta = function(sender, value, optimizeSimpleObject) { - var el, field, i, len, meta, name; + var el, i, len, meta; if (optimizeSimpleObject == null) { optimizeSimpleObject = false; } @@ -58,18 +99,8 @@ var valueToMeta = function(sender, value, optimizeSimpleObject) { // passed to renderer we would assume the renderer keeps a reference of // it. meta.id = objectsRegistry.add(sender.getId(), value); - meta.members = (function() { - var results; - results = []; - for (name in value) { - field = value[name]; - results.push({ - name: name, - type: typeof field - }); - } - return results; - })(); + meta.members = getObjectMemebers(value); + meta.proto = getObjectPrototype(value); } else if (meta.type === 'buffer') { meta.value = Array.prototype.slice.call(value, 0); } else if (meta.type === 'promise') { diff --git a/atom/renderer/api/lib/remote.js b/atom/renderer/api/lib/remote.js index d8a5508621e..d28ec6dfcbd 100644 --- a/atom/renderer/api/lib/remote.js +++ b/atom/renderer/api/lib/remote.js @@ -1,3 +1,5 @@ +'use strict'; + const ipcRenderer = require('electron').ipcRenderer; const CallbacksRegistry = require('electron').CallbacksRegistry; const v8Util = process.atomBinding('v8_util'); @@ -88,9 +90,59 @@ var wrapArgs = function(args, visited) { return Array.prototype.slice.call(args).map(valueToMeta); }; +// Populate object's members from descriptors. +// This matches |getObjectMemebers| in rpc-server. +let setObjectMembers = function(object, metaId, members) { + for (let member of members) { + if (object.hasOwnProperty(member.name)) + continue; + + let descriptor = { enumerable: member.enumerable }; + if (member.type === 'method') { + let remoteMemberFunction = function() { + if (this && this.constructor === remoteMemberFunction) { + // Constructor call. + let ret = ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_CONSTRUCTOR', metaId, member.name, wrapArgs(arguments)); + return metaToValue(ret); + } else { + // Call member function. + let ret = ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_CALL', metaId, member.name, wrapArgs(arguments)); + return metaToValue(ret); + } + }; + descriptor.value = remoteMemberFunction; + } else if (member.type === 'get') { + descriptor.get = function() { + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_GET', metaId, member.name)); + }; + + // Only set setter when it is writable. + if (member.writable) { + descriptor.set = function(value) { + ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_SET', metaId, member.name, value); + return value; + }; + } + } + + Object.defineProperty(object, member.name, descriptor); + } +}; + +// Populate object's prototype from descriptor. +// This matches |getObjectPrototype| in rpc-server. +let setObjectPrototype = function(object, metaId, descriptor) { + if (descriptor === null) + return; + let proto = {}; + setObjectMembers(proto, metaId, descriptor.members); + setObjectPrototype(proto, metaId, descriptor.proto); + Object.setPrototypeOf(object, proto); +}; + // Convert meta data from browser into real value. var metaToValue = function(meta) { - var el, i, j, len, len1, member, ref1, ref2, results, ret; + var el, i, len, ref1, results, ret; switch (meta.type) { case 'value': return meta.value; @@ -115,55 +167,42 @@ var metaToValue = function(meta) { case 'exception': throw new Error(meta.message + "\n" + meta.stack); default: - if (meta.type === 'function') { - // A shadow class to represent the remote function object. - ret = (function() { - function RemoteFunction() { - var obj; - if (this.constructor === RemoteFunction) { - - // Constructor call. - obj = ipcRenderer.sendSync('ATOM_BROWSER_CONSTRUCTOR', meta.id, wrapArgs(arguments)); - - /* - Returning object in constructor will replace constructed object - with the returned object. - http://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this - */ - return metaToValue(obj); - } else { - - // Function call. - obj = ipcRenderer.sendSync('ATOM_BROWSER_FUNCTION_CALL', meta.id, wrapArgs(arguments)); - return metaToValue(obj); - } - } - - return RemoteFunction; - - })(); - } else { - ret = v8Util.createObjectWithName(meta.name); - } - - // Polulate delegate members. - ref2 = meta.members; - for (j = 0, len1 = ref2.length; j < len1; j++) { - member = ref2[j]; - if (member.type === 'function') { - ret[member.name] = createRemoteMemberFunction(meta.id, member.name); - } else { - Object.defineProperty(ret, member.name, createRemoteMemberProperty(meta.id, member.name)); - } - } - if (remoteObjectCache.has(meta.id)) return remoteObjectCache.get(meta.id); + if (meta.type === 'function') { + // A shadow class to represent the remote function object. + let remoteFunction = function() { + if (this && this.constructor === remoteFunction) { + // Constructor call. + let obj = ipcRenderer.sendSync('ATOM_BROWSER_CONSTRUCTOR', meta.id, wrapArgs(arguments)); + // Returning object in constructor will replace constructed object + // with the returned object. + // http://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this + return metaToValue(obj); + } else { + // Function call. + let obj = ipcRenderer.sendSync('ATOM_BROWSER_FUNCTION_CALL', meta.id, wrapArgs(arguments)); + return metaToValue(obj); + } + }; + ret = remoteFunction; + } else { + ret = {}; + } + + // Populate delegate members. + setObjectMembers(ret, meta.id, meta.members); + // Populate delegate prototype. + setObjectPrototype(ret, meta.id, meta.proto); + + // Set constructor.name to object's name. + Object.defineProperty(ret.constructor, 'name', { value: meta.name }); + // Track delegate object's life time, and tell the browser to clean up // when the object is GCed. v8Util.setDestructor(ret, function() { - return ipcRenderer.send('ATOM_BROWSER_DEREFERENCE', meta.id); + ipcRenderer.send('ATOM_BROWSER_DEREFERENCE', meta.id); }); // Remember object's id. @@ -192,52 +231,6 @@ var metaToPlainObject = function(meta) { return obj; }; -// Create a RemoteMemberFunction instance. -// This function's content should not be inlined into metaToValue, otherwise V8 -// may consider it circular reference. -var createRemoteMemberFunction = function(metaId, name) { - return (function() { - function RemoteMemberFunction() { - var ret; - if (this.constructor === RemoteMemberFunction) { - - // Constructor call. - ret = ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_CONSTRUCTOR', metaId, name, wrapArgs(arguments)); - return metaToValue(ret); - } else { - - // Call member function. - ret = ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_CALL', metaId, name, wrapArgs(arguments)); - return metaToValue(ret); - } - } - - return RemoteMemberFunction; - - })(); -}; - -// Create configuration for defineProperty. -// This function's content should not be inlined into metaToValue, otherwise V8 -// may consider it circular reference. -var createRemoteMemberProperty = function(metaId, name) { - return { - enumerable: true, - configurable: false, - set: function(value) { - - // Set member data. - ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_SET', metaId, name, value); - return value; - }, - get: function() { - - // Get member data. - return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_GET', metaId, name)); - } - }; -}; - // Browser calls a callback in renderer. ipcRenderer.on('ATOM_RENDERER_CALLBACK', function(event, id, args) { return callbacksRegistry.apply(id, metaToValue(args)); From f610e332b3e31d9713724d701798e3f945da7311 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 12:13:26 +0800 Subject: [PATCH 285/688] spec: Tests for remote ES6 class --- spec/api-ipc-spec.js | 37 +++++++++++++++++++++++++++++++++++ spec/fixtures/module/class.js | 29 +++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 spec/fixtures/module/class.js diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 9cf741412b0..90e099fa612 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -1,3 +1,5 @@ +'use strict'; + const assert = require('assert'); const path = require('path'); @@ -98,6 +100,41 @@ describe('ipc module', function() { }); }); + describe('remote class', function() { + let cl = remote.require(path.join(fixtures, 'module', 'class.js')); + let base = cl.base; + let derived = cl.derived; + + it('can get methods', function() { + assert.equal(base.method(), 'method'); + }); + + it('can get properties', function() { + assert.equal(base.readonly, 'readonly'); + }); + + it('can change properties', function() { + assert.equal(base.value, 'old'); + base.value = 'new'; + assert.equal(base.value, 'new'); + base.value = 'old'; + }); + + it('has unenumerable methods', function() { + assert(!base.hasOwnProperty('method')); + assert(Object.getPrototypeOf(base).hasOwnProperty('method')); + }); + + it('keeps prototype chain in derived class', function() { + assert.equal(derived.method(), 'method'); + assert.equal(derived.readonly, 'readonly'); + assert(!derived.hasOwnProperty('method')); + let proto = Object.getPrototypeOf(derived); + assert(!proto.hasOwnProperty('method')); + assert(Object.getPrototypeOf(proto).hasOwnProperty('method')); + }); + }); + describe('ipc.sender.send', function() { it('should work when sending an object containing id property', function(done) { var obj = { diff --git a/spec/fixtures/module/class.js b/spec/fixtures/module/class.js new file mode 100644 index 00000000000..f25eb2593ff --- /dev/null +++ b/spec/fixtures/module/class.js @@ -0,0 +1,29 @@ +'use strict'; + +let value = 'old'; + +class BaseClass { + method() { + return 'method'; + } + + get readonly() { + return 'readonly'; + } + + get value() { + return value; + } + + set value(val) { + value = val; + } +} + +class DerivedClass extends BaseClass { +} + +module.exports = { + base: new BaseClass, + derived: new DerivedClass, +} From c65cfadd094f951d65b5561df40c778d3ba583d6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 11:51:41 +0800 Subject: [PATCH 286/688] v8Util.createObjectWithName is no longer used --- atom/browser/lib/rpc-server.js | 4 +++- atom/common/api/atom_api_v8_util.cc | 35 ----------------------------- 2 files changed, 3 insertions(+), 36 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index 64785879b3f..c3e5159cd9e 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -162,7 +162,9 @@ var unwrapArgs = function(sender, args) { then: metaToValue(meta.then) }); case 'object': { - let ret = v8Util.createObjectWithName(meta.name); + let ret = {}; + Object.defineProperty(ret.constructor, 'name', { value: meta.name }); + ref = meta.members; for (i = 0, len = ref.length; i < len; i++) { member = ref[i]; diff --git a/atom/common/api/atom_api_v8_util.cc b/atom/common/api/atom_api_v8_util.cc index c86335adb15..f50d3485eba 100644 --- a/atom/common/api/atom_api_v8_util.cc +++ b/atom/common/api/atom_api_v8_util.cc @@ -2,49 +2,15 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#include #include #include "atom/common/api/object_life_monitor.h" #include "atom/common/node_includes.h" -#include "base/stl_util.h" #include "native_mate/dictionary.h" #include "v8/include/v8-profiler.h" namespace { -// A Persistent that can be copied and will not free itself. -template -struct LeakedPersistentTraits { - typedef v8::Persistent > LeakedPersistent; - static const bool kResetInDestructor = false; - template - static V8_INLINE void Copy(const v8::Persistent& source, - LeakedPersistent* dest) { - // do nothing, just allow copy - } -}; - -// The handles are leaked on purpose. -using FunctionTemplateHandle = - LeakedPersistentTraits::LeakedPersistent; -std::map function_templates_; - -v8::Local CreateObjectWithName(v8::Isolate* isolate, - const std::string& name) { - if (name == "Object") - return v8::Object::New(isolate); - - if (ContainsKey(function_templates_, name)) - return v8::Local::New( - isolate, function_templates_[name])->GetFunction()->NewInstance(); - - v8::Local t = v8::FunctionTemplate::New(isolate); - t->SetClassName(mate::StringToV8(isolate, name)); - function_templates_[name] = FunctionTemplateHandle(isolate, t); - return t->GetFunction()->NewInstance(); -} - v8::Local GetHiddenValue(v8::Local object, v8::Local key) { return object->GetHiddenValue(key); @@ -78,7 +44,6 @@ void TakeHeapSnapshot(v8::Isolate* isolate) { void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); - dict.SetMethod("createObjectWithName", &CreateObjectWithName); dict.SetMethod("getHiddenValue", &GetHiddenValue); dict.SetMethod("setHiddenValue", &SetHiddenValue); dict.SetMethod("deleteHiddenValue", &DeleteHiddenValue); From fe7462b3526d9c74534133273305223180ed0fd5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 12:26:41 +0800 Subject: [PATCH 287/688] No longer needs cache for methods of remote Refs #4517. --- atom/renderer/api/lib/remote.js | 56 +++++---------------------------- 1 file changed, 8 insertions(+), 48 deletions(-) diff --git a/atom/renderer/api/lib/remote.js b/atom/renderer/api/lib/remote.js index d28ec6dfcbd..a9798338faa 100644 --- a/atom/renderer/api/lib/remote.js +++ b/atom/renderer/api/lib/remote.js @@ -141,7 +141,7 @@ let setObjectPrototype = function(object, metaId, descriptor) { }; // Convert meta data from browser into real value. -var metaToValue = function(meta) { +let metaToValue = function(meta) { var el, i, len, ref1, results, ret; switch (meta.type) { case 'value': @@ -257,73 +257,33 @@ for (var name in browserModules) { } // Get remote module. -// (Just like node's require, the modules are cached permanently, note that this -// is safe leak since the object is not expected to get freed in browser) -var moduleCache = {}; - exports.require = function(module) { - var meta; - if (moduleCache[module] != null) { - return moduleCache[module]; - } - meta = ipcRenderer.sendSync('ATOM_BROWSER_REQUIRE', module); - return moduleCache[module] = metaToValue(meta); + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_REQUIRE', module)); }; -// Optimize require('electron'). -moduleCache.electron = exports; - // Alias to remote.require('electron').xxx. -var builtinCache = {}; - exports.getBuiltin = function(module) { - var meta; - if (builtinCache[module] != null) { - return builtinCache[module]; - } - meta = ipcRenderer.sendSync('ATOM_BROWSER_GET_BUILTIN', module); - return builtinCache[module] = metaToValue(meta); + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_GET_BUILTIN', module)); }; -// Get current BrowserWindow object. -var windowCache = null; - +// Get current BrowserWindow. exports.getCurrentWindow = function() { - var meta; - if (windowCache != null) { - return windowCache; - } - meta = ipcRenderer.sendSync('ATOM_BROWSER_CURRENT_WINDOW'); - return windowCache = metaToValue(meta); + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_CURRENT_WINDOW')); }; // Get current WebContents object. -var webContentsCache = null; - exports.getCurrentWebContents = function() { - var meta; - if (webContentsCache != null) { - return webContentsCache; - } - meta = ipcRenderer.sendSync('ATOM_BROWSER_CURRENT_WEB_CONTENTS'); - return webContentsCache = metaToValue(meta); + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_CURRENT_WEB_CONTENTS')); }; // Get a global object in browser. exports.getGlobal = function(name) { - var meta; - meta = ipcRenderer.sendSync('ATOM_BROWSER_GLOBAL', name); - return metaToValue(meta); + return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_GLOBAL', name)); }; // Get the process object in browser. -var processCache = null; - exports.__defineGetter__('process', function() { - if (processCache == null) { - processCache = exports.getGlobal('process'); - } - return processCache; + return exports.getGlobal('process'); }); // Create a funtion that will return the specifed value when called in browser. From 2b04af434937d4cde9a5b6584c19603cc586e6c3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 14:03:31 +0800 Subject: [PATCH 288/688] No longer need to count the references in webContents All remote objects are now cached in renderer process, so there is always only one reference to one remote object for each webContents. --- atom/browser/lib/objects-registry.js | 73 +++++++++++----------------- atom/browser/lib/rpc-server.js | 2 +- 2 files changed, 30 insertions(+), 45 deletions(-) diff --git a/atom/browser/lib/objects-registry.js b/atom/browser/lib/objects-registry.js index e9d6d365fa5..90d1fe80e53 100644 --- a/atom/browser/lib/objects-registry.js +++ b/atom/browser/lib/objects-registry.js @@ -15,70 +15,57 @@ class ObjectsRegistry extends EventEmitter { this.storage = {}; // Stores the IDs of objects referenced by WebContents. - // (webContentsId) => {(id) => (count)} + // (webContentsId) => [id] this.owners = {}; } - // Register a new object, the object would be kept referenced until you release - // it explicitly. + // Register a new object and return its assigned ID. If the object is already + // registered then the already assigned ID would be returned. add(webContentsId, obj) { - var base, base1, id; - id = this.saveToStorage(obj); + // Get or assign an ID to the object. + let id = this.saveToStorage(obj); - // Remember the owner. - if ((base = this.owners)[webContentsId] == null) { - base[webContentsId] = {}; + // Add object to the set of referenced objects. + let owner = this.owners[webContentsId]; + if (!owner) + owner = this.owners[webContentsId] = new Set(); + if (!owner.has(id)) { + owner.add(id); + // Increase reference count if not referenced before. + this.storage[id].count++; } - if ((base1 = this.owners[webContentsId])[id] == null) { - base1[id] = 0; - } - this.owners[webContentsId][id]++; - - // Returns object's id return id; } // Get an object according to its ID. get(id) { - var ref; - return (ref = this.storage[id]) != null ? ref.object : void 0; + return this.storage[id].object; } // Dereference an object according to its ID. remove(webContentsId, id) { - var pointer; - this.dereference(id, 1); + // Dereference from the storage. + this.dereference(id); - // Also reduce the count in owner. - pointer = this.owners[webContentsId]; - if (pointer == null) { - return; - } - --pointer[id]; - if (pointer[id] === 0) { - return delete pointer[id]; - } + // Also remove the reference in owner. + this.owners[webContentsId].delete(id); } // Clear all references to objects refrenced by the WebContents. clear(webContentsId) { - var count, id, ref; - this.emit("clear-" + webContentsId); - if (this.owners[webContentsId] == null) { + this.emit(`clear-${webContentsId}`); + + let owner = this.owners[webContentsId]; + if (!owner) return; - } - ref = this.owners[webContentsId]; - for (id in ref) { - count = ref[id]; - this.dereference(id, count); - } - return delete this.owners[webContentsId]; + for (let id of owner) + this.dereference(id); + delete this.owners[webContentsId]; } // Private: Saves the object into storage and assigns an ID for it. saveToStorage(object) { - var id; - id = v8Util.getHiddenValue(object, 'atomId'); + let id = v8Util.getHiddenValue(object, 'atomId'); if (!id) { id = ++this.nextId; this.storage[id] = { @@ -87,18 +74,16 @@ class ObjectsRegistry extends EventEmitter { }; v8Util.setHiddenValue(object, 'atomId', id); } - ++this.storage[id].count; return id; } // Private: Dereference the object from store. - dereference(id, count) { - var pointer; - pointer = this.storage[id]; + dereference(id) { + let pointer = this.storage[id]; if (pointer == null) { return; } - pointer.count -= count; + pointer.count -= 1; if (pointer.count === 0) { v8Util.deleteHiddenValue(pointer.object, 'atomId'); return delete this.storage[id]; diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index c3e5159cd9e..f366eb43a52 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -145,7 +145,7 @@ var exceptionToMeta = function(error) { var unwrapArgs = function(sender, args) { var metaToValue; metaToValue = function(meta) { - var i, len, member, ref, rendererReleased, returnValue; + var i, len, member, ref, returnValue; switch (meta.type) { case 'value': return meta.value; From 59d6e7d6ef769118a7357c2a0d266223819f1459 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 14:10:25 +0800 Subject: [PATCH 289/688] ObjectsRegistry no longer needs to send events --- atom/browser/lib/objects-registry.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/atom/browser/lib/objects-registry.js b/atom/browser/lib/objects-registry.js index 90d1fe80e53..9677c7fea22 100644 --- a/atom/browser/lib/objects-registry.js +++ b/atom/browser/lib/objects-registry.js @@ -1,13 +1,9 @@ 'use strict'; -const EventEmitter = require('events').EventEmitter; const v8Util = process.atomBinding('v8_util'); -class ObjectsRegistry extends EventEmitter { +class ObjectsRegistry { constructor() { - super(); - - this.setMaxListeners(Number.MAX_VALUE); this.nextId = 0; // Stores all objects by ref-counting. @@ -53,8 +49,6 @@ class ObjectsRegistry extends EventEmitter { // Clear all references to objects refrenced by the WebContents. clear(webContentsId) { - this.emit(`clear-${webContentsId}`); - let owner = this.owners[webContentsId]; if (!owner) return; From d4c954870a14c90f114482e03ef4cc3b60b092bd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 14:15:51 +0800 Subject: [PATCH 290/688] Remove a few CoffeeScript generated junks --- atom/browser/lib/rpc-server.js | 35 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index f366eb43a52..c3ea8ca6b09 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -11,8 +11,6 @@ const FUNCTION_PROPERTIES = [ 'length', 'name', 'arguments', 'caller', 'prototype', ]; -var slice = [].slice; - // Return the description of object's members: let getObjectMemebers = function(object) { let names = Object.getOwnPropertyNames(object); @@ -281,14 +279,13 @@ ipcMain.on('ATOM_BROWSER_CURRENT_WEB_CONTENTS', function(event) { }); ipcMain.on('ATOM_BROWSER_CONSTRUCTOR', function(event, id, args) { - var constructor, obj; try { args = unwrapArgs(event.sender, args); - constructor = objectsRegistry.get(id); + let constructor = objectsRegistry.get(id); // Call new with array of arguments. // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible - obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))); + let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))); return event.returnValue = valueToMeta(event.sender, obj); } catch (error) { return event.returnValue = exceptionToMeta(error); @@ -296,10 +293,9 @@ ipcMain.on('ATOM_BROWSER_CONSTRUCTOR', function(event, id, args) { }); ipcMain.on('ATOM_BROWSER_FUNCTION_CALL', function(event, id, args) { - var func; try { args = unwrapArgs(event.sender, args); - func = objectsRegistry.get(id); + let func = objectsRegistry.get(id); return callFunction(event, func, global, args); } catch (error) { return event.returnValue = exceptionToMeta(error); @@ -307,13 +303,12 @@ ipcMain.on('ATOM_BROWSER_FUNCTION_CALL', function(event, id, args) { }); ipcMain.on('ATOM_BROWSER_MEMBER_CONSTRUCTOR', function(event, id, method, args) { - var constructor, obj; try { args = unwrapArgs(event.sender, args); - constructor = objectsRegistry.get(id)[method]; + let constructor = objectsRegistry.get(id)[method]; // Call new with array of arguments. - obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))); + let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))); return event.returnValue = valueToMeta(event.sender, obj); } catch (error) { return event.returnValue = exceptionToMeta(error); @@ -321,10 +316,9 @@ ipcMain.on('ATOM_BROWSER_MEMBER_CONSTRUCTOR', function(event, id, method, args) }); ipcMain.on('ATOM_BROWSER_MEMBER_CALL', function(event, id, method, args) { - var obj; try { args = unwrapArgs(event.sender, args); - obj = objectsRegistry.get(id); + let obj = objectsRegistry.get(id); return callFunction(event, obj[method], obj, args); } catch (error) { return event.returnValue = exceptionToMeta(error); @@ -332,9 +326,8 @@ ipcMain.on('ATOM_BROWSER_MEMBER_CALL', function(event, id, method, args) { }); ipcMain.on('ATOM_BROWSER_MEMBER_SET', function(event, id, name, value) { - var obj; try { - obj = objectsRegistry.get(id); + let obj = objectsRegistry.get(id); obj[name] = value; return event.returnValue = null; } catch (error) { @@ -343,9 +336,8 @@ ipcMain.on('ATOM_BROWSER_MEMBER_SET', function(event, id, name, value) { }); ipcMain.on('ATOM_BROWSER_MEMBER_GET', function(event, id, name) { - var obj; try { - obj = objectsRegistry.get(id); + let obj = objectsRegistry.get(id); return event.returnValue = valueToMeta(event.sender, obj[name]); } catch (error) { return event.returnValue = exceptionToMeta(error); @@ -357,21 +349,18 @@ ipcMain.on('ATOM_BROWSER_DEREFERENCE', function(event, id) { }); ipcMain.on('ATOM_BROWSER_GUEST_WEB_CONTENTS', function(event, guestInstanceId) { - var guestViewManager; try { - guestViewManager = require('./guest-view-manager'); + let guestViewManager = require('./guest-view-manager'); return event.returnValue = valueToMeta(event.sender, guestViewManager.getGuest(guestInstanceId)); } catch (error) { return event.returnValue = exceptionToMeta(error); } }); -ipcMain.on('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function() { - var args, event, guest, guestInstanceId, guestViewManager, method; - event = arguments[0], guestInstanceId = arguments[1], method = arguments[2], args = 4 <= arguments.length ? slice.call(arguments, 3) : []; +ipcMain.on('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function(event, guestInstanceId, method, ...args) { try { - guestViewManager = require('./guest-view-manager'); - guest = guestViewManager.getGuest(guestInstanceId); + let guestViewManager = require('./guest-view-manager'); + let guest = guestViewManager.getGuest(guestInstanceId); return guest[method].apply(guest, args); } catch (error) { return event.returnValue = exceptionToMeta(error); From 593a79ce20296f0178e6f38016039e5e12a1f77a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 14:36:50 +0800 Subject: [PATCH 291/688] Separate renderer functions by renderer process ID Close #4324. --- atom/browser/lib/rpc-server.js | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index c3ea8ca6b09..7b59648eda1 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -11,6 +11,10 @@ const FUNCTION_PROPERTIES = [ 'length', 'name', 'arguments', 'caller', 'prototype', ]; +// The remote functions in renderer processes. +// (webContentsId) => {id: Function} +let rendererFunctions = {}; + // Return the description of object's members: let getObjectMemebers = function(object) { let names = Object.getOwnPropertyNames(object); @@ -177,32 +181,30 @@ var unwrapArgs = function(sender, args) { }; case 'function': { // Cache the callbacks in renderer. - if (!sender.callbacks) { - sender.callbacks = new IDWeakMap; - sender.on('render-view-deleted', function() { - return this.callbacks.clear(); + let webContentsId = sender.getId(); + let callbacks = rendererFunctions[webContentsId]; + if (!callbacks) { + callbacks = rendererFunctions[webContentsId] = new IDWeakMap; + sender.once('render-view-deleted', function(event, id) { + callbacks.clear(); + delete rendererFunctions[id]; }); } - if (sender.callbacks.has(meta.id)) - return sender.callbacks.get(meta.id); - - // Prevent the callback from being called when its page is gone. - rendererReleased = false; - sender.once('render-view-deleted', function() { - rendererReleased = true; - }); + if (callbacks.has(meta.id)) + return callbacks.get(meta.id); let callIntoRenderer = function(...args) { - if (rendererReleased || sender.isDestroyed()) + if ((webContentsId in rendererFunctions) && !sender.isDestroyed()) + sender.send('ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, args)); + else throw new Error(`Attempting to call a function in a renderer window that has been closed or released. Function provided here: ${meta.location}.`); - sender.send('ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(sender, args)); }; v8Util.setDestructor(callIntoRenderer, function() { - if (!rendererReleased && !sender.isDestroyed()) + if ((webContentsId in rendererFunctions) && !sender.isDestroyed()) sender.send('ATOM_RENDERER_RELEASE_CALLBACK', meta.id); }); - sender.callbacks.set(meta.id, callIntoRenderer); + callbacks.set(meta.id, callIntoRenderer); return callIntoRenderer; } default: From 6753fcc1b4bae07bad8cae674770da220bf9fafb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 14:54:55 +0800 Subject: [PATCH 292/688] Get rid of the ATOM_BROWSER_RELEASE_RENDER_VIEW event --- atom/browser/api/atom_api_web_contents.cc | 12 +----------- atom/browser/lib/objects-registry.js | 10 ++++++++-- atom/browser/lib/rpc-server.js | 7 +------ 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index a7946786c51..72443bdb815 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -485,17 +485,7 @@ void WebContents::BeforeUnloadFired(const base::TimeTicks& proceed_time) { } void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) { - int process_id = render_view_host->GetProcess()->GetID(); - Emit("render-view-deleted", process_id); - - // process.emit('ATOM_BROWSER_RELEASE_RENDER_VIEW', processId); - // Tell the rpc server that a render view has been deleted and we need to - // release all objects owned by it. - v8::Locker locker(isolate()); - v8::HandleScope handle_scope(isolate()); - node::Environment* env = node::Environment::GetCurrent(isolate()); - mate::EmitEvent(isolate(), env->process_object(), - "ATOM_BROWSER_RELEASE_RENDER_VIEW", process_id); + Emit("render-view-deleted", render_view_host->GetProcess()->GetID()); } void WebContents::RenderProcessGone(base::TerminationStatus status) { diff --git a/atom/browser/lib/objects-registry.js b/atom/browser/lib/objects-registry.js index 9677c7fea22..c3f70c976ec 100644 --- a/atom/browser/lib/objects-registry.js +++ b/atom/browser/lib/objects-registry.js @@ -17,14 +17,20 @@ class ObjectsRegistry { // Register a new object and return its assigned ID. If the object is already // registered then the already assigned ID would be returned. - add(webContentsId, obj) { + add(webContents, obj) { // Get or assign an ID to the object. let id = this.saveToStorage(obj); // Add object to the set of referenced objects. + let webContentsId = webContents.getId(); let owner = this.owners[webContentsId]; - if (!owner) + if (!owner) { owner = this.owners[webContentsId] = new Set(); + // Clear the storage when webContents is reloaded/navigated. + webContents.once('render-view-deleted', (event, id) => { + this.clear(id); + }); + } if (!owner.has(id)) { owner.add(id); // Increase reference count if not referenced before. diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index 7b59648eda1..20ee8fbdeae 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -100,7 +100,7 @@ var valueToMeta = function(sender, value, optimizeSimpleObject) { // Reference the original value if it's an object, because when it's // passed to renderer we would assume the renderer keeps a reference of // it. - meta.id = objectsRegistry.add(sender.getId(), value); + meta.id = objectsRegistry.add(sender, value); meta.members = getObjectMemebers(value); meta.proto = getObjectPrototype(value); } else if (meta.type === 'buffer') { @@ -239,11 +239,6 @@ var callFunction = function(event, func, caller, args) { } }; -// Send by BrowserWindow when its render view is deleted. -process.on('ATOM_BROWSER_RELEASE_RENDER_VIEW', function(id) { - return objectsRegistry.clear(id); -}); - ipcMain.on('ATOM_BROWSER_REQUIRE', function(event, module) { try { return event.returnValue = valueToMeta(event.sender, process.mainModule.require(module)); From 96b2705bd3ec3fe7a92bc27bf061613d4871ae19 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 22 Feb 2016 15:20:23 +0800 Subject: [PATCH 293/688] Fix render-view-deleted being emitted twice --- atom/browser/api/atom_api_web_contents.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 72443bdb815..ee6ad94ba77 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -296,6 +296,7 @@ WebContents::~WebContents() { // The WebContentsDestroyed will not be called automatically because we // unsubscribe from webContents before destroying it. So we have to manually // call it here to make sure "destroyed" event is emitted. + RenderViewDeleted(web_contents()->GetRenderViewHost()); WebContentsDestroyed(); } } @@ -665,9 +666,6 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) { // be destroyed on close, and WebContentsDestroyed would be called for it, so // we need to make sure the api::WebContents is also deleted. void WebContents::WebContentsDestroyed() { - // The RenderViewDeleted was not called when the WebContents is destroyed. - RenderViewDeleted(web_contents()->GetRenderViewHost()); - // This event is only for internal use, which is emitted when WebContents is // being destroyed. Emit("will-destroy"); From 39bb670719e4bb65cabc1bc3edad885b61945447 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Mon, 22 Feb 2016 10:23:56 +0100 Subject: [PATCH 294/688] Revert will-enter-full-screen event, matching osx fullscreen: false behaviour on windows instead --- atom/browser/api/atom_api_window.cc | 4 ---- atom/browser/api/atom_api_window.h | 1 - atom/browser/native_window.cc | 19 +++++++++---------- atom/browser/native_window.h | 3 --- atom/browser/native_window_mac.mm | 3 --- atom/browser/native_window_observer.h | 1 - atom/browser/native_window_views.cc | 21 +++++++++++---------- atom/browser/native_window_views.h | 1 + docs/api/browser-window.md | 13 ++++--------- 9 files changed, 25 insertions(+), 41 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 3a3b3c6efc8..bcf6ccc5a33 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -219,10 +219,6 @@ void Window::OnWindowMoved() { Emit("moved"); } -void Window::OnWindowWillEnterFullScreen(bool* prevent_default) { - *prevent_default = Emit("will-enter-full-screen"); -} - void Window::OnWindowEnterFullScreen() { Emit("enter-full-screen"); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 2d1e6d71ec3..641124f4dfd 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -67,7 +67,6 @@ class Window : public mate::TrackableObject, void OnWindowMoved() override; void OnWindowScrollTouchBegin() override; void OnWindowScrollTouchEnd() override; - void OnWindowWillEnterFullScreen(bool* prevent_default) override; void OnWindowEnterFullScreen() override; void OnWindowLeaveFullScreen() override; void OnWindowEnterHtmlFullScreen() override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index a09705fbd96..273bd948fe5 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -134,10 +134,16 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { SetAlwaysOnTop(true); } #if defined(OS_MACOSX) || defined(OS_WIN) - bool fullscreen; - if (options.Get(options::kFullscreen, &fullscreen) && fullscreen) { + // Disable fullscreen button when 'fullscreenable' is false or 'fullscreen' + // is specified to false. + bool fullscreenable = true; + options.Get(options::kFullScreenable, &fullscreenable); + bool fullscreen = false; + if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) + fullscreenable = false; + SetFullScreenable(fullscreenable); + if (fullscreen) SetFullScreen(true); - } #endif bool skip; if (options.Get(options::kSkipTaskbar, &skip) && skip) { @@ -445,13 +451,6 @@ void NativeWindow::NotifyWindowMoved() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowMoved()); } -bool NativeWindow::RequestEnterFullScreen() { - bool prevent_default = false; - FOR_EACH_OBSERVER(NativeWindowObserver, observers_, - OnWindowWillEnterFullScreen(&prevent_default)); - return prevent_default; -} - void NativeWindow::NotifyWindowEnterFullScreen() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowEnterFullScreen()); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 4cc04e790e1..09fae6c6bcf 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -197,9 +197,6 @@ class NativeWindow : public base::SupportsUserData, // Requests the WebContents to close, can be cancelled by the page. virtual void RequestToClosePage(); - // Request the WebContents to go fullscreen, can be cancelled by the page. - virtual bool RequestEnterFullScreen(); - // Methods called by the WebContents. virtual void CloseContents(content::WebContents* source); virtual void RendererUnresponsive(content::WebContents* source); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index f4f5a8c9789..7967a177173 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -602,9 +602,6 @@ void NativeWindowMac::SetFullScreen(bool fullscreen) { if (fullscreen == IsFullscreen()) return; - if (fullscreen && RequestEnterFullScreen()) - return; - if (!base::mac::IsOSLionOrLater()) { LOG(ERROR) << "Fullscreen mode is only supported above Lion"; return; diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 1f66bac5b63..4af181085a0 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -52,7 +52,6 @@ class NativeWindowObserver { virtual void OnWindowMoved() {} virtual void OnWindowScrollTouchBegin() {} virtual void OnWindowScrollTouchEnd() {} - virtual void OnWindowWillEnterFullScreen(bool* prevent_default) {} virtual void OnWindowEnterFullScreen() {} virtual void OnWindowLeaveFullScreen() {} virtual void OnWindowEnterHtmlFullScreen() {} diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 101c57515af..4b3b32024df 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -117,7 +117,8 @@ NativeWindowViews::NativeWindowViews( movable_(true), resizable_(true), maximizable_(true), - minimizable_(true) { + minimizable_(true), + fullscreenable_(true) { options.Get(options::kTitle, &title_); options.Get(options::kAutoHideMenuBar, &menu_bar_autohide_); @@ -347,14 +348,10 @@ bool NativeWindowViews::IsMinimized() { } void NativeWindowViews::SetFullScreen(bool fullscreen) { - bool prevent_default = false; - if (fullscreen) - prevent_default = RequestEnterFullScreen(); - #if defined(OS_WIN) // There is no native fullscreen state on Windows. if (fullscreen) { - if (!prevent_default) { + if (IsFullScreenable()) { last_window_state_ = ui::SHOW_STATE_FULLSCREEN; NotifyWindowEnterFullScreen(); } @@ -364,10 +361,10 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) { } // We set the new value after notifying, so we can handle the size event // correctly. - if (!prevent_default) + if (IsFullScreenable()) window_->SetFullscreen(fullscreen); #else - if (!(fullscreen && prevent_default)) { + if (!fullscreen || IsFullScreenable()) { if (IsVisible()) window_->SetFullscreen(fullscreen); else @@ -499,11 +496,15 @@ bool NativeWindowViews::IsMaximizable() { #endif } -void NativeWindowViews::SetFullScreenable(bool maximizable) { +void NativeWindowViews::SetFullScreenable(bool fullscreenable) { + #if defined(OS_WIN) + FlipWindowStyle(GetAcceleratedWidget(), false, WS_MAXIMIZEBOX); + #endif + fullscreenable_ = fullscreenable; } bool NativeWindowViews::IsFullScreenable() { - return true; + return fullscreenable_; } void NativeWindowViews::SetClosable(bool closable) { diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 934f2aa00c9..862cd5458bb 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -212,6 +212,7 @@ class NativeWindowViews : public NativeWindow, bool resizable_; bool maximizable_; bool minimizable_; + bool fullscreenable_; std::string title_; gfx::Size widget_size_; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 827bb84db81..96ce955db59 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -276,11 +276,6 @@ __Note__: On OS X this event is just an alias of `moved`. Emitted once when the window is moved to a new position. -### Event: 'will-enter-full-screen' - -Emitted when the window is about to enter full screen state. Calling `event.preventDefault()` -will cancel the state change. - ### Event: 'enter-full-screen' Emitted when the window enters full screen state. @@ -589,17 +584,17 @@ nothing. Returns whether the window can be manually maximized by user. On Linux always returns `true`. -### `win.setFullScreenable(fullscreenable)` _OS X_ +### `win.setFullScreenable(fullscreenable)` * `fullscreenable` Boolean Sets whether the maximize/zoom window button toggles fullscreen mode or -maximizes the window. On Windows and Linux does nothing. +maximizes the window. -### `win.isFullScreenable()` _OS X_ +### `win.isFullScreenable()` Returns whether the maximize/zoom window button toggles fullscreen mode or -maximizes the window. On Windows and Linux always returns `true`. +maximizes the window. ### `win.setClosable(closable)` _OS X_ _Windows_ From 331bc42d57f04648a5c92e10afdc074d69cc827e Mon Sep 17 00:00:00 2001 From: jin5354 Date: Tue, 23 Feb 2016 10:00:28 +0800 Subject: [PATCH 295/688] docs: update zh-CN doc debugging-main-process.md update zh-CN doc debugging-main-process.md to be up-to-date with English ver. --- .../zh-CN/tutorial/debugging-main-process.md | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/docs-translations/zh-CN/tutorial/debugging-main-process.md b/docs-translations/zh-CN/tutorial/debugging-main-process.md index 48f3579394e..f971a40892f 100644 --- a/docs-translations/zh-CN/tutorial/debugging-main-process.md +++ b/docs-translations/zh-CN/tutorial/debugging-main-process.md @@ -18,16 +18,31 @@ ## 使用 node-inspector 来调试 -__备注:__ Electron 使用 node v0.11.13 版本,目前对 node-inspector支持的不是特别好, +__备注:__ Electron 目前对 node-inspector支持的不是特别好, 如果你通过 node-inspector 的 console 来检查 `process` 对象,主进程就会崩溃。 -### 1. 开始 [node-inspector][node-inspector] 服务 +### 1. 确认你已经安装了 [node-gyp 所需工具](https://github.com/nodejs/node-gyp#installation) + +### 2. 安装 [node-inspector][node-inspector] ```bash -$ node-inspector +$ npm install node-inspector ``` -### 2. 打开 Electron 的调试模式 +### 3. 安装 `node-pre-gyp` 的一个修订版 + +```bash +$ npm install git+https://git@github.com/enlight/node-pre-gyp.git#detect-electron-runtime-in-find +``` + +### 4. 为 Electron 重新编译 `node-inspector` `v8` 模块(将 target 参数修改为你的 Electron 的版本号) + +```bash +$ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-debug/ --dist-url=https://atom.io/download/atom-shell reinstall +$ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-profiler/ --dist-url=https://atom.io/download/atom-shell reinstall +``` + +### 5. 打开 Electron 的调试模式 你也可以用调试参数来运行 Electron : @@ -41,7 +56,13 @@ $ electron --debug=5858 your/app $ electron --debug-brk=5858 your/app ``` -### 3. 加载调试器界面 +### 6. 使用 Electron 开启 [node-inspector][node-inspector] 服务 + +```bash +$ ELECTRON_RUN_AS_NODE=true path/to/electron.exe node_modules/node-inspector/bin/inspector.js +``` + +### 7. 加载调试器界面 在 Chrome 中打开 http://127.0.0.1:8080/debug?ws=127.0.0.1:8080&port=5858 From 23268531ae32bc0ac8e847b3bb147f7ef6ba6641 Mon Sep 17 00:00:00 2001 From: Yasunari Fujieda Date: Tue, 23 Feb 2016 15:10:38 +0900 Subject: [PATCH 296/688] docs: update jp doc ipc-renderer.md --- docs-translations/jp/api/ipc-renderer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/jp/api/ipc-renderer.md b/docs-translations/jp/api/ipc-renderer.md index 5854157363f..edbd862ffaa 100644 --- a/docs-translations/jp/api/ipc-renderer.md +++ b/docs-translations/jp/api/ipc-renderer.md @@ -52,7 +52,7 @@ * `channel` String - イベント名 * `arg` (optional) -`channel`経由でメインプロセスに非同期にイベントを送信し、任意の引数を送信できます。 +`channel`経由でメインプロセスに同期的にイベントを送信し、任意の引数を送信できます。 メインプロセスは`ipcMain`で`channel`を受信することでハンドルし、 `event.returnValue`を設定してリプライします。 From bdfc19ad20fff7ef7490420f44aa60cd89f606d2 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 19 Feb 2016 19:46:03 +0530 Subject: [PATCH 297/688] add docs --- atom/browser/api/lib/protocol.js | 4 ---- docs/api/session.md | 22 ++++++++++++++++++++++ spec/api-protocol-spec.js | 12 +++++++----- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/atom/browser/api/lib/protocol.js b/atom/browser/api/lib/protocol.js index caef0ad646b..de1bdea471f 100644 --- a/atom/browser/api/lib/protocol.js +++ b/atom/browser/api/lib/protocol.js @@ -19,10 +19,6 @@ var logAndThrow = function(callback, message) { } }; -protocol.fromPartition = function(partition) { - return session.fromPartition(partition).protocol; -}; - protocol.registerProtocol = function(scheme, handler, callback) { return logAndThrow(callback, 'registerProtocol API has been replaced by the register[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.'); }; diff --git a/docs/api/session.md b/docs/api/session.md index cc90a0b542c..d492f3d55c5 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -523,3 +523,25 @@ The `listener` will be called with `listener(details)` when an error occurs. * `timestamp` Double * `fromCache` Boolean * `error` String - The error description. + +#### `ses.protocol` + +Returns an instance of [protocol](protocol.md) module for this session. + +```javascript +const electron = require('electron'); +const app = electron.app; +const session = electron.session; +const path = require('path'); + +app.on('ready', function() { + const protocol = session.fromPartition(partitionName).protocol; + protocol.registerFileProtocol('atom', function(request, callback) { + var url = request.url.substr(7); + callback({path: path.normalize(__dirname + '/' + url)}); + }, function (error) { + if (error) + console.error('Failed to register protocol') + }); +}); +``` diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 483155b7065..beb483e3f80 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -5,6 +5,7 @@ const qs = require('querystring'); const remote = require('electron').remote; const BrowserWindow = remote.require('electron').BrowserWindow; const protocol = remote.require('electron').protocol; +const session = remote.require('electron').session; describe('protocol module', function() { var protocolName = 'sp'; @@ -818,7 +819,7 @@ describe('protocol module', function() { describe('protocol.fromPartition', function() { var partitionName = 'temp'; - var tempProtocol = protocol.fromPartition(partitionName); + var tempProtocol = session.fromPartition(partitionName).protocol; var w = null; beforeEach(function() { @@ -852,17 +853,18 @@ describe('protocol module', function() { if (error) { return done(error); } + protocol.isProtocolHandled(protocolName, function(result) { assert.equal(result, false); }); tempProtocol.isProtocolHandled(protocolName, function(result) { assert.equal(result, true); + w.webContents.on('did-finish-load', function() { + done(); + }); + w.loadURL(protocolName + "://fake-host"); }); }); - w.webContents.on('did-finish-load', function() { - done(); - }); - w.loadURL(protocolName + "://fake-host"); }); }); }); From 49f995925c8981f4d90809d49839e05f349a9b0a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 23 Feb 2016 15:43:32 +0800 Subject: [PATCH 298/688] Notify the global menu bar when window is mapped --- atom/browser/native_window_views.cc | 15 +++++++++++++++ atom/browser/ui/views/global_menu_bar_x11.cc | 8 ++++++++ atom/browser/ui/views/global_menu_bar_x11.h | 4 ++++ 3 files changed, 27 insertions(+) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 44df87da9fb..97a2ee05a33 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -300,14 +300,29 @@ bool NativeWindowViews::IsFocused() { void NativeWindowViews::Show() { window_->native_widget_private()->ShowWithWindowState(GetRestoredState()); + +#if defined(USE_X11) + if (global_menu_bar_) + global_menu_bar_->OnWindowMapped(); +#endif } void NativeWindowViews::ShowInactive() { window_->ShowInactive(); + +#if defined(USE_X11) + if (global_menu_bar_) + global_menu_bar_->OnWindowMapped(); +#endif } void NativeWindowViews::Hide() { window_->Hide(); + +#if defined(USE_X11) + if (global_menu_bar_) + global_menu_bar_->OnWindowUnmapped(); +#endif } bool NativeWindowViews::IsVisible() { diff --git a/atom/browser/ui/views/global_menu_bar_x11.cc b/atom/browser/ui/views/global_menu_bar_x11.cc index 26279ecbe8e..b393e3f4657 100644 --- a/atom/browser/ui/views/global_menu_bar_x11.cc +++ b/atom/browser/ui/views/global_menu_bar_x11.cc @@ -210,6 +210,14 @@ void GlobalMenuBarX11::InitServer(gfx::AcceleratedWidget xid) { server_ = server_new(path.c_str()); } +void GlobalMenuBarX11::OnWindowMapped() { + GlobalMenuBarRegistrarX11::GetInstance()->OnWindowMapped(xid_); +} + +void GlobalMenuBarX11::OnWindowUnmapped() { + GlobalMenuBarRegistrarX11::GetInstance()->OnWindowUnmapped(xid_); +} + void GlobalMenuBarX11::BuildMenuFromModel(ui::MenuModel* model, DbusmenuMenuitem* parent) { for (int i = 0; i < model->GetItemCount(); ++i) { diff --git a/atom/browser/ui/views/global_menu_bar_x11.h b/atom/browser/ui/views/global_menu_bar_x11.h index 51147a26f92..d9e818ce3eb 100644 --- a/atom/browser/ui/views/global_menu_bar_x11.h +++ b/atom/browser/ui/views/global_menu_bar_x11.h @@ -46,6 +46,10 @@ class GlobalMenuBarX11 { void SetMenu(ui::MenuModel* menu_model); bool IsServerStarted() const; + // Called by NativeWindow when it show/hides. + void OnWindowMapped(); + void OnWindowUnmapped(); + private: // Creates a DbusmenuServer. void InitServer(gfx::AcceleratedWidget xid); From 367d12402ae6f3822b769da63fa5adeeaf8643b2 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 17 Feb 2016 13:06:18 +0530 Subject: [PATCH 299/688] ipc: allow passing date instances --- .../v8_value_converter.cc | 35 +++++++++++++------ .../v8_value_converter.h | 4 --- spec/api-ipc-spec.js | 9 +++++ 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/atom/common/native_mate_converters/v8_value_converter.cc b/atom/common/native_mate_converters/v8_value_converter.cc index 7d3a1277cb8..f5d7217ae52 100644 --- a/atom/common/native_mate_converters/v8_value_converter.cc +++ b/atom/common/native_mate_converters/v8_value_converter.cc @@ -4,6 +4,7 @@ #include "atom/common/native_mate_converters/v8_value_converter.h" +#include #include #include #include @@ -20,6 +21,14 @@ namespace { const int kMaxRecursionDepth = 100; +const double kMsPerDay = 24 * 60 * 60 * 1000; + +int TimeInDay(double time_ms) { + if (time_ms < 0) time_ms -= (kMsPerDay -1); + int days = static_cast(time_ms / kMsPerDay); + return static_cast(time_ms - days * kMsPerDay); +} + } // namespace // The state of a call to FromV8Value. @@ -76,15 +85,10 @@ class V8ValueConverter::FromV8ValueState { }; V8ValueConverter::V8ValueConverter() - : date_allowed_(false), - reg_exp_allowed_(false), + : reg_exp_allowed_(false), function_allowed_(false), strip_null_from_objects_(false) {} -void V8ValueConverter::SetDateAllowed(bool val) { - date_allowed_ = val; -} - void V8ValueConverter::SetRegExpAllowed(bool val) { reg_exp_allowed_ = val; } @@ -243,12 +247,21 @@ base::Value* V8ValueConverter::FromV8ValueImpl( return NULL; if (val->IsDate()) { - if (!date_allowed_) - // JSON.stringify would convert this to a string, but an object is more - // consistent within this class. - return FromV8Object(val->ToObject(), state, isolate); v8::Date* date = v8::Date::Cast(*val); - return new base::FundamentalValue(date->NumberValue() / 1000.0); + double const time_ms = date->NumberValue(); + int const time_in_day_ms = TimeInDay(time_ms); + std::time_t time_s(time_ms / 1000.0); + char buf[128]; + std::tm* gm_time = std::gmtime(&time_s); + int year = gm_time->tm_year + 1900; + int month = gm_time->tm_mon + 1; + int ms = time_in_day_ms % 1000; + size_t length = snprintf(buf, sizeof buf, + "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", + year, month, gm_time->tm_mday, + gm_time->tm_hour, gm_time->tm_min, + gm_time->tm_sec, ms); + return new base::StringValue(std::string(buf, length)); } if (val->IsRegExp()) { diff --git a/atom/common/native_mate_converters/v8_value_converter.h b/atom/common/native_mate_converters/v8_value_converter.h index 2b695b43747..95840c01ba7 100644 --- a/atom/common/native_mate_converters/v8_value_converter.h +++ b/atom/common/native_mate_converters/v8_value_converter.h @@ -22,7 +22,6 @@ class V8ValueConverter { public: V8ValueConverter(); - void SetDateAllowed(bool val); void SetRegExpAllowed(bool val); void SetFunctionAllowed(bool val); void SetStripNullFromObjects(bool val); @@ -58,9 +57,6 @@ class V8ValueConverter { FromV8ValueState* state, v8::Isolate* isolate) const; - // If true, we will convert Date JavaScript objects to doubles. - bool date_allowed_; - // If true, we will convert RegExp JavaScript objects to string. bool reg_exp_allowed_; diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 2c8bc28f156..92a8c001bf1 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -102,6 +102,15 @@ describe('ipc module', function() { }); ipcRenderer.send('message', obj); }); + + it('can send instance of Date', function(done) { + const currentDate = new Date(); + ipcRenderer.once('message', function(event, value) { + assert.equal(value, currentDate.toISOString()); + done(); + }); + ipcRenderer.send('message', currentDate); + }); }); describe('ipc.sendSync', function() { From bb1e4c2208fe099faf9138072bdd24a019a29ba6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 24 Feb 2016 13:25:22 +0800 Subject: [PATCH 300/688] Revert "add docs" This reverts commit bdfc19ad20fff7ef7490420f44aa60cd89f606d2. --- atom/browser/api/lib/protocol.js | 4 ++++ docs/api/session.md | 22 ---------------------- spec/api-protocol-spec.js | 12 +++++------- 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/atom/browser/api/lib/protocol.js b/atom/browser/api/lib/protocol.js index de1bdea471f..caef0ad646b 100644 --- a/atom/browser/api/lib/protocol.js +++ b/atom/browser/api/lib/protocol.js @@ -19,6 +19,10 @@ var logAndThrow = function(callback, message) { } }; +protocol.fromPartition = function(partition) { + return session.fromPartition(partition).protocol; +}; + protocol.registerProtocol = function(scheme, handler, callback) { return logAndThrow(callback, 'registerProtocol API has been replaced by the register[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.'); }; diff --git a/docs/api/session.md b/docs/api/session.md index d492f3d55c5..cc90a0b542c 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -523,25 +523,3 @@ The `listener` will be called with `listener(details)` when an error occurs. * `timestamp` Double * `fromCache` Boolean * `error` String - The error description. - -#### `ses.protocol` - -Returns an instance of [protocol](protocol.md) module for this session. - -```javascript -const electron = require('electron'); -const app = electron.app; -const session = electron.session; -const path = require('path'); - -app.on('ready', function() { - const protocol = session.fromPartition(partitionName).protocol; - protocol.registerFileProtocol('atom', function(request, callback) { - var url = request.url.substr(7); - callback({path: path.normalize(__dirname + '/' + url)}); - }, function (error) { - if (error) - console.error('Failed to register protocol') - }); -}); -``` diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index beb483e3f80..483155b7065 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -5,7 +5,6 @@ const qs = require('querystring'); const remote = require('electron').remote; const BrowserWindow = remote.require('electron').BrowserWindow; const protocol = remote.require('electron').protocol; -const session = remote.require('electron').session; describe('protocol module', function() { var protocolName = 'sp'; @@ -819,7 +818,7 @@ describe('protocol module', function() { describe('protocol.fromPartition', function() { var partitionName = 'temp'; - var tempProtocol = session.fromPartition(partitionName).protocol; + var tempProtocol = protocol.fromPartition(partitionName); var w = null; beforeEach(function() { @@ -853,18 +852,17 @@ describe('protocol module', function() { if (error) { return done(error); } - protocol.isProtocolHandled(protocolName, function(result) { assert.equal(result, false); }); tempProtocol.isProtocolHandled(protocolName, function(result) { assert.equal(result, true); - w.webContents.on('did-finish-load', function() { - done(); - }); - w.loadURL(protocolName + "://fake-host"); }); }); + w.webContents.on('did-finish-load', function() { + done(); + }); + w.loadURL(protocolName + "://fake-host"); }); }); }); From 8ff30a2abc15059fdce79faa1576b12bd6536158 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 24 Feb 2016 13:25:30 +0800 Subject: [PATCH 301/688] Revert "protocol: respect requests from partition" This reverts commit 85800256deb7c2eb543bba8d28eb369e3521eb54. --- atom/browser/api/atom_api_protocol.cc | 70 ++++++++++++++++----------- atom/browser/api/atom_api_protocol.h | 11 ++--- atom/browser/api/atom_api_session.cc | 10 ---- atom/browser/api/atom_api_session.h | 2 - atom/browser/api/lib/protocol.js | 9 +--- atom/common/node_bindings.cc | 1 + spec/api-protocol-spec.js | 51 ------------------- 7 files changed, 49 insertions(+), 105 deletions(-) diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 335c20e11e3..09da9c71cad 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -28,6 +28,33 @@ Protocol::Protocol(AtomBrowserContext* browser_context) CHECK(job_factory_); } +mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return mate::ObjectTemplateBuilder(isolate) + .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes) + .SetMethod("registerServiceWorkerSchemes", + &Protocol::RegisterServiceWorkerSchemes) + .SetMethod("registerStringProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerBufferProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerFileProtocol", + &Protocol::RegisterProtocol) + .SetMethod("registerHttpProtocol", + &Protocol::RegisterProtocol) + .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) + .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) + .SetMethod("interceptStringProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptBufferProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptFileProtocol", + &Protocol::InterceptProtocol) + .SetMethod("interceptHttpProtocol", + &Protocol::InterceptProtocol) + .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); +} + void Protocol::RegisterStandardSchemes( const std::vector& schemes) { atom::AtomBrowserClient::SetCustomSchemes(schemes); @@ -126,34 +153,21 @@ mate::Handle Protocol::Create( return mate::CreateHandle(isolate, new Protocol(browser_context)); } -// static -void Protocol::BuildPrototype(v8::Isolate* isolate, - v8::Local prototype) { - mate::ObjectTemplateBuilder(isolate, prototype) - .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes) - .SetMethod("registerServiceWorkerSchemes", - &Protocol::RegisterServiceWorkerSchemes) - .SetMethod("registerStringProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerBufferProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerFileProtocol", - &Protocol::RegisterProtocol) - .SetMethod("registerHttpProtocol", - &Protocol::RegisterProtocol) - .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) - .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) - .SetMethod("interceptStringProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptBufferProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptFileProtocol", - &Protocol::InterceptProtocol) - .SetMethod("interceptHttpProtocol", - &Protocol::InterceptProtocol) - .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol); -} - } // namespace api } // namespace atom + +namespace { + +void Initialize(v8::Local exports, v8::Local unused, + v8::Local context, void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + mate::Dictionary dict(isolate, exports); + auto browser_context = static_cast( + atom::AtomBrowserMainParts::Get()->browser_context()); + dict.Set("protocol", atom::api::Protocol::Create(isolate, browser_context)); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_protocol, Initialize) diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index 36ab46ba823..8aef406fbc3 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -9,7 +9,6 @@ #include #include -#include "atom/browser/api/trackable_object.h" #include "atom/browser/net/atom_url_request_job_factory.h" #include "base/callback.h" #include "base/containers/scoped_ptr_hash_map.h" @@ -31,7 +30,7 @@ class AtomURLRequestJobFactory; namespace api { -class Protocol : public mate::TrackableObject { +class Protocol : public mate::Wrappable { public: using Handler = base::Callback)>; @@ -41,13 +40,13 @@ class Protocol : public mate::TrackableObject { static mate::Handle Create( v8::Isolate* isolate, AtomBrowserContext* browser_context); - // mate::TrackableObject: - static void BuildPrototype(v8::Isolate* isolate, - v8::Local prototype); - protected: explicit Protocol(AtomBrowserContext* browser_context); + // mate::Wrappable implementations: + virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate); + private: // Possible errors. enum ProtocolError { diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 51f7c1bb811..e5c5198f034 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -9,7 +9,6 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/api/atom_api_download_item.h" -#include "atom/browser/api/atom_api_protocol.h" #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_request.h" #include "atom/browser/api/save_page_handler.h" @@ -444,14 +443,6 @@ v8::Local Session::Cookies(v8::Isolate* isolate) { return v8::Local::New(isolate, cookies_); } -v8::Local Session::Protocol(v8::Isolate* isolate) { - if (protocol_.IsEmpty()) { - auto handle = atom::api::Protocol::Create(isolate, browser_context()); - protocol_.Reset(isolate, handle.ToV8()); - } - return v8::Local::New(isolate, protocol_); -} - v8::Local Session::WebRequest(v8::Isolate* isolate) { if (web_request_.IsEmpty()) { auto handle = atom::api::WebRequest::Create(isolate, browser_context()); @@ -499,7 +490,6 @@ void Session::BuildPrototype(v8::Isolate* isolate, &Session::SetPermissionRequestHandler) .SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache) .SetProperty("cookies", &Session::Cookies) - .SetProperty("protocol", &Session::Protocol) .SetProperty("webRequest", &Session::WebRequest); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 63c4cfc612b..02d8ba5cdec 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -80,12 +80,10 @@ class Session: public mate::TrackableObject, mate::Arguments* args); void ClearHostResolverCache(mate::Arguments* args); v8::Local Cookies(v8::Isolate* isolate); - v8::Local Protocol(v8::Isolate* isolate); v8::Local WebRequest(v8::Isolate* isolate); // Cached object. v8::Global cookies_; - v8::Global protocol_; v8::Global web_request_; scoped_refptr browser_context_; diff --git a/atom/browser/api/lib/protocol.js b/atom/browser/api/lib/protocol.js index caef0ad646b..41cb48db09b 100644 --- a/atom/browser/api/lib/protocol.js +++ b/atom/browser/api/lib/protocol.js @@ -4,10 +4,7 @@ if (!app.isReady()) { throw new Error('Can not initialize protocol module before app is ready'); } -const session = require('electron').session; - -// Returns the protocol property for default session. -const protocol = session.defaultSession.protocol; +const protocol = process.atomBinding('protocol').protocol; // Warn about removed APIs. var logAndThrow = function(callback, message) { @@ -19,10 +16,6 @@ var logAndThrow = function(callback, message) { } }; -protocol.fromPartition = function(partition) { - return session.fromPartition(partition).protocol; -}; - protocol.registerProtocol = function(scheme, handler, callback) { return logAndThrow(callback, 'registerProtocol API has been replaced by the register[File/Http/Buffer/String]Protocol API family, please switch to the new APIs.'); }; diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 4af3ba5b64b..69e7906ffbb 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -41,6 +41,7 @@ REFERENCE_MODULE(atom_browser_download_item); REFERENCE_MODULE(atom_browser_menu); 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_session); REFERENCE_MODULE(atom_browser_tray); diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 483155b7065..215868bfdc8 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -3,7 +3,6 @@ const http = require('http'); const path = require('path'); const qs = require('querystring'); const remote = require('electron').remote; -const BrowserWindow = remote.require('electron').BrowserWindow; const protocol = remote.require('electron').protocol; describe('protocol module', function() { @@ -815,54 +814,4 @@ describe('protocol module', function() { }); }); }); - - describe('protocol.fromPartition', function() { - var partitionName = 'temp'; - var tempProtocol = protocol.fromPartition(partitionName); - var w = null; - - beforeEach(function() { - if (w != null) { - w.destroy(); - } - w = new BrowserWindow({ - show: false, - width: 400, - height: 400, - webPreferences: { - partition: partitionName - } - }); - }); - - afterEach(function() { - if (w != null) { - w.destroy(); - } - w = null; - }); - - it('handles requests from a partition', function(done) { - var handler = function(error, callback) { - callback({ - data: text - }); - }; - tempProtocol.registerStringProtocol(protocolName, handler, function(error) { - if (error) { - return done(error); - } - protocol.isProtocolHandled(protocolName, function(result) { - assert.equal(result, false); - }); - tempProtocol.isProtocolHandled(protocolName, function(result) { - assert.equal(result, true); - }); - }); - w.webContents.on('did-finish-load', function() { - done(); - }); - w.loadURL(protocolName + "://fake-host"); - }); - }); }); From 6fcc197db8e98acd1d17c406504e30a5a5f5335b Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 17 Feb 2016 14:22:19 +0530 Subject: [PATCH 302/688] webview: api to get webcontents and associated host webcontents --- atom/browser/api/atom_api_web_contents.cc | 16 ++++++++++++---- atom/browser/api/atom_api_web_contents.h | 4 ++++ .../native_mate_converters/content_converter.cc | 2 ++ atom/renderer/lib/web-view/web-view.js | 8 +++++++- docs/api/web-contents.md | 4 ++++ docs/api/web-view-tag.md | 4 ++++ spec/webview-spec.js | 13 +++++++++++++ 7 files changed, 46 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index ee6ad94ba77..4935adbc75a 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -218,7 +218,8 @@ WebContents::WebContents(content::WebContents* web_contents) WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) - : request_id_(0) { + : embedder_(nullptr), + request_id_(0) { // Whether it is a guest WebContents. bool is_guest = false; options.Get("isGuest", &is_guest); @@ -273,10 +274,10 @@ WebContents::WebContents(v8::Isolate* isolate, guest_delegate_->Initialize(this); NativeWindow* owner_window = nullptr; - WebContents* embedder = nullptr; - if (options.Get("embedder", &embedder) && embedder) { + if (options.Get("embedder", &embedder_) && embedder_) { // New WebContents's owner_window is the embedder's owner_window. - auto relay = NativeWindowRelay::FromWebContents(embedder->web_contents()); + auto relay = + NativeWindowRelay::FromWebContents(embedder_->web_contents()); if (relay) owner_window = relay->window.get(); } @@ -1116,6 +1117,12 @@ v8::Local WebContents::Session(v8::Isolate* isolate) { return v8::Local::New(isolate, session_); } +content::WebContents* WebContents::HostWebContents() { + if (!embedder_) + return nullptr; + return embedder_->web_contents(); +} + v8::Local WebContents::DevToolsWebContents(v8::Isolate* isolate) { if (devtools_web_contents_.IsEmpty()) return v8::Null(isolate); @@ -1199,6 +1206,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("addWorkSpace", &WebContents::AddWorkSpace) .SetMethod("removeWorkSpace", &WebContents::RemoveWorkSpace) .SetProperty("session", &WebContents::Session) + .SetProperty("hostWebContents", &WebContents::HostWebContents) .SetProperty("devToolsWebContents", &WebContents::DevToolsWebContents) .SetProperty("debugger", &WebContents::Debugger); } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 63c4a017771..b4f29090dbd 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -147,6 +147,7 @@ class WebContents : public mate::TrackableObject, // Properties. v8::Local Session(v8::Isolate* isolate); + content::WebContents* HostWebContents(); v8::Local DevToolsWebContents(v8::Isolate* isolate); v8::Local Debugger(v8::Isolate* isolate); @@ -287,6 +288,9 @@ class WebContents : public mate::TrackableObject, scoped_ptr guest_delegate_; + // The host webcontents that may contain this webcontents. + WebContents* embedder_; + // The type of current WebContents. Type type_; diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index 699f101d0e4..f5d81d085bc 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -173,6 +173,8 @@ bool Converter::FromV8( // static v8::Local Converter::ToV8( v8::Isolate* isolate, content::WebContents* val) { + if (!val) + return v8::Null(isolate); return atom::api::WebContents::CreateFrom(isolate, val).ToV8(); } diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 7e38bb33715..44fc1042162 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -388,7 +388,7 @@ var registerWebViewElement = function() { 'downloadURL', 'inspectServiceWorker', 'print', - 'printToPDF' + 'printToPDF', ]; nonblockMethods = [ 'executeJavaScript', @@ -430,6 +430,12 @@ var registerWebViewElement = function() { proto[m] = createNonBlockHandler(m); } + // WebContents associated with this webview. + proto.getWebContents = function() { + var internal = v8Util.getHiddenValue(this, 'internal'); + return internal.webContents; + }; + // Deprecated. deprecate.rename(proto, 'getUrl', 'getURL'); window.WebView = webFrame.registerEmbedderCustomElement('webview', { diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index e0139a29fa6..dde701d7f48 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -842,6 +842,10 @@ win.webContents.on('did-finish-load', function() { Returns the [session](session.md) object used by this webContents. +### `webContents.hostWebContents` + +Returns the `WebContents` that might own this `WebContents`. + ### `webContents.devToolsWebContents` Get the `WebContents` of DevTools for this `WebContents`. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index b4f139d475c..4a0697ad843 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -438,6 +438,10 @@ Sends an input `event` to the page. See [webContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent) for detailed description of `event` object. +### `.getWebContents()` + +Returns the [WebContents](web-contents.md) associated with this `webview`. + ## DOM events The following DOM events are available to the `webview` tag: diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 54b544def0d..d73a177d097 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -703,4 +703,17 @@ describe(' tag', function() { document.body.appendChild(webview); }); }); + + describe('.getWebContents', function() { + it('can return the webcontents associated', function(done) { + webview.addEventListener('did-finish-load', function() { + const webviewContents = webview.getWebContents(); + assert(webviewContents); + assert.equal(webviewContents.getURL(), 'about:blank'); + done(); + }); + webview.src = "about:blank"; + document.body.appendChild(webview); + }); + }); }); From 467870deb64f307be89578205a1e5cab7cc9ad6e Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 24 Feb 2016 16:25:41 +0530 Subject: [PATCH 303/688] use builtin method --- .../v8_value_converter.cc | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/atom/common/native_mate_converters/v8_value_converter.cc b/atom/common/native_mate_converters/v8_value_converter.cc index f5d7217ae52..6a858f2749c 100644 --- a/atom/common/native_mate_converters/v8_value_converter.cc +++ b/atom/common/native_mate_converters/v8_value_converter.cc @@ -4,7 +4,6 @@ #include "atom/common/native_mate_converters/v8_value_converter.h" -#include #include #include #include @@ -21,14 +20,6 @@ namespace { const int kMaxRecursionDepth = 100; -const double kMsPerDay = 24 * 60 * 60 * 1000; - -int TimeInDay(double time_ms) { - if (time_ms < 0) time_ms -= (kMsPerDay -1); - int days = static_cast(time_ms / kMsPerDay); - return static_cast(time_ms - days * kMsPerDay); -} - } // namespace // The state of a call to FromV8Value. @@ -248,20 +239,17 @@ base::Value* V8ValueConverter::FromV8ValueImpl( if (val->IsDate()) { v8::Date* date = v8::Date::Cast(*val); - double const time_ms = date->NumberValue(); - int const time_in_day_ms = TimeInDay(time_ms); - std::time_t time_s(time_ms / 1000.0); - char buf[128]; - std::tm* gm_time = std::gmtime(&time_s); - int year = gm_time->tm_year + 1900; - int month = gm_time->tm_mon + 1; - int ms = time_in_day_ms % 1000; - size_t length = snprintf(buf, sizeof buf, - "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", - year, month, gm_time->tm_mday, - gm_time->tm_hour, gm_time->tm_min, - gm_time->tm_sec, ms); - return new base::StringValue(std::string(buf, length)); + v8::Local toISOString = + date->GetRealNamedPropertyInPrototypeChain( + v8::String::NewFromUtf8(isolate, "toISOString")); + if (toISOString->IsFunction()) { + v8::Local result = + toISOString.As()->Call(val, 0, nullptr); + if (!result.IsEmpty()) { + v8::String::Utf8Value utf8(result->ToString()); + return new base::StringValue(std::string(*utf8, utf8.length())); + } + } } if (val->IsRegExp()) { From d2b48b2aa7ff7ed3bb257f96ef0ed6d46c4c28b9 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Wed, 24 Feb 2016 14:01:26 +0100 Subject: [PATCH 304/688] Fix crash in mate::Converter::ToV8 The net::URLRequest::url() method calls vector::back(), which is undefined when the url_chain is empty --- atom/common/native_mate_converters/net_converter.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 94081b88a3d..184f1c3fecf 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -27,7 +27,9 @@ v8::Local Converter::ToV8( v8::Isolate* isolate, const net::URLRequest* val) { scoped_ptr dict(new base::DictionaryValue); dict->SetString("method", val->method()); - dict->SetStringWithoutPathExpansion("url", val->url().spec()); + std::string url; + if (!val->url_chain().empty()) url = val->url().spec(); + dict->SetStringWithoutPathExpansion("url", url); dict->SetString("referrer", val->referrer()); scoped_ptr list(new base::ListValue); atom::GetUploadData(list.get(), val); From fee56df40074b6730e71591db964477c8fce8b91 Mon Sep 17 00:00:00 2001 From: Dongjoon Hyun Date: Wed, 24 Feb 2016 11:15:21 -0800 Subject: [PATCH 305/688] Rename function `FilterAccecelator` to `FilterAccelerator` in `submenu_button.cc`. --- atom/browser/ui/views/submenu_button.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/ui/views/submenu_button.cc b/atom/browser/ui/views/submenu_button.cc index bedbb98832d..7f413d519c2 100644 --- a/atom/browser/ui/views/submenu_button.cc +++ b/atom/browser/ui/views/submenu_button.cc @@ -15,7 +15,7 @@ namespace atom { namespace { // Filter out the "&" in menu label. -base::string16 FilterAccecelator(const base::string16& label) { +base::string16 FilterAccelerator(const base::string16& label) { base::string16 out; base::RemoveChars(label, base::ASCIIToUTF16("&").c_str(), &out); return out; @@ -26,7 +26,7 @@ base::string16 FilterAccecelator(const base::string16& label) { SubmenuButton::SubmenuButton(views::ButtonListener* listener, const base::string16& title, views::MenuButtonListener* menu_button_listener) - : views::MenuButton(listener, FilterAccecelator(title), + : views::MenuButton(listener, FilterAccelerator(title), menu_button_listener, false), accelerator_(0), show_underline_(false), From a1a17b7ee8d0c1313ef9ac37c33ae979c26b62fd Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 25 Feb 2016 11:21:21 +0530 Subject: [PATCH 306/688] use v8::Object::Get --- atom/common/native_mate_converters/v8_value_converter.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/atom/common/native_mate_converters/v8_value_converter.cc b/atom/common/native_mate_converters/v8_value_converter.cc index 6a858f2749c..1a729dda535 100644 --- a/atom/common/native_mate_converters/v8_value_converter.cc +++ b/atom/common/native_mate_converters/v8_value_converter.cc @@ -240,8 +240,7 @@ base::Value* V8ValueConverter::FromV8ValueImpl( if (val->IsDate()) { v8::Date* date = v8::Date::Cast(*val); v8::Local toISOString = - date->GetRealNamedPropertyInPrototypeChain( - v8::String::NewFromUtf8(isolate, "toISOString")); + date->Get(v8::String::NewFromUtf8(isolate, "toISOString")); if (toISOString->IsFunction()) { v8::Local result = toISOString.As()->Call(val, 0, nullptr); From 2b547bd44a8eca9bd2d0c7872f0a49906d808af7 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 17 Feb 2016 22:33:27 +0530 Subject: [PATCH 307/688] webContents: provide responses for executeJavscript method --- atom/browser/api/lib/ipc-main.js | 4 ++ atom/browser/api/lib/web-contents.js | 14 ++++++- .../native_mate_converters/blink_converter.h | 14 +++++++ atom/renderer/api/atom_api_web_frame.cc | 41 +++++++++++++++++-- atom/renderer/lib/init.js | 10 +++++ atom/renderer/lib/web-view/web-view.js | 17 +++++--- docs/api/web-contents.md | 4 +- docs/api/web-view-tag.md | 4 +- spec/webview-spec.js | 18 +++++++- 9 files changed, 113 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/lib/ipc-main.js b/atom/browser/api/lib/ipc-main.js index e253e03eaab..d6a043a92bf 100644 --- a/atom/browser/api/lib/ipc-main.js +++ b/atom/browser/api/lib/ipc-main.js @@ -1,3 +1,7 @@ const EventEmitter = require('events').EventEmitter; module.exports = new EventEmitter; + +// Every webContents would add a listenter to the +// WEB_FRAME_RESPONSE event, so ignore the listenters warning. +module.exports.setMaxListeners(0); diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index e0c16999c72..c2376af53a2 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -11,6 +11,7 @@ const debuggerBinding = process.atomBinding('debugger'); let slice = [].slice; let nextId = 0; +let responseCallback = {}; let getNextId = function() { return ++nextId; @@ -109,13 +110,24 @@ let wrapWebContents = function(webContents) { // Make sure webContents.executeJavaScript would run the code only when the // webContents has been loaded. const executeJavaScript = webContents.executeJavaScript; - webContents.executeJavaScript = function(code, hasUserGesture) { + webContents.executeJavaScript = function(code, hasUserGesture, callback) { + if (typeof hasUserGesture === "function") { + callback = hasUserGesture; + hasUserGesture = false; + } + if (callback !== null) + responseCallback["executeJavaScript"] = callback; if (this.getURL() && !this.isLoading()) return executeJavaScript.call(this, code, hasUserGesture); else return this.once('did-finish-load', executeJavaScript.bind(this, code, hasUserGesture)); }; + ipcMain.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_RESPONSE', function(event, method, result) { + if (responseCallback[method]) + responseCallback[method].apply(null, [result]); + }); + // Dispatch IPC messages to the ipc module. webContents.on('ipc-message', function(event, packed) { var args, channel; diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h index 6a360192921..f066ea29ccd 100644 --- a/atom/common/native_mate_converters/blink_converter.h +++ b/atom/common/native_mate_converters/blink_converter.h @@ -6,6 +6,7 @@ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ #include "native_mate/converter.h" +#include "third_party/WebKit/public/platform/WebVector.h" namespace blink { class WebInputEvent; @@ -87,6 +88,19 @@ struct Converter { blink::WebFindOptions* out); }; +template +struct Converter > { + static v8::Local ToV8(v8::Isolate* isolate, + const blink::WebVector& val) { + v8::Local result( + MATE_ARRAY_NEW(isolate, static_cast(val.size()))); + for (size_t i = 0; i < val.size(); ++i) { + result->Set(static_cast(i), Converter::ToV8(isolate, val[i])); + } + return result; + } +}; + } // namespace mate #endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index c72882886b9..06c9621b820 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -8,6 +8,7 @@ #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" +#include "atom/common/native_mate_converters/blink_converter.h" #include "atom/renderer/api/atom_api_spell_check_client.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" @@ -15,7 +16,7 @@ #include "native_mate/object_template_builder.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" -#include "third_party/WebKit/public/web/WebScopedUserGesture.h" +#include "third_party/WebKit/public/web/WebScriptExecutionCallback.h" #include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebSecurityPolicy.h" #include "third_party/WebKit/public/web/WebView.h" @@ -26,6 +27,33 @@ namespace atom { namespace api { +namespace { + +class ScriptExecutionCallback : public blink::WebScriptExecutionCallback { + public: + using CompletionCallback = + base::Callback>& result)>; + + explicit ScriptExecutionCallback(const CompletionCallback& callback) + : callback_(callback) {} + ~ScriptExecutionCallback() {} + + void completed( + const blink::WebVector>& result) override { + if (!callback_.is_null()) + callback_.Run(result); + delete this; + } + + private: + CompletionCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(ScriptExecutionCallback); +}; + +} // namespace + WebFrame::WebFrame() : web_frame_(blink::WebLocalFrame::frameForCurrentContext()) { } @@ -124,9 +152,14 @@ void WebFrame::ExecuteJavaScript(const base::string16& code, mate::Arguments* args) { bool has_user_gesture = false; args->GetNext(&has_user_gesture); - scoped_ptr gesture( - has_user_gesture ? new blink::WebScopedUserGesture : nullptr); - web_frame_->executeScriptAndReturnValue(blink::WebScriptSource(code)); + ScriptExecutionCallback::CompletionCallback completion_callback; + args->GetNext(&completion_callback); + scoped_ptr callback( + new ScriptExecutionCallback(completion_callback)); + web_frame_->requestExecuteScriptAndReturnValue( + blink::WebScriptSource(code), + has_user_gesture, + callback.release()); } mate::ObjectTemplateBuilder WebFrame::GetObjectTemplateBuilder( diff --git a/atom/renderer/lib/init.js b/atom/renderer/lib/init.js index 340a1ef5053..ab03a9055ce 100644 --- a/atom/renderer/lib/init.js +++ b/atom/renderer/lib/init.js @@ -32,7 +32,17 @@ v8Util.setHiddenValue(global, 'ipc', new events.EventEmitter); const electron = require('electron'); // Call webFrame method. +const asyncWebFrameMethods = [ + 'executeJavaScript' +]; + electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, method, args) => { + if (asyncWebFrameMethods.includes(method)) { + const responseCallback = function(result) { + event.sender.send('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_RESPONSE', method, result); + }; + args.push(responseCallback); + } electron.webFrame[method].apply(electron.webFrame, args); }); diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 44fc1042162..892ecf56192 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -307,7 +307,7 @@ var registerBrowserPluginElement = function() { // Registers custom element. var registerWebViewElement = function() { - var createBlockHandler, createNonBlockHandler, i, j, len, len1, m, methods, nonblockMethods, proto; + var createBlockHandler, createNonBlockHandler, i, j, len, len1, m, methods, nonblockMethods, webFrameMethods, proto; proto = Object.create(HTMLObjectElement.prototype); proto.createdCallback = function() { return new WebViewImpl(this); @@ -391,14 +391,16 @@ var registerWebViewElement = function() { 'printToPDF', ]; nonblockMethods = [ - 'executeJavaScript', 'insertCSS', - 'insertText', 'send', - 'sendInputEvent', + 'sendInputEvent' + ]; + webFrameMethods = [ + 'executeJavaScript', + 'insertText', 'setZoomFactor', 'setZoomLevel', - 'setZoomLevelLimits', + 'setZoomLevelLimits' ]; // Forward proto.foo* method calls to WebViewImpl.foo*. @@ -430,6 +432,11 @@ var registerWebViewElement = function() { proto[m] = createNonBlockHandler(m); } + // Forward proto.foo* webframe method calls to WebFrame.foo*. + for (let method of webFrameMethods) { + proto[method] = webFrame[method].bind(webFrame); + } + // WebContents associated with this webview. proto.getWebContents = function() { var internal = v8Util.getHiddenValue(this, 'internal'); diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index dde701d7f48..376860b17f9 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -425,10 +425,12 @@ Returns a `String` representing the user agent for this web page. Injects CSS into the current web page. -### `webContents.executeJavaScript(code[, userGesture])` +### `webContents.executeJavaScript(code[, userGesture, callback])` * `code` String * `userGesture` Boolean (optional) +* `callback` Function (optional) - Called after script has been executed. + * `result` Array Evaluates `code` in page. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 4a0697ad843..3bc4f0e9f64 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -279,10 +279,12 @@ Returns a `String` representing the user agent for guest page. Injects CSS into the guest page. -### `.executeJavaScript(code, userGesture)` +### `.executeJavaScript(code, userGesture, callback)` * `code` String * `userGesture` Boolean - Default `false`. +* `callback` Function (optional) - Called after script has been executed. + * `result` Array Evaluates `code` in page. If `userGesture` is set, it will create the user gesture context in the page. HTML APIs like `requestFullScreen`, which require diff --git a/spec/webview-spec.js b/spec/webview-spec.js index d73a177d097..fef49de454f 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -194,6 +194,7 @@ describe(' tag', function() { document.body.appendChild(webview); }); }); + describe('partition attribute', function() { it('inserts no node symbols when not set', function(done) { webview.addEventListener('console-message', function(e) { @@ -356,6 +357,7 @@ describe(' tag', function() { document.body.appendChild(webview); }); }); + describe('did-navigate-in-page event', function() { it('emits when an anchor link is clicked', function(done) { var p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page.html'); @@ -556,7 +558,7 @@ describe(' tag', function() { done(); }; var listener2 = function() { - var jsScript = 'document.getElementsByTagName("video")[0].webkitRequestFullScreen()'; + var jsScript = "document.querySelector('video').webkitRequestFullscreen()"; webview.executeJavaScript(jsScript, true); webview.removeEventListener('did-finish-load', listener2); }; @@ -565,6 +567,20 @@ describe(' tag', function() { webview.src = "file://" + fixtures + "/pages/fullscreen.html"; document.body.appendChild(webview); }); + + it('can return the result of the executed script', function(done) { + var listener = function() { + var jsScript = "'4'+2"; + webview.executeJavaScript(jsScript, false, function(result) { + assert.equal(result[0], '42'); + done(); + }); + webview.removeEventListener('did-finish-load', listener); + }; + webview.addEventListener('did-finish-load', listener); + webview.src = "about:blank"; + document.body.appendChild(webview); + }); }); describe('sendInputEvent', function() { From a734326907d4a23c328cf602dabe62d677ec695b Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 22 Feb 2016 19:30:21 +0530 Subject: [PATCH 308/688] track async api requests --- atom/browser/api/lib/web-contents.js | 29 ++++++++++++++----- .../native_mate_converters/blink_converter.h | 14 --------- atom/renderer/api/atom_api_web_frame.cc | 6 ++-- atom/renderer/lib/init.js | 19 ++++++------ atom/renderer/lib/web-view/web-view.js | 4 +-- docs/api/web-contents.md | 2 +- docs/api/web-view-tag.md | 2 +- spec/webview-spec.js | 2 +- 8 files changed, 39 insertions(+), 39 deletions(-) diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index c2376af53a2..ed8afef7a52 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -11,6 +11,8 @@ const debuggerBinding = process.atomBinding('debugger'); let slice = [].slice; let nextId = 0; + +// Map of requestId and response callback. let responseCallback = {}; let getNextId = function() { @@ -59,13 +61,16 @@ let PDFPageSize = { // Following methods are mapped to webFrame. const webFrameMethods = [ - 'executeJavaScript', 'insertText', 'setZoomFactor', 'setZoomLevel', 'setZoomLevelLimits' ]; +const asyncWebFrameMethods = [ + 'executeJavaScript', +]; + let wrapWebContents = function(webContents) { // webContents is an EventEmitter. var controller, method, name, ref1; @@ -107,25 +112,35 @@ let wrapWebContents = function(webContents) { }; } + for (let method of asyncWebFrameMethods) { + webContents[method] = function() { + let args = Array.prototype.slice.call(arguments); + this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', method, args); + }; + } + // Make sure webContents.executeJavaScript would run the code only when the // webContents has been loaded. const executeJavaScript = webContents.executeJavaScript; webContents.executeJavaScript = function(code, hasUserGesture, callback) { + let requestId = getNextId(); if (typeof hasUserGesture === "function") { callback = hasUserGesture; hasUserGesture = false; } if (callback !== null) - responseCallback["executeJavaScript"] = callback; + responseCallback[requestId] = callback; if (this.getURL() && !this.isLoading()) - return executeJavaScript.call(this, code, hasUserGesture); + return executeJavaScript.call(this, requestId, code, hasUserGesture); else - return this.once('did-finish-load', executeJavaScript.bind(this, code, hasUserGesture)); + return this.once('did-finish-load', executeJavaScript.bind(this, requestId, code, hasUserGesture)); }; - ipcMain.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_RESPONSE', function(event, method, result) { - if (responseCallback[method]) - responseCallback[method].apply(null, [result]); + ipcMain.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE', function(event, id, result) { + if (responseCallback[id]) { + responseCallback[id].apply(null, [result]); + delete responseCallback[id]; + } }); // Dispatch IPC messages to the ipc module. diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h index f066ea29ccd..6a360192921 100644 --- a/atom/common/native_mate_converters/blink_converter.h +++ b/atom/common/native_mate_converters/blink_converter.h @@ -6,7 +6,6 @@ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ #include "native_mate/converter.h" -#include "third_party/WebKit/public/platform/WebVector.h" namespace blink { class WebInputEvent; @@ -88,19 +87,6 @@ struct Converter { blink::WebFindOptions* out); }; -template -struct Converter > { - static v8::Local ToV8(v8::Isolate* isolate, - const blink::WebVector& val) { - v8::Local result( - MATE_ARRAY_NEW(isolate, static_cast(val.size()))); - for (size_t i = 0; i < val.size(); ++i) { - result->Set(static_cast(i), Converter::ToV8(isolate, val[i])); - } - return result; - } -}; - } // namespace mate #endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_ diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index 06c9621b820..af9a3c41621 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -8,7 +8,6 @@ #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" -#include "atom/common/native_mate_converters/blink_converter.h" #include "atom/renderer/api/atom_api_spell_check_client.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" @@ -33,7 +32,7 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback { public: using CompletionCallback = base::Callback>& result)>; + const v8::Local& result)>; explicit ScriptExecutionCallback(const CompletionCallback& callback) : callback_(callback) {} @@ -42,7 +41,8 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback { void completed( const blink::WebVector>& result) override { if (!callback_.is_null()) - callback_.Run(result); + // Right now only single results per frame is supported. + callback_.Run(result[0]); delete this; } diff --git a/atom/renderer/lib/init.js b/atom/renderer/lib/init.js index ab03a9055ce..f7f78e84a1b 100644 --- a/atom/renderer/lib/init.js +++ b/atom/renderer/lib/init.js @@ -32,17 +32,16 @@ v8Util.setHiddenValue(global, 'ipc', new events.EventEmitter); const electron = require('electron'); // Call webFrame method. -const asyncWebFrameMethods = [ - 'executeJavaScript' -]; - electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, method, args) => { - if (asyncWebFrameMethods.includes(method)) { - const responseCallback = function(result) { - event.sender.send('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_RESPONSE', method, result); - }; - args.push(responseCallback); - } + electron.webFrame[method].apply(electron.webFrame, args); +}); + +electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, method, args) => { + let requestId = args.shift(); + const responseCallback = function(result) { + event.sender.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE', requestId, result); + }; + args.push(responseCallback); electron.webFrame[method].apply(electron.webFrame, args); }); diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 892ecf56192..25e5eead2dd 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -393,14 +393,14 @@ var registerWebViewElement = function() { nonblockMethods = [ 'insertCSS', 'send', - 'sendInputEvent' + 'sendInputEvent', ]; webFrameMethods = [ 'executeJavaScript', 'insertText', 'setZoomFactor', 'setZoomLevel', - 'setZoomLevelLimits' + 'setZoomLevelLimits', ]; // Forward proto.foo* method calls to WebViewImpl.foo*. diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 376860b17f9..e095213bd97 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -430,7 +430,7 @@ Injects CSS into the current web page. * `code` String * `userGesture` Boolean (optional) * `callback` Function (optional) - Called after script has been executed. - * `result` Array + * `result` Evaluates `code` in page. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 3bc4f0e9f64..fa48ef60f3f 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -284,7 +284,7 @@ Injects CSS into the guest page. * `code` String * `userGesture` Boolean - Default `false`. * `callback` Function (optional) - Called after script has been executed. - * `result` Array + * `result` Evaluates `code` in page. If `userGesture` is set, it will create the user gesture context in the page. HTML APIs like `requestFullScreen`, which require diff --git a/spec/webview-spec.js b/spec/webview-spec.js index fef49de454f..cd2be69d737 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -572,7 +572,7 @@ describe(' tag', function() { var listener = function() { var jsScript = "'4'+2"; webview.executeJavaScript(jsScript, false, function(result) { - assert.equal(result[0], '42'); + assert.equal(result, '42'); done(); }); webview.removeEventListener('did-finish-load', listener); From 8386baf267545157584588f244bdfa8a75652555 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 24 Feb 2016 15:41:09 +0530 Subject: [PATCH 309/688] add spec --- atom/browser/api/lib/ipc-main.js | 4 ---- atom/browser/api/lib/web-contents.js | 33 ++++++++++------------------ atom/renderer/lib/init.js | 5 ++--- spec/api-browser-window-spec.js | 19 ++++++++++++++++ spec/static/main.js | 11 ++++++++++ 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/atom/browser/api/lib/ipc-main.js b/atom/browser/api/lib/ipc-main.js index d6a043a92bf..e253e03eaab 100644 --- a/atom/browser/api/lib/ipc-main.js +++ b/atom/browser/api/lib/ipc-main.js @@ -1,7 +1,3 @@ const EventEmitter = require('events').EventEmitter; module.exports = new EventEmitter; - -// Every webContents would add a listenter to the -// WEB_FRAME_RESPONSE event, so ignore the listenters warning. -module.exports.setMaxListeners(0); diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index ed8afef7a52..7cd54bfddfb 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -67,10 +67,6 @@ const webFrameMethods = [ 'setZoomLevelLimits' ]; -const asyncWebFrameMethods = [ - 'executeJavaScript', -]; - let wrapWebContents = function(webContents) { // webContents is an EventEmitter. var controller, method, name, ref1; @@ -112,37 +108,32 @@ let wrapWebContents = function(webContents) { }; } - for (let method of asyncWebFrameMethods) { - webContents[method] = function() { - let args = Array.prototype.slice.call(arguments); - this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', method, args); - }; - } + const asyncWebFrameMethods = function(requestId, method, ...args) { + this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', requestId, method, args); + ipcMain.once('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE_' + requestId, function(event, result) { + if (responseCallback[requestId]) { + responseCallback[requestId](result); + delete responseCallback[requestId]; + } + }); + }; // Make sure webContents.executeJavaScript would run the code only when the // webContents has been loaded. - const executeJavaScript = webContents.executeJavaScript; webContents.executeJavaScript = function(code, hasUserGesture, callback) { let requestId = getNextId(); if (typeof hasUserGesture === "function") { callback = hasUserGesture; hasUserGesture = false; } - if (callback !== null) + if (callback != null) responseCallback[requestId] = callback; if (this.getURL() && !this.isLoading()) - return executeJavaScript.call(this, requestId, code, hasUserGesture); + return asyncWebFrameMethods.call(this, requestId, "executeJavaScript", code, hasUserGesture); else - return this.once('did-finish-load', executeJavaScript.bind(this, requestId, code, hasUserGesture)); + return this.once('did-finish-load', asyncWebFrameMethods.bind(this, requestId, "executeJavaScript", code, hasUserGesture)); }; - ipcMain.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE', function(event, id, result) { - if (responseCallback[id]) { - responseCallback[id].apply(null, [result]); - delete responseCallback[id]; - } - }); - // Dispatch IPC messages to the ipc module. webContents.on('ipc-message', function(event, packed) { var args, channel; diff --git a/atom/renderer/lib/init.js b/atom/renderer/lib/init.js index f7f78e84a1b..cf42aa27229 100644 --- a/atom/renderer/lib/init.js +++ b/atom/renderer/lib/init.js @@ -36,10 +36,9 @@ electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, m electron.webFrame[method].apply(electron.webFrame, args); }); -electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, method, args) => { - let requestId = args.shift(); +electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => { const responseCallback = function(result) { - event.sender.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE', requestId, result); + event.sender.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE_' + requestId, result); }; args.push(responseCallback); electron.webFrame[method].apply(electron.webFrame, args); diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 58cf57cc8d0..25e92382cca 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -10,6 +10,7 @@ const screen = require('electron').screen; const app = remote.require('electron').app; const ipcMain = remote.require('electron').ipcMain; +const ipcRenderer = require('electron').ipcRenderer; const BrowserWindow = remote.require('electron').BrowserWindow; const isCI = remote.getGlobal('isCi'); @@ -690,4 +691,22 @@ describe('browser-window module', function() { assert.equal(fs.existsSync(serializedPath), false); }); }); + + describe('window.webContents.executeJavaScript', function() { + var expected = 'hello, world!'; + var code = '(() => \"' + expected + '\")()'; + + it('doesnt throw when no calback is provided', function() { + const result = ipcRenderer.sendSync('executeJavaScript', code, false); + assert.equal(result, 'success'); + }); + + it('returns result when calback is provided', function(done) { + ipcRenderer.send('executeJavaScript', code, true); + ipcRenderer.once('executeJavaScript-response', function(event, result) { + assert.equal(result, expected); + done(); + }); + }); + }); }); diff --git a/spec/static/main.js b/spec/static/main.js index 48fdf17c3dc..9a049e3f107 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -138,4 +138,15 @@ app.on('ready', function() { }); event.returnValue = "done"; }); + + ipcMain.on('executeJavaScript', function(event, code, hasCallback) { + if (hasCallback) { + window.webContents.executeJavaScript(code, (result) => { + window.webContents.send('executeJavaScript-response', result); + }); + } else { + window.webContents.executeJavaScript(code); + event.returnValue = "success"; + } + }); }); From 6f45678e9c68874474de2d3727f16a96ac45a528 Mon Sep 17 00:00:00 2001 From: Robert Lyall Date: Thu, 25 Feb 2016 18:28:03 +0000 Subject: [PATCH 310/688] Fix Menu template API example --- docs-translations/jp/api/menu.md | 2 +- docs-translations/ko-KR/api/menu.md | 2 +- docs/api/menu.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs-translations/jp/api/menu.md b/docs-translations/jp/api/menu.md index e68a69cca83..12039b1d6ad 100644 --- a/docs-translations/jp/api/menu.md +++ b/docs-translations/jp/api/menu.md @@ -135,7 +135,7 @@ var template = [ ]; if (process.platform == 'darwin') { - var name = require('electron').app.getName(); + var name = require('electron').remote.app.getName(); template.unshift({ label: name, submenu: [ diff --git a/docs-translations/ko-KR/api/menu.md b/docs-translations/ko-KR/api/menu.md index 347ea880dce..61c68023b07 100644 --- a/docs-translations/ko-KR/api/menu.md +++ b/docs-translations/ko-KR/api/menu.md @@ -140,7 +140,7 @@ var template = [ ]; if (process.platform == 'darwin') { - var name = require('electron').app.getName(); + var name = require('electron').remote.app.getName(); template.unshift({ label: name, submenu: [ diff --git a/docs/api/menu.md b/docs/api/menu.md index 49a499a3d4b..7d05f88aa2b 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -143,7 +143,7 @@ var template = [ ]; if (process.platform == 'darwin') { - var name = require('electron').app.getName(); + var name = require('electron').remote.app.getName(); template.unshift({ label: name, submenu: [ From 9a0372b61be525c528919742384ecc56bf3428ec Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 25 Feb 2016 23:48:58 +0100 Subject: [PATCH 311/688] Removed size_ since it's not needed anymore --- atom/browser/api/frame_subscriber.cc | 6 +++--- atom/browser/api/frame_subscriber.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index ec3bcd05ab7..4653fc452ad 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -4,13 +4,14 @@ #include "atom/browser/api/frame_subscriber.h" -#include "atom/common/node_includes.h" #include "base/bind.h" +#include "atom/common/node_includes.h" #include "media/base/video_frame.h" #include "media/base/yuv_convert.h" -#include "content/public/browser/render_widget_host.h" #include "ui/gfx/screen.h" +#include "content/public/browser/render_widget_host.h" + namespace atom { namespace api { @@ -22,7 +23,6 @@ FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, const FrameCaptureCallback& callback) : isolate_(isolate), callback_(callback), pending_frames(0), view_(view) { subscriber_ = new Subscriber(this); - size_ = view->GetVisibleViewportSize(); } Subscriber::Subscriber( diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h index 745cf382adb..7029e0ed33a 100644 --- a/atom/browser/api/frame_subscriber.h +++ b/atom/browser/api/frame_subscriber.h @@ -6,12 +6,13 @@ #define ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_ #include "base/callback.h" +#include "v8/include/v8.h" + #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/render_widget_host_view_frame_subscriber.h" #include "content/public/browser/readback_types.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/geometry/size.h" -#include "v8/include/v8.h" namespace atom { @@ -50,7 +51,6 @@ class FrameSubscriber { bool RequestDestruct(); v8::Isolate* isolate_; - gfx::Size size_; content::RenderWidgetHostView* view_; FrameCaptureCallback callback_; Subscriber* subscriber_; From 12359078357f0d0227864a9700e660a673f764e3 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 25 Feb 2016 23:35:01 +0530 Subject: [PATCH 312/688] run webframe methods for webview in its context --- atom/browser/api/lib/web-contents.js | 19 ++++++------------ atom/browser/lib/rpc-server.js | 10 ++++++++-- atom/renderer/api/atom_api_web_frame.cc | 2 +- atom/renderer/lib/init.js | 2 +- atom/renderer/lib/web-view/web-view.js | 26 +++++++++++++++---------- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index 7cd54bfddfb..9486378264b 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -12,9 +12,6 @@ const debuggerBinding = process.atomBinding('debugger'); let slice = [].slice; let nextId = 0; -// Map of requestId and response callback. -let responseCallback = {}; - let getNextId = function() { return ++nextId; }; @@ -108,13 +105,11 @@ let wrapWebContents = function(webContents) { }; } - const asyncWebFrameMethods = function(requestId, method, ...args) { + const asyncWebFrameMethods = function(requestId, method, callback, ...args) { this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', requestId, method, args); - ipcMain.once('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE_' + requestId, function(event, result) { - if (responseCallback[requestId]) { - responseCallback[requestId](result); - delete responseCallback[requestId]; - } + ipcMain.once(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, function(event, result) { + if (callback) + callback(result); }); }; @@ -126,12 +121,10 @@ let wrapWebContents = function(webContents) { callback = hasUserGesture; hasUserGesture = false; } - if (callback != null) - responseCallback[requestId] = callback; if (this.getURL() && !this.isLoading()) - return asyncWebFrameMethods.call(this, requestId, "executeJavaScript", code, hasUserGesture); + return asyncWebFrameMethods.call(this, requestId, "executeJavaScript", callback, code, hasUserGesture); else - return this.once('did-finish-load', asyncWebFrameMethods.bind(this, requestId, "executeJavaScript", code, hasUserGesture)); + return this.once('did-finish-load', asyncWebFrameMethods.bind(this, requestId, "executeJavaScript", callback, code, hasUserGesture)); }; // Dispatch IPC messages to the ipc module. diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index 20ee8fbdeae..a31c6e146e8 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -354,11 +354,17 @@ ipcMain.on('ATOM_BROWSER_GUEST_WEB_CONTENTS', function(event, guestInstanceId) { } }); -ipcMain.on('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function(event, guestInstanceId, method, ...args) { +ipcMain.on('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function(event, requestId, guestInstanceId, method, ...args) { try { let guestViewManager = require('./guest-view-manager'); let guest = guestViewManager.getGuest(guestInstanceId); - return guest[method].apply(guest, args); + if (requestId) { + const responseCallback = function(result) { + event.sender.send(`ATOM_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, result); + }; + args.push(responseCallback); + } + guest[method].apply(guest, args); } catch (error) { return event.returnValue = exceptionToMeta(error); } diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index af9a3c41621..e00b901bfff 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -40,7 +40,7 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback { void completed( const blink::WebVector>& result) override { - if (!callback_.is_null()) + if (!callback_.is_null() && !result.isEmpty() && !result[0].IsEmpty()) // Right now only single results per frame is supported. callback_.Run(result[0]); delete this; diff --git a/atom/renderer/lib/init.js b/atom/renderer/lib/init.js index cf42aa27229..166e64237de 100644 --- a/atom/renderer/lib/init.js +++ b/atom/renderer/lib/init.js @@ -38,7 +38,7 @@ electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, m electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => { const responseCallback = function(result) { - event.sender.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE_' + requestId, result); + event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, result); }; args.push(responseCallback); electron.webFrame[method].apply(electron.webFrame, args); diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 25e5eead2dd..bd128f6fffe 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -307,7 +307,7 @@ var registerBrowserPluginElement = function() { // Registers custom element. var registerWebViewElement = function() { - var createBlockHandler, createNonBlockHandler, i, j, len, len1, m, methods, nonblockMethods, webFrameMethods, proto; + var createBlockHandler, createNonBlockHandler, i, j, len, len1, m, methods, nonblockMethods, proto; proto = Object.create(HTMLObjectElement.prototype); proto.createdCallback = function() { return new WebViewImpl(this); @@ -392,12 +392,9 @@ var registerWebViewElement = function() { ]; nonblockMethods = [ 'insertCSS', + 'insertText', 'send', 'sendInputEvent', - ]; - webFrameMethods = [ - 'executeJavaScript', - 'insertText', 'setZoomFactor', 'setZoomLevel', 'setZoomLevelLimits', @@ -424,7 +421,7 @@ var registerWebViewElement = function() { var args, internal; args = 1 <= arguments.length ? slice.call(arguments, 0) : []; internal = v8Util.getHiddenValue(this, 'internal'); - return ipcRenderer.send.apply(ipcRenderer, ['ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', internal.guestInstanceId, m].concat(slice.call(args))); + return ipcRenderer.send.apply(ipcRenderer, ['ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', null, internal.guestInstanceId, m].concat(slice.call(args))); }; }; for (j = 0, len1 = nonblockMethods.length; j < len1; j++) { @@ -432,10 +429,19 @@ var registerWebViewElement = function() { proto[m] = createNonBlockHandler(m); } - // Forward proto.foo* webframe method calls to WebFrame.foo*. - for (let method of webFrameMethods) { - proto[method] = webFrame[method].bind(webFrame); - } + proto.executeJavaScript = function(code, hasUserGesture, callback) { + var internal = v8Util.getHiddenValue(this, 'internal'); + if (typeof hasUserGesture === "function") { + callback = hasUserGesture; + hasUserGesture = false; + } + let requestId = getNextId(); + ipcRenderer.send('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', requestId, internal.guestInstanceId, "executeJavaScript", code, hasUserGesture); + ipcRenderer.once(`ATOM_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, function(event, result) { + if (callback) + callback(result); + }); + }; // WebContents associated with this webview. proto.getWebContents = function() { From 4bfa03e5f4574ecea0d513b359406ded69449f9c Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Fri, 26 Feb 2016 02:13:17 +0100 Subject: [PATCH 313/688] Removed an include no longer needed --- atom/browser/api/frame_subscriber.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index 89e05d3e2dc..c76d5ffc87d 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -6,8 +6,6 @@ #include "base/bind.h" #include "atom/common/node_includes.h" -#include "ui/gfx/screen.h" - #include "content/public/browser/render_widget_host.h" namespace atom { From a3b8e81c213a157d944937c7c73641040622529e Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Wed, 24 Feb 2016 12:19:43 -0800 Subject: [PATCH 314/688] :memo: Add Headless CI Tutorial --- docs/README.md | 1 + docs/tutorial/testing-on-headless-ci.md | 38 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 docs/tutorial/testing-on-headless-ci.md diff --git a/docs/README.md b/docs/README.md index 9d2b36eb6c1..19ec51343d4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -26,6 +26,7 @@ an issue: * [DevTools Extension](tutorial/devtools-extension.md) * [Using Pepper Flash Plugin](tutorial/using-pepper-flash-plugin.md) * [Using Widevine CDM Plugin](tutorial/using-widevine-cdm-plugin.md) +* [Testing on Headless CI Systems (Travis, Jenkins)](tutorial/testing-on-headless-ci.md) ## Tutorials diff --git a/docs/tutorial/testing-on-headless-ci.md b/docs/tutorial/testing-on-headless-ci.md new file mode 100644 index 00000000000..6b0dacf788f --- /dev/null +++ b/docs/tutorial/testing-on-headless-ci.md @@ -0,0 +1,38 @@ +# Testing Electron with headless CI Systems (Travis CI, Jenkins) + +Being based on Chromium, Electron requires a display driver to function. If Chromium can't find a display driver, Electron will simply fail to launch - and therefore not executing any of your tests, regardless of how you are running them. Testing Electron-based apps on Travis, Circle, Jenkins or similar systems requires therefore a little bit of configuration. In essence, we need to use a virtual display driver. + +## Configuring the Virtual Display Server +First, install [Xvfb](https://en.wikipedia.org/wiki/Xvfb). It's a virtual framebuffer, implementing the X11 display server protocol - it performs all graphical operations in memory without showing any screen output, which is exactly what we need. + +Then, create a virtual xvfb screen and export an environment variable called DISPLAY that points to it. Chromium in Electron will automatically look for `$DISPLAY`, so no further configuration of your app is required. This step can be automated with Paul Betts's [xfvb-maybe](https://github.com/paulcbetts/xvfb-maybe): Prepend your test commands with `xfvb-maybe` and the little tool will automatically configure xfvb, if required by the current system. On Windows or Mac OS X, it will simply do nothing. + +``` +## On Windows or OS X, this just invokes electron-mocha +## On Linux, if we are in a headless environment, this will be equivalent +## to xvfb-run electron-mocha ./test/*.js +xvfb-maybe electron-mocha ./test/*.js +``` + +### Travis CI +On Travis, your `.travis.yml` should look roughly like this: + +``` +addons: + apt: + packages: + - xvfb + +install: + - export DISPLAY=':99.0' + - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & +``` + +### Jenkins +For Jenkins, a [Xfvb plugin is available](https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin). + +### Circle CI +Circle CI is awesome and has xvfb and `$DISPLAY` [already setup, so no further configuration is required](https://circleci.com/docs/environment#browsers). + +### AppVeyor +AppVeyor runs on Windows, supporting Selenium, Chromium, Electron and similar tools out of the box - no configuration is required. From 8a744255facacf54cecc8b5eb526ce08afab1ec4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 26 Feb 2016 09:23:39 +0800 Subject: [PATCH 315/688] Update libchromiumcontent, use harfbuzz 1.06 Close #4513. --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index e3404918ce4..d4a055912e4 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '599c8941e1884e155218ec1013cba9fc5c7c7072' +LIBCHROMIUMCONTENT_COMMIT = 'ff714bf7ad79b0d278bcd20c3081a69b40be8bb8' PLATFORM = { 'cygwin': 'win32', From a67b29d8d28c1eb993c89a097dda17c0cf63d99b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 26 Feb 2016 02:18:27 +0000 Subject: [PATCH 316/688] Bump v0.36.9 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index 68a30cc637f..0bccc254b1b 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.36.8', + 'version%': '0.36.9', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index e1a5694d27a..b3eb7d8efaa 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.36.8 + 0.36.9 CFBundleShortVersionString - 0.36.8 + 0.36.9 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index ff125b3edf7..2dee1c0e433 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,36,8,0 - PRODUCTVERSION 0,36,8,0 + FILEVERSION 0,36,9,0 + PRODUCTVERSION 0,36,9,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.36.8" + VALUE "FileVersion", "0.36.9" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.36.8" + VALUE "ProductVersion", "0.36.9" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index b464ebdae4f..136c375e2ac 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 36 -#define ATOM_PATCH_VERSION 8 +#define ATOM_PATCH_VERSION 9 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index e6d399fb3be..504bdd6a4f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.36.8", + "version": "0.36.9", "devDependencies": { "asar": "^0.10.0", "eslint": "^2.1.0", From fce641aab64da828cf03afd2e07b7b81333655ad Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 26 Feb 2016 15:47:28 +0530 Subject: [PATCH 317/688] browser: allow enumeration of media device labels --- atom/browser/api/atom_api_web_contents.cc | 7 +++++++ atom/browser/api/atom_api_web_contents.h | 4 ++++ spec/chromium-spec.js | 14 ++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 4935adbc75a..28893a54a3d 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -463,6 +463,13 @@ void WebContents::FindReply(content::WebContents* web_contents, } } +bool WebContents::CheckMediaAccessPermission( + content::WebContents* web_contents, + const GURL& security_origin, + content::MediaStreamType type) { + return true; +} + void WebContents::RequestMediaAccessPermission( content::WebContents* web_contents, const content::MediaStreamRequest& request, diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index b4f29090dbd..a785e1c070d 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -202,6 +202,10 @@ class WebContents : public mate::TrackableObject, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) override; + bool CheckMediaAccessPermission( + content::WebContents* web_contents, + const GURL& security_origin, + content::MediaStreamType type) override; void RequestMediaAccessPermission( content::WebContents* web_contents, const content::MediaStreamRequest& request, diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index e4444f55b11..8477aea776a 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -87,6 +87,20 @@ describe('chromium feature', function() { }); }); + describe('navigator.mediaDevices', function() { + if (process.env.TRAVIS === 'true') { + return; + } + + it('can return labels of enumerated devices', function(done) { + navigator.mediaDevices.enumerateDevices().then((devices) => { + const result = devices.some((device) => !!device.label); + if (result) + done(); + }); + }); + }); + describe('navigator.language', function() { it('should not be empty', function() { assert.notEqual(navigator.language, ''); From 070772b4b984e0bc03cea28388dffaa63b14d0d0 Mon Sep 17 00:00:00 2001 From: gellert Date: Sat, 6 Feb 2016 22:33:21 +0100 Subject: [PATCH 318/688] Added special key identifiers for OSX and Windows --- atom/common/keyboard_util.cc | 10 ++++++++++ docs/api/web-contents.md | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/atom/common/keyboard_util.cc b/atom/common/keyboard_util.cc index e5dedd84ded..1884246d233 100644 --- a/atom/common/keyboard_util.cc +++ b/atom/common/keyboard_util.cc @@ -80,6 +80,16 @@ ui::KeyboardCode KeyboardCodeFromKeyIdentifier(const std::string& chr) { if (chr == "tab") return ui::VKEY_TAB; if (chr == "escape") return ui::VKEY_ESCAPE; if (chr == "control") return ui::VKEY_CONTROL; +#if defined(OS_MACOSX) + if (chr == "command" + || chr == "cmd" + || chr == "meta") return ui::VKEY_COMMAND; + if (chr == "option") return ui::VKEY_MENU; +#endif +#if defined(OS_WIN) + if (chr == "meta") return ui::VKEY_LWIN; + if (chr == "altgr") return ui::VKEY_ALTGR; +#endif if (chr == "alt") return ui::VKEY_MENU; if (chr == "shift") return ui::VKEY_SHIFT; if (chr == "end") return ui::VKEY_END; diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index dde701d7f48..31c55801aab 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -769,8 +769,10 @@ For keyboard events, the `event` object also have following properties: * `keyCode` Char or String (**required**) - The character that will be sent as the keyboard event. Can be a single UTF-8 character, or the name of the key that generates the event. Accepted key names are `enter`, `backspace`, - `delete`, `tab`, `escape`, `control`, `alt`, `shift`, `end`, `home`, `insert`, - `left`, `up`, `right`, `down`, `pageUp`, `pageDown`, `printScreen` + `delete`, `tab`, `escape`, `control`, `alt`, `altgr` (Windows only), `shift`, + `end`, `home`, `insert`, `left`, `up`, `right`, `down`, `pageUp`, `pageDown`, + `printScreen`, `meta`, `cmd` (OSX only), `command` (OSX only), `option` + (OSX only) For mouse events, the `event` object also have following properties: From bb0ac688b2d1d19904370a33a49a19c75a31e129 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Sat, 27 Feb 2016 03:07:53 +0100 Subject: [PATCH 319/688] Reverted SetFullscreenable disabling maximize button on Windows and removed that from the docs. --- atom/browser/native_window_views.cc | 3 --- docs/api/browser-window.md | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 4b3b32024df..c74e8808150 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -497,9 +497,6 @@ bool NativeWindowViews::IsMaximizable() { } void NativeWindowViews::SetFullScreenable(bool fullscreenable) { - #if defined(OS_WIN) - FlipWindowStyle(GetAcceleratedWidget(), false, WS_MAXIMIZEBOX); - #endif fullscreenable_ = fullscreenable; } diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 96ce955db59..d38a5b7083d 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -59,8 +59,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. other windows. Default is `false`. * `fullscreen` Boolean - Whether the window should show in fullscreen. When explicity set to `false` the fullscreen button will be hidden or disabled - on OS X, or the maximize button will be disabled on Windows. Default is - `false`. + on OS X. Default is `false`. * `fullscreenable` Boolean - Whether the maximize/zoom button on OS X should toggle full screen mode or maximize window. Default is `true`. * `skipTaskbar` Boolean - Whether to show the window in taskbar. Default is From fd11b7e7db57683da2453cb61a289d53012923d2 Mon Sep 17 00:00:00 2001 From: Andrea Parodi Date: Sat, 27 Feb 2016 20:34:51 +0100 Subject: [PATCH 320/688] Removed duplicate isDevToolsFocused entry --- docs/api/web-contents.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 25597d9b6c8..66ab545bf21 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -664,10 +664,6 @@ Returns whether the devtools view is focused . Toggles the developer tools. -### `webContents.isDevToolsFocused()` - -Returns whether the developer tools is focused. - ### `webContents.inspectElement(x, y)` * `x` Integer From a06392459e2c43fcc2070513f564d506526d837f Mon Sep 17 00:00:00 2001 From: brenca Date: Sat, 27 Feb 2016 22:37:42 +0100 Subject: [PATCH 321/688] Making fullsceenable work on Linux --- atom/browser/native_window.cc | 4 ++-- atom/browser/native_window_views.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 273bd948fe5..16154be6bea 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -133,7 +133,7 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { if (options.Get(options::kAlwaysOnTop, &top) && top) { SetAlwaysOnTop(true); } -#if defined(OS_MACOSX) || defined(OS_WIN) + // Disable fullscreen button when 'fullscreenable' is false or 'fullscreen' // is specified to false. bool fullscreenable = true; @@ -144,7 +144,7 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { SetFullScreenable(fullscreenable); if (fullscreen) SetFullScreen(true); -#endif + bool skip; if (options.Get(options::kSkipTaskbar, &skip) && skip) { SetSkipTaskbar(skip); diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 1c9493a1cf9..a0c2e3f170b 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -379,7 +379,7 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) { if (IsFullScreenable()) window_->SetFullscreen(fullscreen); #else - if (!fullscreen || IsFullScreenable()) { + if (!fullscreen || (fullscreen && IsFullScreenable())) { if (IsVisible()) window_->SetFullscreen(fullscreen); else From 681a772f5f4797fe4e7efeb5b8f094d801a1c43a Mon Sep 17 00:00:00 2001 From: RacioN Date: Sun, 28 Feb 2016 20:42:14 +0900 Subject: [PATCH 322/688] Add list --- docs-translations/jp/README.md | 55 ++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs-translations/jp/README.md b/docs-translations/jp/README.md index accde973976..6248e35044d 100644 --- a/docs-translations/jp/README.md +++ b/docs-translations/jp/README.md @@ -3,6 +3,7 @@ そうでない場合、おそらくご使用の Electron のバージョンと互換性のない API 変更を含んだ development ブランチのドキュメントを使っているものと思われます。 その場合、atom.io の [available versions](http://electron.atom.io/docs/) リストにある別のバージョンのドキュメントに切り替えることができます。また GitHub で閲覧している場合、"Switch branches/tags" ドロップダウンを開いて、バージョンに対応したタグを選ぶこともできます。 +_リンクになっていないリストは未翻訳のものです。_ ## FAQ 頻繁に聞かれる質問がありますので、issueを作成する前にこれをチェックしてください。 @@ -31,3 +32,57 @@ ## API リファレンス * [概要](api/synopsis.md) +* [Process Object](api/process.md) +* [Supported Chrome Command Line Switches](api/chrome-command-line-switches.md) +* [Environment Variables](api/environment-variables.md) + +### Custom DOM Elements: + +* [`File` Object](api/file-object.md) +* `` Tag +* [`window.open` Function](api/window-open.md) + +### Modules for the Main Process: + +* [app](api/app.md) +* [autoUpdater](api/auto-updater.md) +* BrowserWindow + * [frameless-window](frameless-window.md) +* [contentTracing](api/content-tracing.md) +* [dialog](api/dialog.md) +* [globalShortcut](api/global-shortcut.md) +* [ipcMain](api/ipc-main.md) +* [Menu](api/menu.md) +* [MenuItem](api/menu-item.md) +* [powerMonitor](api/power-monitor.md) +* [powerSaveBlocker](api/power-save-blocker.md) +* [protocol](api/protocol.md) +* [session](api/session.md) +* webContents +* [Tray](api/tray.md) + +### Modules for the Renderer Process (Web Page): + +* [desktopCapturer](api/desktop-capturer.md) +* [ipcRenderer](api/ipc-renderer.md) +* [remote](api/remote.md) +* [webFrame](api/web-frame.md) + +### Modules for Both Processes: + +* [clipboard](api/clipboard.md) +* [crashReporter](api/crash-reporter.md) +* [nativeImage](api/native-image.md) +* [screen](api/screen.md) +* [shell](api/shell.md) + +## Development + +* [Coding Style](development/coding-style.md) +* [Source Code Directory Structure](development/source-code-directory-structure.md) +* [Technical Differences to NW.js (formerly node-webkit)](development/atom-shell-vs-node-webkit.md) +* [Build System Overview](development/build-system-overview.md) +* [Build Instructions (OS X)](development/build-instructions-osx.md) +* [Build Instructions (Windows)](development/build-instructions-windows.md) +* [Build Instructions (Linux)](development/build-instructions-linux.md) +* [Setting Up Symbol Server in debugger](development/setting-up-symbol-server.md) From e3dde12c45d2e8817005c74beea1f57696d3f13b Mon Sep 17 00:00:00 2001 From: RacioN Date: Sun, 28 Feb 2016 20:50:16 +0900 Subject: [PATCH 323/688] Update read me tranlation --- docs-translations/jp/README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs-translations/jp/README.md b/docs-translations/jp/README.md index 6248e35044d..558d362498a 100644 --- a/docs-translations/jp/README.md +++ b/docs-translations/jp/README.md @@ -33,21 +33,21 @@ _リンクになっていないリストは未翻訳のものです。_ * [概要](api/synopsis.md) * [Process Object](api/process.md) -* [Supported Chrome Command Line Switches](api/chrome-command-line-switches.md) -* [Environment Variables](api/environment-variables.md) +* [サポートしているChromeコマンドラインスイッチ](api/chrome-command-line-switches.md) +* [環境変数](api/environment-variables.md) ### Custom DOM Elements: * [`File` Object](api/file-object.md) * `` Tag -* [`window.open` Function](api/window-open.md) +* [`window.open` 関数](api/window-open.md) ### Modules for the Main Process: * [app](api/app.md) * [autoUpdater](api/auto-updater.md) * BrowserWindow - * [frameless-window](frameless-window.md) + * [フレームの無いウィンドウ](api/frameless-window.md) * [contentTracing](api/content-tracing.md) * [dialog](api/dialog.md) * [globalShortcut](api/global-shortcut.md) @@ -78,11 +78,11 @@ _リンクになっていないリストは未翻訳のものです。_ ## Development -* [Coding Style](development/coding-style.md) -* [Source Code Directory Structure](development/source-code-directory-structure.md) -* [Technical Differences to NW.js (formerly node-webkit)](development/atom-shell-vs-node-webkit.md) -* [Build System Overview](development/build-system-overview.md) -* [Build Instructions (OS X)](development/build-instructions-osx.md) -* [Build Instructions (Windows)](development/build-instructions-windows.md) -* [Build Instructions (Linux)](development/build-instructions-linux.md) -* [Setting Up Symbol Server in debugger](development/setting-up-symbol-server.md) +* Coding Style +* Source Code Directory Structure +* Technical Differences to NW.js (formerly node-webkit) +* Build System Overview +* Build Instructions (OS X) +* Build Instructions (Windows) +* Build Instructions (Linux) +* Setting Up Symbol Server in debugger From 2d11b1d9eb36e88d8650ed7596b5b8d29ff508e9 Mon Sep 17 00:00:00 2001 From: RacioN Date: Sun, 28 Feb 2016 20:55:47 +0900 Subject: [PATCH 324/688] Update read me tranlation --- docs-translations/jp/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs-translations/jp/README.md b/docs-translations/jp/README.md index 558d362498a..a71661a7e53 100644 --- a/docs-translations/jp/README.md +++ b/docs-translations/jp/README.md @@ -36,13 +36,13 @@ _リンクになっていないリストは未翻訳のものです。_ * [サポートしているChromeコマンドラインスイッチ](api/chrome-command-line-switches.md) * [環境変数](api/environment-variables.md) -### Custom DOM Elements: +### カスタムDOM要素: * [`File` Object](api/file-object.md) * `` Tag * [`window.open` 関数](api/window-open.md) -### Modules for the Main Process: +### Main Processのモジュール: * [app](api/app.md) * [autoUpdater](api/auto-updater.md) @@ -61,14 +61,14 @@ _リンクになっていないリストは未翻訳のものです。_ * webContents * [Tray](api/tray.md) -### Modules for the Renderer Process (Web Page): +### Renderer Processのモジュール (Web Page): * [desktopCapturer](api/desktop-capturer.md) * [ipcRenderer](api/ipc-renderer.md) * [remote](api/remote.md) * [webFrame](api/web-frame.md) -### Modules for Both Processes: +### 両方のProcessのモジュール : * [clipboard](api/clipboard.md) * [crashReporter](api/crash-reporter.md) @@ -76,7 +76,7 @@ _リンクになっていないリストは未翻訳のものです。_ * [screen](api/screen.md) * [shell](api/shell.md) -## Development +## 開発 * Coding Style * Source Code Directory Structure From 24ae9b0ea923fdf84999dad134a8cccb001cbe53 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Mon, 29 Feb 2016 01:38:32 +0900 Subject: [PATCH 325/688] Cleanup docs * Adjust 80 chars per line * Line feed after header --- docs/tutorial/testing-on-headless-ci.md | 32 +++++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/docs/tutorial/testing-on-headless-ci.md b/docs/tutorial/testing-on-headless-ci.md index 6b0dacf788f..ec1f4635c90 100644 --- a/docs/tutorial/testing-on-headless-ci.md +++ b/docs/tutorial/testing-on-headless-ci.md @@ -1,11 +1,27 @@ # Testing Electron with headless CI Systems (Travis CI, Jenkins) -Being based on Chromium, Electron requires a display driver to function. If Chromium can't find a display driver, Electron will simply fail to launch - and therefore not executing any of your tests, regardless of how you are running them. Testing Electron-based apps on Travis, Circle, Jenkins or similar systems requires therefore a little bit of configuration. In essence, we need to use a virtual display driver. +Being based on Chromium, Electron requires a display driver to function. +If Chromium can't find a display driver, Electron will simply fail to launch - +and therefore not executing any of your tests, regardless of how you are running +them. Testing Electron-based apps on Travis, Circle, Jenkins or similar Systems +requires therefore a little bit of configuration. In essence, we need to use +a virtual display driver. ## Configuring the Virtual Display Server -First, install [Xvfb](https://en.wikipedia.org/wiki/Xvfb). It's a virtual framebuffer, implementing the X11 display server protocol - it performs all graphical operations in memory without showing any screen output, which is exactly what we need. -Then, create a virtual xvfb screen and export an environment variable called DISPLAY that points to it. Chromium in Electron will automatically look for `$DISPLAY`, so no further configuration of your app is required. This step can be automated with Paul Betts's [xfvb-maybe](https://github.com/paulcbetts/xvfb-maybe): Prepend your test commands with `xfvb-maybe` and the little tool will automatically configure xfvb, if required by the current system. On Windows or Mac OS X, it will simply do nothing. +First, install [Xvfb](https://en.wikipedia.org/wiki/Xvfb). +It's a virtual framebuffer, implementing the X11 display server protocol - +it performs all graphical operations in memory without showing any screen output, +which is exactly what we need. + +Then, create a virtual xvfb screen and export an environment variable +called DISPLAY that points to it. Chromium in Electron will automatically look +for `$DISPLAY`, so no further configuration of your app is required. +This step can be automated with Paul Betts's +[xfvb-maybe](https://github.com/paulcbetts/xvfb-maybe): Prepend your test +commands with `xfvb-maybe` and the little tool will automatically configure +xfvb, if required by the current system. On Windows or Mac OS X, it will simply +do nothing. ``` ## On Windows or OS X, this just invokes electron-mocha @@ -15,6 +31,7 @@ xvfb-maybe electron-mocha ./test/*.js ``` ### Travis CI + On Travis, your `.travis.yml` should look roughly like this: ``` @@ -29,10 +46,15 @@ install: ``` ### Jenkins + For Jenkins, a [Xfvb plugin is available](https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin). ### Circle CI -Circle CI is awesome and has xvfb and `$DISPLAY` [already setup, so no further configuration is required](https://circleci.com/docs/environment#browsers). + +Circle CI is awesome and has xvfb and `$DISPLAY` +[already setup, so no further configuration is required](https://circleci.com/docs/environment#browsers). ### AppVeyor -AppVeyor runs on Windows, supporting Selenium, Chromium, Electron and similar tools out of the box - no configuration is required. + +AppVeyor runs on Windows, supporting Selenium, Chromium, Electron and similar +tools out of the box - no configuration is required. From 9c7bb0b3700475d7f378d6a91ae0d22ce8bd5f6d Mon Sep 17 00:00:00 2001 From: akameco Date: Tue, 1 Mar 2016 01:41:46 +0900 Subject: [PATCH 326/688] Fix JP docs tranlation --- docs-translations/jp/api/app.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs-translations/jp/api/app.md b/docs-translations/jp/api/app.md index 8d109937358..168f7a09399 100644 --- a/docs-translations/jp/api/app.md +++ b/docs-translations/jp/api/app.md @@ -378,6 +378,7 @@ if (browserOptions.transparent) { // No transparency, so we load a fallback that uses basic styles. win.loadURL('file://' + __dirname + '/fallback.html'); } +``` ### `app.commandLine.appendSwitch(switch[, value])` From eaac67ac603d025664b80ad127f09c4f1ca119d8 Mon Sep 17 00:00:00 2001 From: Daniel Pham Date: Fri, 19 Feb 2016 12:40:41 -0500 Subject: [PATCH 327/688] :apple: Add 'isDarkModeEnabled' to app api --- atom/browser/api/atom_api_app.cc | 1 + atom/browser/browser.h | 3 +++ atom/browser/browser_mac.mm | 5 +++++ docs/api/app.md | 4 ++++ 4 files changed, 13 insertions(+) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index e54d7fee176..53415c4d9c9 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -370,6 +370,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( #if defined(OS_MACOSX) .SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("show", base::Bind(&Browser::Show, browser)) + .SetMethod("isDarkModeEnabled", base::Bind(&Browser::IsDarkModeEnabled, browser)) #endif #if defined(OS_WIN) .SetMethod("setUserTasks", diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 2c44eaa107b..b2e1679b7fc 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -83,6 +83,9 @@ class Browser : public WindowListObserver { // Show the application. void Show(); + // Check if Dark Mode enabled. + bool IsDarkModeEnabled(); + // Bounce the dock icon. enum BounceType { BOUNCE_CRITICAL = 0, diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index bc0be22dcae..affeead255a 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -26,6 +26,11 @@ void Browser::Show() { [[AtomApplication sharedApplication] unhide:nil]; } +bool Browser::IsDarkModeEnabled() { + NSString *mode = CFBridgingRelease(CFPreferencesCopyValue((CFStringRef)@"AppleInterfaceStyle", kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost)); + return [mode isEqualToString: @"Dark"]; +} + void Browser::AddRecentDocument(const base::FilePath& path) { NSString* path_string = base::mac::FilePathToNSString(path); if (!path_string) diff --git a/docs/api/app.md b/docs/api/app.md index bdf0a8a5587..3d0790a9294 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -461,6 +461,10 @@ if (browserOptions.transparent) { } ``` +### `app.isDarkModeEnabled()` _OS X_ + +This method returns `true` if Dark Mode is enabled, and `false` otherwise. + ### `app.commandLine.appendSwitch(switch[, value])` Append a switch (with optional `value`) to Chromium's command line. From c4049cb393cc6266e5d1cc34780621b8dad2ad26 Mon Sep 17 00:00:00 2001 From: Daniel Pham Date: Tue, 1 Mar 2016 15:05:44 -0500 Subject: [PATCH 328/688] :apple: Add 'dark-mode-changed' event to app api --- atom/browser/api/atom_api_app.cc | 9 ++++++++- atom/browser/api/atom_api_app.h | 4 ++++ atom/browser/browser.cc | 4 ++++ atom/browser/browser.h | 2 ++ atom/browser/browser_observer.h | 2 ++ atom/browser/mac/atom_application_delegate.mm | 7 +++++++ docs/api/app.md | 4 ++++ 7 files changed, 31 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 53415c4d9c9..76a5f32a245 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -282,6 +282,12 @@ void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) { Emit("gpu-process-crashed"); } +#if defined(OS_MACOSX) +void App::OnDarkModeChanged() { + Emit("dark-mode-changed"); +} +#endif + base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) { bool succeed = false; base::FilePath path; @@ -370,7 +376,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( #if defined(OS_MACOSX) .SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("show", base::Bind(&Browser::Show, browser)) - .SetMethod("isDarkModeEnabled", base::Bind(&Browser::IsDarkModeEnabled, browser)) + .SetMethod("isDarkModeEnabled", + base::Bind(&Browser::IsDarkModeEnabled, browser)) #endif #if defined(OS_WIN) .SetMethod("setUserTasks", diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index c59b9154df1..54d3f9dc743 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -71,6 +71,10 @@ class App : public AtomBrowserClient::Delegate, // content::GpuDataManagerObserver: void OnGpuProcessCrashed(base::TerminationStatus exit_code) override; +#if defined(OS_MACOSX) + void OnDarkModeChanged() override; +#endif + // mate::Wrappable: mate::ObjectTemplateBuilder GetObjectTemplateBuilder( v8::Isolate* isolate) override; diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 7a2c22ea9d2..7fbe01633b0 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -181,4 +181,8 @@ void Browser::OnWindowAllClosed() { FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWindowAllClosed()); } +void Browser::DarkModeChanged() { + FOR_EACH_OBSERVER(BrowserObserver, observers_, OnDarkModeChanged()); +} + } // namespace atom diff --git a/atom/browser/browser.h b/atom/browser/browser.h index b2e1679b7fc..04b7a725787 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -145,6 +145,8 @@ class Browser : public WindowListObserver { // Request basic auth login. void RequestLogin(LoginHandler* login_handler); + void DarkModeChanged(); + void AddObserver(BrowserObserver* obs) { observers_.AddObserver(obs); } diff --git a/atom/browser/browser_observer.h b/atom/browser/browser_observer.h index f6d76bc13fb..0577712becd 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -45,6 +45,8 @@ class BrowserObserver { // The browser requests HTTP login. virtual void OnLogin(LoginHandler* login_handler) {} + virtual void OnDarkModeChanged() {} + protected: virtual ~BrowserObserver() {} }; diff --git a/atom/browser/mac/atom_application_delegate.mm b/atom/browser/mac/atom_application_delegate.mm index 7662162ab61..0b9c60e7d26 100644 --- a/atom/browser/mac/atom_application_delegate.mm +++ b/atom/browser/mac/atom_application_delegate.mm @@ -24,6 +24,9 @@ // Don't add the "Enter Full Screen" menu item automatically. [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"]; + // Add observer to monitor the system's Dark Mode theme. + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(darkModeChanged:) name:@"AppleInterfaceThemeChangedNotification" object:nil]; + atom::Browser::Get()->WillFinishLaunching(); } @@ -59,4 +62,8 @@ return flag; } +- (void)darkModeChanged:(NSNotification *)notify { + atom::Browser::Get()->DarkModeChanged(); +} + @end diff --git a/docs/api/app.md b/docs/api/app.md index 3d0790a9294..3469c6b108d 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -228,6 +228,10 @@ app.on('login', function(event, webContents, request, authInfo, callback) { Emitted when the gpu process crashes. +### Event: 'dark-mode-changed' _OS X_ + +Emitted when the system's Dark Mode theme is toggled. + ## Methods The `app` object has the following methods: From f02affbc18bf1e02af030b2a0f6cf891fb0d0844 Mon Sep 17 00:00:00 2001 From: Prince J Wesley Date: Thu, 3 Mar 2016 08:37:16 +0530 Subject: [PATCH 329/688] :bug: Add platform predicate for menu item action --- atom/browser/api/lib/menu-item.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/lib/menu-item.js b/atom/browser/api/lib/menu-item.js index d58a0fad2c7..eef8881cf52 100644 --- a/atom/browser/api/lib/menu-item.js +++ b/atom/browser/api/lib/menu-item.js @@ -67,7 +67,7 @@ MenuItem = (function() { } } else if (typeof click === 'function') { return click(_this, focusedWindow); - } else if (typeof _this.selector === 'string') { + } else if (typeof _this.selector === 'string' && process.platform === 'darwin') { return Menu.sendActionToFirstResponder(_this.selector); } }; From b6958e5221590f8a67b20b182ca462af47263691 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Mon, 29 Feb 2016 01:30:43 +0900 Subject: [PATCH 330/688] Update as upstream [ci skip] --- README-ko.md | 5 +- docs-translations/ko-KR/README.md | 1 + docs-translations/ko-KR/api/web-contents.md | 23 +++++--- docs-translations/ko-KR/api/web-view-tag.md | 10 +++- .../ko-KR/tutorial/testing-on-headless-ci.md | 58 +++++++++++++++++++ 5 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 docs-translations/ko-KR/tutorial/testing-on-headless-ci.md diff --git a/README-ko.md b/README-ko.md index b9085828d46..28bb02a1637 100644 --- a/README-ko.md +++ b/README-ko.md @@ -71,8 +71,9 @@ API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝 - Atom 포럼의 [`electron`](http://discuss.atom.io/c/electron) 카테고리 - Freenode 채팅의 `#atom-shell` 채널 - Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널 -- [`electron-br`](https://electron-br.slack.com) *(브라질 포르투갈어)* 커뮤니티 -- [`electron-kr`](http://www.meetup.com/electron-kr/) *(한국어)* 커뮤니티 +- [`electron-br`](https://electron-br.slack.com) *(브라질)* 커뮤니티 +- [`electron-kr`](http://www.meetup.com/electron-kr/) *(한국)* 커뮤니티 +- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(일본)* 커뮤니티 [awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에 커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기 diff --git a/docs-translations/ko-KR/README.md b/docs-translations/ko-KR/README.md index 6f4a1c520f5..8c5912f604b 100644 --- a/docs-translations/ko-KR/README.md +++ b/docs-translations/ko-KR/README.md @@ -30,6 +30,7 @@ Electron에 대해 자주 묻는 질문이 있습니다. 이슈를 생성하기 * [개발자 도구 확장 기능](tutorial/devtools-extension.md) * [Pepper 플래시 플러그인 사용하기](tutorial/using-pepper-flash-plugin.md) * [Widevine CDM 플러그인 사용하기](tutorial/using-widevine-cdm-plugin.md) +* [Headless CI 시스템에서 테스팅하기 (Travis, Jenkins)](tutorial/testing-on-headless-ci.md) ## 튜토리얼 diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 6e41f31155c..ed2f05f1d5a 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -421,10 +421,12 @@ var currentURL = win.webContents.getURL(); CSS 코드를 현재 웹 페이지에 삽입합니다. -### `webContents.executeJavaScript(code[, userGesture])` +### `webContents.executeJavaScript(code[, userGesture, callback])` * `code` String * `userGesture` Boolean (optional) +* `callback` Function (optional) - 스크립트의 실행이 완료되면 호출됩니다. + * `result` 페이지에서 자바스크립트 코드를 실행합니다. @@ -646,14 +648,14 @@ mainWindow.webContents.on('devtools-opened', function() { 개발자 도구가 열려있는지 여부를 반환합니다. -### `webContents.toggleDevTools()` - -개발자 도구를 토글합니다. - ### `webContents.isDevToolsFocused()` 개발자 도구에 포커스 되어있는지 여부를 반환합니다. +### `webContents.toggleDevTools()` + +개발자 도구를 토글합니다. + ### `webContents.inspectElement(x, y)` * `x` Integer @@ -758,9 +760,10 @@ Input `event`를 웹 페이지로 전송합니다. * `keyCode` Char or String (**required**) - 키보드 이벤트로 보내지는 문자. 단일 UTF-8 문자를 사용할 수 있고 이벤트를 발생시키는 다음 키 중 하나를 포함할 수 있습니다: - `enter`, `backspace`, `delete`, `tab`, `escape`, `control`, `alt`, `shift`, - `end`, `home`, `insert`, `left`, `up`, `right`, `down`, `pageUp`, `pageDown`, - `printScreen` + `enter`, `backspace`, `delete`, `tab`, `escape`, `control`, `alt`, `altgr` + (Windows 전용), `shift`, `end`, `home`, `insert`, `left`, `up`, `right`, + `down`, `pageUp`, `pageDown`, `printScreen`, `meta`, `cmd` (OSX 전용), + `command` (OSX 전용), `option` (OSX 전용) 마우스 이벤트들에 대해서는 `event` 객체는 다음 속성들을 사용할 수 있습니다: @@ -832,6 +835,10 @@ win.webContents.on('did-finish-load', function() { 이 webContents에서 사용하는 [session](session.md) 객체를 반환합니다. +### `webContents.hostWebContents` + +현재 `WebContents`를 소유하는 `WebContents`를 반환합니다. + ### `webContents.devToolsWebContents` 이 `WebContents`에 대한 개발자 도구의 `WebContents`를 가져옵니다. diff --git a/docs-translations/ko-KR/api/web-view-tag.md b/docs-translations/ko-KR/api/web-view-tag.md index 30da9f253b4..bda18b78898 100644 --- a/docs-translations/ko-KR/api/web-view-tag.md +++ b/docs-translations/ko-KR/api/web-view-tag.md @@ -272,12 +272,14 @@ Webview에 웹 페이지 `url`을 로드합니다. `url`은 `http://`, `file://` 페이지에 CSS를 삽입합니다. -### `.executeJavaScript(code[, userGesture])` +### `.executeJavaScript(code[, userGesture, callback])` * `code` String * `userGesture` Boolean +* `callback` Function (optional) - 스크립트의 실행이 완료되면 호출됩니다. + * `result` -페이지에서 자바스크립트 `code`를 실행합니다. +페이지에서 자바스크립트 코드를 실행합니다. 만약 `userGesture`가 `true`로 설정되어 있으면 페이지에 유저 제스쳐 컨텍스트를 만듭니다. 이 옵션을 활성화 시키면 `requestFullScreen`와 같은 HTML API에서 유저의 승인을 @@ -427,6 +429,10 @@ Webview 페이지를 PDF 형식으로 인쇄합니다. `event` 객체에 대해 자세히 알아보려면 [webContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent)를 참고하세요. +### `.getWebContents()` + +이 `webview`에 해당하는 [WebContents](web-contents.md)를 반환합니다. + ## DOM 이벤트 `webview` 태그는 다음과 같은 DOM 이벤트를 가지고 있습니다: diff --git a/docs-translations/ko-KR/tutorial/testing-on-headless-ci.md b/docs-translations/ko-KR/tutorial/testing-on-headless-ci.md new file mode 100644 index 00000000000..be88be1cec6 --- /dev/null +++ b/docs-translations/ko-KR/tutorial/testing-on-headless-ci.md @@ -0,0 +1,58 @@ +# Headless CI 시스템에서 테스팅하기 (Travis, Jenkins) (Travis CI, Jenkins) + +Chromium을 기반으로 한 Electron은 작업을 위해 디스플레이 드라이버가 필요합니다. +만약 Chromium이 디스플레이 드라이버를 찾기 못한다면, Electron은 그대로 실행에 +실패할 것입니다. 따라서 실행하는 방법에 관계없이 모든 테스트를 실행하지 못하게 됩니다. +Electron 기반 어플리케이션을 Travis, Circle, Jenkins 또는 유사한 시스템에서 테스팅을 +진행하려면 약간의 설정이 필요합니다. 요점만 말하자면, 가상 디스플레이 드라이버가 +필요합니다. + +## 가상 디스플레이 드라이버 설정 + +먼저, [Xvfb](https://en.wikipedia.org/wiki/Xvfb)를 설치합니다. 이것은 X11 +디스플레이 서버 프로토콜의 구현이며 모든 그래픽 작업을 스크린 출력없이 인-메모리에서 +수행하는 가상 프레임버퍼입니다. 정확히 우리가 필요로 하는 것입니다. + +그리고, 가상 xvfb 스크린을 생성하고 DISPLAY라고 불리우는 환경 변수를 지정합니다. +Electron의 Chromium은 자동적으로 `$DISPLAY` 변수를 찾습니다. 따라서 앱의 추가적인 +다른 설정이 필요하지 않습니다. 이러한 작업은 Paul Betts의 +[xfvb-maybe](https://github.com/paulcbetts/xvfb-maybe)를 통해 자동화 할 수 +있습니다: `xfvb-maybe`를 테스트 커맨드 앞에 추가하고 현재 시스템에서 요구하면 +이 작은 툴이 자동적으로 xfvb를 설정합니다. Windows와 Mac OS X에선 간단히 아무 작업도 +하지 않습니다. + +``` +## Windows와 OS X에선, 그저 electron-mocha를 호출합니다 +## Linux에선, 현재 headless 환경에 있는 경우 +## xvfb-run electron-mocha ./test/*.js와 같습니다 +xvfb-maybe electron-mocha ./test/*.js +``` + +### Travis CI + +Travis에선, `.travis.yml`이 대충 다음과 같이 되어야 합니다: + +``` +addons: + apt: + packages: + - xvfb + +install: + - export DISPLAY=':99.0' + - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & +``` + +### Jenkins + +Jenkins는 [Xfvb 플러그인이 존재합니다](https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin). + +### Circle CI + +Circle CI는 멋지게도 이미 xvfb와 `$DISPLY` 변수가 준비되어 있습니다. 따라서 +[추가적인 설정이 필요하지](https://circleci.com/docs/environment#browsers) 않습니다. + +### AppVeyor + +AppVeyor는 Windows에서 작동하기 때문에 Selenium, Chromium, Electron과 그 비슷한 +툴들을 복잡한 과정 없이 모두 지원합니다. - 설정이 필요하지 않습니다. From b46fc8bc4c16f9defdc06e8f9b724f2f91ee605b Mon Sep 17 00:00:00 2001 From: Victor Zhu Date: Thu, 3 Mar 2016 15:42:14 -0500 Subject: [PATCH 331/688] Add Pepper Flash doc and match doc style - Add Pepper Flash plugin documentation - Use and match the same documentaion style for other CN docs. - Fix some typos and grammar. --- .../tutorial/application-distribution.md | 5 +- .../zh-CN/tutorial/application-packaging.md | 84 +++++++++++-------- .../zh-CN/tutorial/debugging-main-process.md | 4 +- .../zh-CN/tutorial/devtools-extension.md | 22 ++--- .../zh-CN/tutorial/supported-platforms.md | 2 +- .../tutorial/using-native-node-modules.md | 27 +++--- .../tutorial/using-pepper-flash-plugin.md | 48 +++++++++++ .../tutorial/using-selenium-and-webdriver.md | 40 ++++----- 8 files changed, 149 insertions(+), 83 deletions(-) create mode 100644 docs-translations/zh-CN/tutorial/using-pepper-flash-plugin.md diff --git a/docs-translations/zh-CN/tutorial/application-distribution.md b/docs-translations/zh-CN/tutorial/application-distribution.md index dcfe4d240ee..f3cf3692b5d 100644 --- a/docs-translations/zh-CN/tutorial/application-distribution.md +++ b/docs-translations/zh-CN/tutorial/application-distribution.md @@ -1,6 +1,7 @@ # 应用部署 -为了使用Electron部署你的应用程序,你存放应用程序的文件夹需要叫做 `app` 并且需要放在 Electron 的资源文件夹下(在 OS X 中是指 `Electron.app/Contents/Resources/`,在 Linux 和 Windows 中是指 `resources/`) +为了使用 Electron 部署你的应用程序,你存放应用程序的文件夹需要叫做 `app` 并且需要放在 Electron 的 +资源文件夹下(在 OS X 中是指 `Electron.app/Contents/Resources/`,在 Linux 和 Windows 中是指 `resources/`) 就像这样: 在 OS X 中: @@ -56,7 +57,7 @@ electron/resources/ 你可以将 `electron.exe` 改成任意你喜欢的名字,然后可以使用像 [rcedit](https://github.com/atom/rcedit) -编辑它的icon和其他信息。 +编辑它的 icon 和其他信息。 ### OS X diff --git a/docs-translations/zh-CN/tutorial/application-packaging.md b/docs-translations/zh-CN/tutorial/application-packaging.md index ee4b7bf63b8..13a24d2d1c3 100644 --- a/docs-translations/zh-CN/tutorial/application-packaging.md +++ b/docs-translations/zh-CN/tutorial/application-packaging.md @@ -1,34 +1,38 @@ # 应用打包 -为舒缓Windows下路径名过长的问题[issues](https://github.com/joyent/node/issues/6960), 也略对`require`加速以及简单隐匿你的源代码, 你可以通过极小的源代码改动将你的应用打包成[asar][asar]. +为舒缓 Windows 下路径名过长的问题[issues](https://github.com/joyent/node/issues/6960), +也略对 `require` 加速以及简单隐匿你的源代码,你可以通过极小的源代码改动将你的应用打包成 [asar][asar]。 -## 生成`asar`包 +## 生成 `asar` 包 -[asar][asar]是一种将多个文件合并成一个文件的类tar风格的归档格式。 Electron可以无需解压,即从其中读取任意文件内容。 +[asar][asar] 是一种将多个文件合并成一个文件的类 tar 风格的归档格式。 +Electron 可以无需解压,即从其中读取任意文件内容。 -参照如下步骤将你的应用打包成`asar`: +参照如下步骤将你的应用打包成 `asar`: -### 1. 安装asar +### 1. 安装 asar ```bash $ npm install -g asar ``` -### 2. 用`asar pack`打包 +### 2. 用 `asar pack` 打包 ```bash $ asar pack your-app app.asar ``` -## 使用`asar`包 +## 使用 `asar` 包 -在Electron中有两类APIs:Node.js提供的Node APIs和Chromium提供的Web APIs。这两种APIs都支持从`asar`包中读取文件。 +在 Electron 中有两类 APIs:Node.js 提供的 Node API 和 Chromium 提供的 Web API。 +这两种 API 都支持从 `asar` 包中读取文件。 ### Node API -由于Electron中打了特别补丁, Node APIs中如`fs.readFile`或者`require`之类的方法可以将`asar`视之为虚拟文件夹,读取`asar`里面的文件就和从真实的文件系统中读取一样。 +由于 Electron 中打了特别补丁, Node API 中如 `fs.readFile` 或者 `require` 之类 +的方法可以将 `asar` 视之为虚拟文件夹,读取 `asar` 里面的文件就和从真实的文件系统中读取一样。 -例如,假设我们在`/path/to`文件夹下有个`example.asar`包: +例如,假设我们在 `/path/to` 文件夹下有个 `example.asar` 包: ```bash $ asar list /path/to/example.asar @@ -40,27 +44,27 @@ $ asar list /path/to/example.asar /static/jquery.min.js ``` -从`asar`包读取一个文件: +从 `asar` 包读取一个文件: ```javascript const fs = require('fs'); fs.readFileSync('/path/to/example.asar/file.txt'); ``` -列出`asar`包中根目录下的所有文件: +列出 `asar` 包中根目录下的所有文件: ```javascript const fs = require('fs'); fs.readdirSync('/path/to/example.asar'); ``` -使用`asar`包中的一个模块: +使用 `asar` 包中的一个模块: ```javascript require('/path/to/example.asar/dir/module.js'); ``` -你也可以使用`BrowserWindow`来显示一个`asar`包里的web页面: +你也可以使用 `BrowserWindow` 来显示一个 `asar` 包里的 web 页面: ```javascript const BrowserWindow = require('electron').BrowserWindow; @@ -70,9 +74,9 @@ win.loadURL('file:///path/to/example.asar/static/index.html'); ### Web API -在Web页面里,用`file:`协议可以获取`asar`包中文件。和Node API一样,视`asar`包如虚拟文件夹。 +在 Web 页面里,用 `file:` 协议可以获取 `asar` 包中文件。和 Node API 一样,视 `asar` 包如虚拟文件夹。 -例如,用`$.get`获取文件: +例如,用 `$.get` 获取文件: ```html ``` -### 像“文件”那样处理`asar`包 +### 像“文件”那样处理 `asar` 包 -有些场景,如:核查`asar`包的校验和,我们需要像读取“文件”那样读取`asar`包的内容(而不是当成虚拟文件夹)。你可以使用内置的`original-fs`(提供和`fs`一样的APIs)模块来读取`asar`包的真实信息。 +有些场景,如:核查 `asar` 包的校验和,我们需要像读取“文件”那样读取 `asar` 包的内容(而不是当成虚拟文件夹)。 +你可以使用内置的 `original-fs` (提供和 `fs` 一样的 API)模块来读取 `asar` 包的真实信息。 ```javascript var originalFs = require('original-fs'); originalFs.readFileSync('/path/to/example.asar'); ``` -## Node API缺陷 +## Node API 缺陷 -尽管我们已经尽了最大努力使得`asar`包在Node API下的应用尽可能的趋向于真实的目录结构,但仍有一些底层Node API我们无法保证其正常工作。 +尽管我们已经尽了最大努力使得 `asar` 包在 Node API 下的应用尽可能的趋向于真实的目录结构,但仍有一些底层 Node API 我们无法保证其正常工作。 -### `asar`包是只读的 +### `asar` 包是只读的 -`asar`包中的内容不可更改,所以Node APIs里那些可以用来修改文件的方法在对待`asar`包时都无法正常工作。 +`asar` 包中的内容不可更改,所以 Node APIs 里那些可以用来修改文件的方法在对待 `asar` 包时都无法正常工作。 -### Working Directory在`asar`包中无效 +### Working Directory 在 `asar` 包中无效 -尽管`asar`包是虚拟文件夹,但其实并没有真实的目录架构对应在文件系统里,所以你不可能将working Directory设置成`asar`包里的一个文件夹。将`asar`中的文件夹以`cwd`形式作为参数传入一些API中也会报错。 +尽管 `asar` 包是虚拟文件夹,但其实并没有真实的目录架构对应在文件系统里,所以你不可能将 working Directory +设置成 `asar` 包里的一个文件夹。将 `asar` 中的文件夹以 `cwd` 形式作为参数传入一些 API 中也会报错。 -### API中的额外“开箱” +### API 中的额外“开箱” -大部分`fs`API可以无需解压即从`asar`包中读取文件或者文件的信息,但是在处理一些依赖真实文件路径的底层系统方法时,Electron会将所需文件解压到临时目录下,然后将临时目录下的真实文件路径传给底层系统方法使其正常工作。 对于这类API,耗费会略多一些。 +大部分 `fs` API 可以无需解压即从 `asar` 包中读取文件或者文件的信息,但是在处理一些依赖真实文件路径的底层 +系统方法时,Electron 会将所需文件解压到临时目录下,然后将临时目录下的真实文件路径传给底层系统方法使其正 +常工作。 对于这类API,耗费会略多一些。 -以下是一些需要额外解压的APIs: +以下是一些需要额外解压的 API: * `child_process.execFile` * `child_process.execFileSync` @@ -116,26 +124,32 @@ originalFs.readFileSync('/path/to/example.asar'); * `fs.openSync` * `process.dlopen` - `require`native模块时用到 -### `fs.stat`获取的stat信息不可靠 +### `fs.stat` 获取的 stat 信息不可靠 -对`asar`包中的文件取`fs.stat`,返回的`Stats`对象不是精确值,因为这些文件不是真实存在于文件系统里。所以除了文件大小和文件类型以外,你不应该依赖`Stats`对象的值。 +对 `asar` 包中的文件取 `fs.stat`,返回的 `Stats` 对象不是精确值,因为这些文件不是真实存在于文件系 +统里。所以除了文件大小和文件类型以外,你不应该依赖 `Stats` 对象的值。 -### 执行`asar`包中的程序 +### 执行 `asar` 包中的程序 -Node中有一些可以执行程序的API,如`child_process.exec`,`child_process.spawn`和`child_process.execFile`等,但只有`execFile`可以执行`asar`包中的程序。 +Node 中有一些可以执行程序的 API,如 `child_process.exec`,`child_process.spawn` 和 `child_process.execFile` 等, +但只有 `execFile` 可以执行 `asar` 包中的程序。 -因为`exec`和`spawn`允许`command`替代`file`作为输入,而`command`是需要在shell下执行的,目前没有可靠的方法来判断`command`中是否在操作一个`asar`包中的文件,而且即便可以判断,我们依旧无法保证可以在无任何副作用的情况下替换`command`中的文件路径。 +因为 `exec` 和 `spawn` 允许 `command` 替代 `file` 作为输入,而 `command` 是需要在 shell 下执行的,目前没有 +可靠的方法来判断 `command` 中是否在操作一个 `asar` 包中的文件,而且即便可以判断,我们依旧无法保证可以在无任何 +副作用的情况下替换 `command` 中的文件路径。 ## 打包时排除文件 -如上所述,一些Node API会在调用时将文件解压到文件系统中,除了效率问题外,也有可能引起杀毒软件的注意! +如上所述,一些 Node API 会在调用时将文件解压到文件系统中,除了效率问题外,也有可能引起杀毒软件的注意! -为解决这个问题,你可以在生成`asar`包时使用`--unpack`选项来排除一些文件,使其不打包到`asar`包中,下面是如何排除一些用作共享用途的native模块的方法: +为解决这个问题,你可以在生成 `asar` 包时使用 `--unpack` 选项来排除一些文件,使其不打包到 `asar` 包中, +下面是如何排除一些用作共享用途的 native 模块的方法: ```bash $ asar pack app app.asar --unpack *.node ``` -经过上述命令后,除了生成的`app.asar`包以外,还有一个包含了排除文件的`app.asar.unpacked`文件夹,你需要将这个文件夹一起拷贝,提供给用户。 +经过上述命令后,除了生成的 `app.asar` 包以外,还有一个包含了排除文件的 `app.asar.unpacked` 文件夹, +你需要将这个文件夹一起拷贝,提供给用户。 [asar]: https://github.com/atom/asar diff --git a/docs-translations/zh-CN/tutorial/debugging-main-process.md b/docs-translations/zh-CN/tutorial/debugging-main-process.md index f971a40892f..e3eec0c5b39 100644 --- a/docs-translations/zh-CN/tutorial/debugging-main-process.md +++ b/docs-translations/zh-CN/tutorial/debugging-main-process.md @@ -1,6 +1,6 @@ # 主进程调试 -浏览器窗口的开发工具仅能调试渲染器的进程脚本(比如web 页面)。为了提供一个可以调试主进程 +浏览器窗口的开发工具仅能调试渲染器的进程脚本(比如 web 页面)。为了提供一个可以调试主进程 的方法,Electron 提供了 `--debug` 和 `--debug-brk` 开关。 ## 命令行开关 @@ -18,7 +18,7 @@ ## 使用 node-inspector 来调试 -__备注:__ Electron 目前对 node-inspector支持的不是特别好, +__备注:__ Electron 目前对 node-inspector 支持的不是特别好, 如果你通过 node-inspector 的 console 来检查 `process` 对象,主进程就会崩溃。 ### 1. 确认你已经安装了 [node-gyp 所需工具](https://github.com/nodejs/node-gyp#installation) diff --git a/docs-translations/zh-CN/tutorial/devtools-extension.md b/docs-translations/zh-CN/tutorial/devtools-extension.md index 9a2d9fc8832..0270eae2955 100644 --- a/docs-translations/zh-CN/tutorial/devtools-extension.md +++ b/docs-translations/zh-CN/tutorial/devtools-extension.md @@ -1,10 +1,10 @@ # DevTools扩展 -为了使调试更容易,Electron原生支持[Chrome DevTools Extension][devtools-extension]。 +为了使调试更容易,Electron 原生支持 [Chrome DevTools Extension][devtools-extension]。 -对于大多数DevTools的扩展,你可以直接下载源码,然后通过`BrowserWindow.addDevToolsExtension`API加载它们。Electron会记住已经加载了哪些扩展,所以你不需要每次创建一个新window时都调用`BrowserWindow.addDevToolsExtension`API。 +对于大多数DevTools的扩展,你可以直接下载源码,然后通过 `BrowserWindow.addDevToolsExtension` API 加载它们。Electron会记住已经加载了哪些扩展,所以你不需要每次创建一个新window时都调用 `BrowserWindow.addDevToolsExtension` API。 -** 注:React DevTools目前不能直接工作,详情留意[https://github.com/atom/electron/issues/915](https://github.com/atom/electron/issues/915) ** +** 注:React DevTools目前不能直接工作,详情留意 [https://github.com/atom/electron/issues/915](https://github.com/atom/electron/issues/915) ** 例如,要用[React DevTools Extension](https://github.com/facebook/react-devtools),你得先下载他的源码: @@ -13,33 +13,33 @@ $ cd /some-directory $ git clone --recursive https://github.com/facebook/react-devtools.git ``` -参考[`react-devtools/shells/chrome/Readme.md`](https://github.com/facebook/react-devtools/blob/master/shells/chrome/Readme.md)来编译这个扩展源码。 +参考 [`react-devtools/shells/chrome/Readme.md`](https://github.com/facebook/react-devtools/blob/master/shells/chrome/Readme.md) 来编译这个扩展源码。 -然后你就可以在任意页面的DevTools里加载React DevTools了,通过控制台输入如下命令加载扩展: +然后你就可以在任意页面的 DevTools 里加载 React DevTools 了,通过控制台输入如下命令加载扩展: ```javascript const BrowserWindow = require('electron').remote.BrowserWindow; BrowserWindow.addDevToolsExtension('/some-directory/react-devtools/shells/chrome'); ``` -要卸载扩展,可以调用`BrowserWindow.removeDevToolsExtension`API(扩展名作为参数传入),该扩展在下次打开DevTools时就不会加载了: +要卸载扩展,可以调用 `BrowserWindow.removeDevToolsExtension` API (扩展名作为参数传入),该扩展在下次打开DevTools时就不会加载了: ```javascript BrowserWindow.removeDevToolsExtension('React Developer Tools'); ``` -## DevTools扩展的格式 +## DevTools 扩展的格式 -理论上,Electron可以加载所有为chrome浏览器编写的DevTools扩展,但它们必须存放在文件夹里。那些以`crx`形式发布的扩展是不能被加载的,除非你把它们解压到一个文件夹里。 +理论上,Electron 可以加载所有为 chrome 浏览器编写的 DevTools 扩展,但它们必须存放在文件夹里。那些以 `crx` 形式发布的扩展是不能被加载的,除非你把它们解压到一个文件夹里。 ## 后台运行(background pages) -Electron目前并不支持chrome扩展里的后台运行(background pages)功能,所以那些依赖此特性的DevTools扩展在Electron里可能无法正常工作。 +Electron 目前并不支持 chrome 扩展里的后台运行(background pages)功能,所以那些依赖此特性的 DevTools 扩展在 Electron 里可能无法正常工作。 ## `chrome.*` APIs -有些chrome扩展使用了`chrome.*`APIs,而且这些扩展在Electron中需要额外实现一些代码才能使用,所以并不是所有的这类扩展都已经在Electron中实现完毕了。 +有些 chrome 扩展使用了 `chrome.*`APIs,而且这些扩展在 Electron 中需要额外实现一些代码才能使用,所以并不是所有的这类扩展都已经在 Electron 中实现完毕了。 -考虑到并非所有的`chrome.*`APIs都实现完毕,如果DevTools正在使用除了`chrome.devtools.*`之外的其它APIs,这个扩展很可能无法正常工作。你可以通过报告这个扩展的异常信息,这样做方便我们对该扩展的支持。 +考虑到并非所有的 `chrome.*`APIs 都实现完毕,如果 DevTools 正在使用除了 `chrome.devtools.*` 之外的其它 APIs,这个扩展很可能无法正常工作。你可以通过报告这个扩展的异常信息,这样做方便我们对该扩展的支持。 [devtools-extension]: https://developer.chrome.com/extensions/devtools diff --git a/docs-translations/zh-CN/tutorial/supported-platforms.md b/docs-translations/zh-CN/tutorial/supported-platforms.md index d4d42ec03ff..e03ccd82364 100644 --- a/docs-translations/zh-CN/tutorial/supported-platforms.md +++ b/docs-translations/zh-CN/tutorial/supported-platforms.md @@ -20,7 +20,7 @@ Ubuntu 12.04 下编译的,`arm` 版的二进制文件是在 ARM v7(硬浮点 Debian Wheezy 版本的 NEON)下完成的。 预编译二进制文件是否能够运行,取决于其中是否包括了编译平台链接的库,所以只有 Ubuntu 12.04 -可以保证正常工作,但是以下的平台也被证实可以运行 Electron的预编译版本: +可以保证正常工作,但是以下的平台也被证实可以运行 Electron 的预编译版本: * Ubuntu 12.04 及更新 * Fedora 21 diff --git a/docs-translations/zh-CN/tutorial/using-native-node-modules.md b/docs-translations/zh-CN/tutorial/using-native-node-modules.md index e03e7b8948a..0fe67d4a08a 100644 --- a/docs-translations/zh-CN/tutorial/using-native-node-modules.md +++ b/docs-translations/zh-CN/tutorial/using-native-node-modules.md @@ -1,12 +1,12 @@ # 使用原生模块 -Electron同样也支持原生模块,但由于和官方的Node相比使用了不同的V8引擎,如果你想编译原生模块,则需要手动设置Electron的headers的位置。 +Electron 同样也支持原生模块,但由于和官方的 Node 相比使用了不同的 V8 引擎,如果你想编译原生模块,则需要手动设置 Electron 的 headers 的位置。 ## 原生Node模块的兼容性 -当Node开始换新的V8引擎版本时,原生模块可能“坏”掉。为确保一切工作正常,你需要检查你想要使用的原生模块是否被Electron内置的Node支持。你可以在[这里](https://github.com/atom/electron/releases)查看Electron内置的Node版本,或者使用`process.version`(参考:[快速入门](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md))查看。 +当 Node 开始换新的V8引擎版本时,原生模块可能“坏”掉。为确保一切工作正常,你需要检查你想要使用的原生模块是否被 Electron 内置的 Node 支持。你可以在[这里](https://github.com/atom/electron/releases)查看 Electron 内置的 Node 版本,或者使用 `process.version` (参考:[快速入门](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md))查看。 -考虑到[NAN](https://github.com/nodejs/nan/)可以使你的开发更容易对多版本Node的支持,建议使用它来开发你自己的模块。你也可以使用[NAN](https://github.com/nodejs/nan/)来移植旧的模块到新的Node版本,以使它们可以在新的Electron下良好工作。 +考虑到 [NAN](https://github.com/nodejs/nan/) 可以使你的开发更容易对多版本 Node 的支持,建议使用它来开发你自己的模块。你也可以使用 [NAN](https://github.com/nodejs/nan/) 来移植旧的模块到新的 Nod e版本,以使它们可以在新的 Electron 下良好工作。 ## 如何安装原生模块 @@ -14,7 +14,7 @@ Electron同样也支持原生模块,但由于和官方的Node相比使用了 ### 最简单方式 -最简单的方式就是通过[`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild)包重新编译原生模块,它帮你自动完成了下载headers、编译原生模块等步骤: +最简单的方式就是通过 [`electron-rebuild`](https://github.com/paulcbetts/electron-rebuild) 包重新编译原生模块,它帮你自动完成了下载 headers、编译原生模块等步骤: ```sh npm install --save-dev electron-rebuild @@ -26,9 +26,9 @@ npm install --save-dev electron-rebuild .\node_modules\.bin\electron-rebuild.cmd ``` -### 通过npm安装 +### 通过 npm 安装 -你当然也可以通过`npm`安装原生模块。大部分步骤和安装普通模块时一样,除了以下一些系统环境变量你需要自己操作: +你当然也可以通过 `npm` 安装原生模块。大部分步骤和安装普通模块时一样,除了以下一些系统环境变量你需要自己操作: ```bash export npm_config_disturl=https://atom.io/download/atom-shell @@ -38,16 +38,19 @@ export npm_config_runtime=electron HOME=~/.electron-gyp npm install module-name ``` -### 通过node-gyp安装 +### 通过 node-gyp 安装 -你需要告诉`node-gyp`去哪下载Electron的headers,以及下载什么版本: +你需要告诉 `node-gyp` 去哪下载 Electron 的 headers,以及下载什么版本: ```bash $ cd /path-to-module/ $ HOME=~/.electron-gyp node-gyp rebuild --target=0.29.1 --arch=x64 --dist-url=https://atom.io/download/atom-shell ``` -`HOME=~/.electron-gyp`设置了去哪找开发时的headers。 -`--target=0.29.1`设置了Electron的版本 -`--dist-url=...`设置了Electron的headers的下载地址 -`--arch=x64`设置了该模块为适配64bit操作系统而编译 +`HOME=~/.electron-gyp` 设置去哪找开发时的 headers。 + +`--target=0.29.1` 设置了 Electron 的版本 + +`--dist-url=...` 设置了 Electron 的 headers 的下载地址 + +`--arch=x64` 设置了该模块为适配64位操作系统而编译 diff --git a/docs-translations/zh-CN/tutorial/using-pepper-flash-plugin.md b/docs-translations/zh-CN/tutorial/using-pepper-flash-plugin.md new file mode 100644 index 00000000000..ce1f210c5c9 --- /dev/null +++ b/docs-translations/zh-CN/tutorial/using-pepper-flash-plugin.md @@ -0,0 +1,48 @@ +# 使用 Pepper Flash 插件 + +Electron 现在支持 Pepper Flash 插件。要在 Electron 里面使用 Pepper Flash 插件,你需 +要手动设置 Pepper Flash 的路径和在你的应用里启用 Pepper Flash。 + +## 保留一份 Flash 插件的副本 + +在 OS X 和 Linux 上,你可以在 Chrome 浏览器的 `chrome://plugins` 页面上找到 Pepper +Flash 的插件信息。插件的路径和版本会对 Election 对其的支持有帮助。你也可以把插件 +复制到另一个路径以保留一份副本。 + +## 添加插件在 Electron 里的开关 + +你可以直接在命令行中用 `--ppapi-flash-path` 和 `ppapi-flash-version` 或者 +在 app 的准备事件前调用 `app.commandLine.appendSwitch` 这个 method。同时, +添加 `browser-window` 的插件开关。 +例如: + +```javascript +// Specify flash path. 设置 flash 路径 +// On Windows, it might be /path/to/pepflashplayer.dll +// On OS X, /path/to/PepperFlashPlayer.plugin +// On Linux, /path/to/libpepflashplayer.so +app.commandLine.appendSwitch('ppapi-flash-path', '/path/to/libpepflashplayer.so'); + +// Specify flash version, for example, v17.0.0.169 设置版本号 +app.commandLine.appendSwitch('ppapi-flash-version', '17.0.0.169'); + +app.on('ready', function() { + mainWindow = new BrowserWindow({ + 'width': 800, + 'height': 600, + 'web-preferences': { + 'plugins': true + } + }); + mainWindow.loadURL('file://' + __dirname + '/index.html'); + // Something else +}); +``` + +## 使用 `` 标签启用插件 + +在 `` 标签里添加 `plugins` 属性。 + +```html + +``` diff --git a/docs-translations/zh-CN/tutorial/using-selenium-and-webdriver.md b/docs-translations/zh-CN/tutorial/using-selenium-and-webdriver.md index c05a3190eea..0a0b29c854f 100644 --- a/docs-translations/zh-CN/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/zh-CN/tutorial/using-selenium-and-webdriver.md @@ -1,18 +1,18 @@ -# 使用Selenium和WebDriver +# 使用 Selenium 和 WebDriver 引自[ChromeDriver - WebDriver for Chrome][chrome-driver]: -> WebDriver是一款开源的支持多浏览器的自动化测试工具。它提供了操作网页、用户输入、JavaScript执行等能力。ChromeDriver是一个实现了WebDriver与Chromium联接协议的独立服务。它也是由开发了Chromium和WebDriver的团队开发的。 +> WebDriver 是一款开源的支持多浏览器的自动化测试工具。它提供了操作网页、用户输入、JavaScript 执行等能力。ChromeDriver 是一个实现了 WebDriver 与 Chromium 联接协议的独立服务。它也是由开发了 Chromium 和 WebDriver 的团队开发的。 -为了能够使`chromedriver`和Electron一起正常工作,我们需要告诉它Electron在哪,并且让它相信Electron就是Chrome浏览器。 +为了能够使 `chromedriver` 和 Electron 一起正常工作,我们需要告诉它 Electron 在哪,并且让它相信 Electron 就是 Chrome 浏览器。 -## 通过WebDriverJs配置 +## 通过 WebDriverJs 配置 -[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) 是一个可以配合WebDriver做测试的node模块,我们会用它来做个演示。 +[WebDriverJs](https://code.google.com/p/selenium/wiki/WebDriverJs) 是一个可以配合 WebDriver 做测试的 node 模块,我们会用它来做个演示。 -### 1. 启动ChromeDriver +### 1. 启动 ChromeDriver -首先,你要下载`chromedriver`,然后运行以下命令: +首先,你要下载 `chromedriver`,然后运行以下命令: ```bash $ ./chromedriver @@ -20,17 +20,17 @@ Starting ChromeDriver (v2.10.291558) on port 9515 Only local connections are allowed. ``` -记住`9515`这个端口号,我们后面会用到 +记住 `9515` 这个端口号,我们后面会用到 -### 2. 安装WebDriverJS +### 2. 安装 WebDriverJS ```bash $ npm install selenium-webdriver ``` -### 3. 联接到ChromeDriver +### 3. 联接到 ChromeDriver -在Electron下使用`selenium-webdriver`和其平时的用法并没有大的差异,只是你需要手动设置连接ChromeDriver,以及Electron的路径: +在 Electron 下使用 `selenium-webdriver` 和其平时的用法并没有大的差异,只是你需要手动设置连接 ChromeDriver,以及 Electron 的路径: ```javascript const webdriver = require('selenium-webdriver'); @@ -59,13 +59,13 @@ driver.wait(function() { driver.quit(); ``` -## 通过WebdriverIO配置 +## 通过 WebdriverIO 配置 -[WebdriverIO](http://webdriver.io/)也是一个配合WebDriver用来测试的node模块 +[WebdriverIO](http://webdriver.io/) 也是一个配合 WebDriver 用来测试的 node 模块 -### 1. 启动ChromeDriver +### 1. 启动 ChromeDriver -首先,下载`chromedriver`,然后运行以下命令: +首先,下载 `chromedriver`,然后运行以下命令: ```bash $ chromedriver --url-base=wd/hub --port=9515 @@ -73,15 +73,15 @@ Starting ChromeDriver (v2.10.291558) on port 9515 Only local connections are allowed. ``` -记住`9515`端口,后面会用到 +记住 `9515` 端口,后面会用到 -### 2. 安装WebdriverIO +### 2. 安装 WebdriverIO ```bash $ npm install webdriverio ``` -### 3. 连接到ChromeDriver +### 3. 连接到 ChromeDriver ```javascript const webdriverio = require('webdriverio'); @@ -112,8 +112,8 @@ client ## 工作流程 -无需重新编译Electron,只要把app的源码放到[Electron的资源目录](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md)里就可直接开始测试了。 +无需重新编译 Electron,只要把 app 的源码放到 [Electron的资源目录](https://github.com/atom/electron/blob/master/docs/tutorial/application-distribution.md) 里就可直接开始测试了。 -当然,你也可以在运行Electron时传入参数指定你app的所在文件夹。这步可以免去你拷贝-粘贴你的app到Electron的资源目录。 +当然,你也可以在运行 Electron 时传入参数指定你 app 的所在文件夹。这步可以免去你拷贝-粘贴你的 app 到 Electron 的资源目录。 [chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/ From fed77d1837b031a666d0d229e26a26f7889d1ad8 Mon Sep 17 00:00:00 2001 From: christoth Date: Thu, 3 Mar 2016 17:22:20 -0500 Subject: [PATCH 332/688] Use flexbox layout for browserplugin --- atom/renderer/lib/web-view/web-view.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index bd128f6fffe..5b135e0427a 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -33,6 +33,7 @@ var WebViewImpl = (function() { this.on = {}; this.browserPluginNode = this.createBrowserPluginNode(); shadowRoot = this.webviewNode.createShadowRoot(); + shadowRoot.innerHTML = ''; this.setupWebViewAttributes(); this.setupFocusPropagation(); this.viewInstanceId = getNextId(); @@ -279,9 +280,7 @@ var registerBrowserPluginElement = function() { this.setAttribute('id', 'browser-plugin-' + getNextId()); // The node fills in the container. - this.style.display = 'block'; - this.style.width = '100%'; - return this.style.height = '100%'; + return this.style.flex = '1 1 auto'; }; proto.attributeChangedCallback = function(name, oldValue, newValue) { var internal; From b1eefbdcd93779c932be8b2a0cac7e342997bf79 Mon Sep 17 00:00:00 2001 From: Daniel Pham Date: Thu, 3 Mar 2016 23:48:30 -0500 Subject: [PATCH 333/688] Simplify the isDarkModeEnabled check --- atom/browser/browser_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index affeead255a..f5859df97aa 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -27,7 +27,7 @@ void Browser::Show() { } bool Browser::IsDarkModeEnabled() { - NSString *mode = CFBridgingRelease(CFPreferencesCopyValue((CFStringRef)@"AppleInterfaceStyle", kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost)); + NSString *mode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; return [mode isEqualToString: @"Dark"]; } From be67dca686474fc57ff92c341fe5fe3a9dc55a5e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 3 Mar 2016 20:53:58 -0800 Subject: [PATCH 334/688] Use _cycleWindows selector to implement cmd-` --- atom/browser/native_window_mac.mm | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9d9f2a2392d..01073ed73da 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -896,21 +896,11 @@ void NativeWindowMac::HandleKeyboardEvent( // Handle the cmd+~ shortcut. if ((event.os_event.modifierFlags & NSCommandKeyMask) /* cmd */ && (event.os_event.keyCode == 50 /* ~ */)) { - // Switch to next visible window. - NSArray* windows = [NSApp windows]; - NSIndexSet* indexes = [windows indexesOfObjectsPassingTest: - ^BOOL(id window, NSUInteger idx, BOOL* stop) { - return [window isVisible]; - }]; - if ([indexes count] == 0) - return; - NSUInteger current = [windows indexOfObject:event.os_event.window]; - if (current == NSNotFound) // Some faked event. - return; - NSUInteger next = [indexes indexGreaterThanIndex:current]; - if (next == NSNotFound) - next = [indexes firstIndex]; - [[windows objectAtIndex:next] makeKeyAndOrderFront:nil]; + if (event.os_event.modifierFlags & NSShiftKeyMask) { + [NSApp sendAction:@selector(_cycleWindowsReversed:) to:nil from:nil]; + } else { + [NSApp sendAction:@selector(_cycleWindows:) to:nil from:nil]; + } } } } From 63294892f0be54713a2104646291a7e1a6eddb94 Mon Sep 17 00:00:00 2001 From: Daniel Pham Date: Thu, 3 Mar 2016 23:58:58 -0500 Subject: [PATCH 335/688] Rename dark-mode-changed to platform-theme-changed --- atom/browser/api/atom_api_app.cc | 4 ++-- atom/browser/api/atom_api_app.h | 2 +- atom/browser/browser.cc | 4 ++-- atom/browser/browser.h | 3 ++- atom/browser/browser_observer.h | 2 +- atom/browser/mac/atom_application_delegate.mm | 6 +++--- docs/api/app.md | 2 +- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 76a5f32a245..fc1afb6d35c 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -283,8 +283,8 @@ void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) { } #if defined(OS_MACOSX) -void App::OnDarkModeChanged() { - Emit("dark-mode-changed"); +void App::OnPlatformThemeChanged() { + Emit("platform-theme-changed"); } #endif diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 54d3f9dc743..3d4ac17adf7 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -72,7 +72,7 @@ class App : public AtomBrowserClient::Delegate, void OnGpuProcessCrashed(base::TerminationStatus exit_code) override; #if defined(OS_MACOSX) - void OnDarkModeChanged() override; + void OnPlatformThemeChanged() override; #endif // mate::Wrappable: diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 7fbe01633b0..e89f52283b3 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -181,8 +181,8 @@ void Browser::OnWindowAllClosed() { FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWindowAllClosed()); } -void Browser::DarkModeChanged() { - FOR_EACH_OBSERVER(BrowserObserver, observers_, OnDarkModeChanged()); +void Browser::PlatformThemeChanged() { + FOR_EACH_OBSERVER(BrowserObserver, observers_, OnPlatformThemeChanged()); } } // namespace atom diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 04b7a725787..8ea52370027 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -145,7 +145,8 @@ class Browser : public WindowListObserver { // Request basic auth login. void RequestLogin(LoginHandler* login_handler); - void DarkModeChanged(); + // Tell the application that plaform's theme changed. + void PlatformThemeChanged(); void AddObserver(BrowserObserver* obs) { observers_.AddObserver(obs); diff --git a/atom/browser/browser_observer.h b/atom/browser/browser_observer.h index 0577712becd..da327eb90a0 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -45,7 +45,7 @@ class BrowserObserver { // The browser requests HTTP login. virtual void OnLogin(LoginHandler* login_handler) {} - virtual void OnDarkModeChanged() {} + virtual void OnPlatformThemeChanged() {} protected: virtual ~BrowserObserver() {} diff --git a/atom/browser/mac/atom_application_delegate.mm b/atom/browser/mac/atom_application_delegate.mm index 0b9c60e7d26..f4db929bf57 100644 --- a/atom/browser/mac/atom_application_delegate.mm +++ b/atom/browser/mac/atom_application_delegate.mm @@ -25,7 +25,7 @@ [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"]; // Add observer to monitor the system's Dark Mode theme. - [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(darkModeChanged:) name:@"AppleInterfaceThemeChangedNotification" object:nil]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(platformThemeChanged:) name:@"AppleInterfaceThemeChangedNotification" object:nil]; atom::Browser::Get()->WillFinishLaunching(); } @@ -62,8 +62,8 @@ return flag; } -- (void)darkModeChanged:(NSNotification *)notify { - atom::Browser::Get()->DarkModeChanged(); +- (void)platformThemeChanged:(NSNotification *)notify { + atom::Browser::Get()->PlatformThemeChanged(); } @end diff --git a/docs/api/app.md b/docs/api/app.md index 3469c6b108d..8cc9c6e3747 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -228,7 +228,7 @@ app.on('login', function(event, webContents, request, authInfo, callback) { Emitted when the gpu process crashes. -### Event: 'dark-mode-changed' _OS X_ +### Event: 'platform-theme-changed' _OS X_ Emitted when the system's Dark Mode theme is toggled. From a4e04e6083a4f40fc8838571490ee00adb9e3596 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 12:29:50 -0800 Subject: [PATCH 336/688] Always call done callback --- spec/chromium-spec.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 8477aea776a..0e3a836d39b 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -94,10 +94,13 @@ describe('chromium feature', function() { it('can return labels of enumerated devices', function(done) { navigator.mediaDevices.enumerateDevices().then((devices) => { - const result = devices.some((device) => !!device.label); - if (result) + const labels = devices.map((device) => device.label); + const labelFound = labels.some((label) => !!label); + if (labelFound) done(); - }); + else + done('No device labels found: ' + JSON.stringify(labels)); + }).catch(done); }); }); From 20e9a871589369982b64c4b1c25885dcb34f29ab Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 12:38:39 -0800 Subject: [PATCH 337/688] Don't run mediaDevices spec on Linux CI --- spec/chromium-spec.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 0e3a836d39b..67b2d263204 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -7,6 +7,8 @@ const remote = require('electron').remote; const BrowserWindow = remote.require('electron').BrowserWindow; const session = remote.require('electron').session; +const isCI = remote.getGlobal('isCi'); + describe('chromium feature', function() { var fixtures = path.resolve(__dirname, 'fixtures'); var listener = null; @@ -91,6 +93,9 @@ describe('chromium feature', function() { if (process.env.TRAVIS === 'true') { return; } + if (isCI && process.platform === 'linux') { + return; + } it('can return labels of enumerated devices', function(done) { navigator.mediaDevices.enumerateDevices().then((devices) => { From a9e22801e9a4671da2d13b338864b59195dffd70 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 15:43:51 -0800 Subject: [PATCH 338/688] Add failing spec for reassigning remote function --- spec/api-ipc-spec.js | 8 ++++++++ spec/fixtures/module/function.js | 1 + 2 files changed, 9 insertions(+) create mode 100644 spec/fixtures/module/function.js diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 1ac717cd9d3..462c7bcf976 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -63,6 +63,14 @@ describe('ipc module', function() { var obj = new call.constructor; assert.equal(obj.test, 'test'); }); + + it('can reassign its member functions', function() { + var remoteFunctions = remote.require(path.join(fixtures, 'module', 'function.js')); + assert.equal(remoteFunctions.aFunction(), 1127); + + remoteFunctions.aFunction = function () { return 1234; }; + assert.equal(remoteFunctions.aFunction(), 1234); + }); }); describe('remote value in browser', function() { diff --git a/spec/fixtures/module/function.js b/spec/fixtures/module/function.js new file mode 100644 index 00000000000..803a2838d37 --- /dev/null +++ b/spec/fixtures/module/function.js @@ -0,0 +1 @@ +exports.aFunction = function() { return 1127; }; From 610a5031885474d320eeda46fdffb03884ccd867 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 15:49:46 -0800 Subject: [PATCH 339/688] Make member functions writable --- atom/renderer/api/lib/remote.js | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/renderer/api/lib/remote.js b/atom/renderer/api/lib/remote.js index a9798338faa..6b84f74d354 100644 --- a/atom/renderer/api/lib/remote.js +++ b/atom/renderer/api/lib/remote.js @@ -110,6 +110,7 @@ let setObjectMembers = function(object, metaId, members) { return metaToValue(ret); } }; + descriptor.writable = true; descriptor.value = remoteMemberFunction; } else if (member.type === 'get') { descriptor.get = function() { From f460d81dd09d6bc050574e3018fec372958f854b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 15:51:17 -0800 Subject: [PATCH 340/688] Allow remote member functions to be deleted --- atom/renderer/api/lib/remote.js | 1 + spec/api-ipc-spec.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/atom/renderer/api/lib/remote.js b/atom/renderer/api/lib/remote.js index 6b84f74d354..07aa2478293 100644 --- a/atom/renderer/api/lib/remote.js +++ b/atom/renderer/api/lib/remote.js @@ -111,6 +111,7 @@ let setObjectMembers = function(object, metaId, members) { } }; descriptor.writable = true; + descriptor.configurable = true; descriptor.value = remoteMemberFunction; } else if (member.type === 'get') { descriptor.get = function() { diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 462c7bcf976..df18835c43d 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -70,6 +70,8 @@ describe('ipc module', function() { remoteFunctions.aFunction = function () { return 1234; }; assert.equal(remoteFunctions.aFunction(), 1234); + + assert.equal(delete remoteFunctions.aFunction, true); }); }); From 3230927f105a9140985eec7505b7d1d9a2c72ea7 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 15:56:18 -0800 Subject: [PATCH 341/688] Mention deleting --- spec/api-ipc-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index df18835c43d..641d89270cb 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -64,7 +64,7 @@ describe('ipc module', function() { assert.equal(obj.test, 'test'); }); - it('can reassign its member functions', function() { + it('can reassign and delete its member functions', function() { var remoteFunctions = remote.require(path.join(fixtures, 'module', 'function.js')); assert.equal(remoteFunctions.aFunction(), 1127); From fe9e026f9e9aaf191c9e998493f2d88c4c6f76e7 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 15:57:21 -0800 Subject: [PATCH 342/688] getObjectMemebers -> getObjectMembers --- atom/browser/lib/rpc-server.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index a31c6e146e8..5399c192e82 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -16,7 +16,7 @@ const FUNCTION_PROPERTIES = [ let rendererFunctions = {}; // Return the description of object's members: -let getObjectMemebers = function(object) { +let getObjectMembers = function(object) { let names = Object.getOwnPropertyNames(object); // For Function, we should not override following properties even though they // are "own" properties. @@ -46,7 +46,7 @@ let getObjectPrototype = function(object) { if (proto === null || proto === Object.prototype) return null; return { - members: getObjectMemebers(proto), + members: getObjectMembers(proto), proto: getObjectPrototype(proto), }; }; @@ -101,7 +101,7 @@ var valueToMeta = function(sender, value, optimizeSimpleObject) { // passed to renderer we would assume the renderer keeps a reference of // it. meta.id = objectsRegistry.add(sender, value); - meta.members = getObjectMemebers(value); + meta.members = getObjectMembers(value); meta.proto = getObjectPrototype(value); } else if (meta.type === 'buffer') { meta.value = Array.prototype.slice.call(value, 0); From 73f6162f5c6e0889857d27d1470a6742c719f492 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 16:12:14 -0800 Subject: [PATCH 343/688] Enable resizable spec on Linux --- spec/api-browser-window-spec.js | 34 +++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 25e92382cca..8c45b43f553 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -527,6 +527,24 @@ describe('browser-window module', function() { }); }); + describe('window states', function () { + describe('resizable state', function() { + it('can be changed with resizable option', function() { + w.destroy(); + w = new BrowserWindow({show: false, resizable: false}); + assert.equal(w.isResizable(), false); + }); + + it('can be changed with setResizable method', function() { + assert.equal(w.isResizable(), true); + w.setResizable(false); + assert.equal(w.isResizable(), false); + w.setResizable(true); + assert.equal(w.isResizable(), true); + }); + }); + }) + describe('window states', function() { // Not implemented on Linux. if (process.platform == 'linux') @@ -625,22 +643,6 @@ describe('browser-window module', function() { }); }); - describe('resizable state', function() { - it('can be changed with resizable option', function() { - w.destroy(); - w = new BrowserWindow({show: false, resizable: false}); - assert.equal(w.isResizable(), false); - }); - - it('can be changed with setResizable method', function() { - assert.equal(w.isResizable(), true); - w.setResizable(false); - assert.equal(w.isResizable(), false); - w.setResizable(true); - assert.equal(w.isResizable(), true); - }); - }); - describe('hasShadow state', function() { // On Window there is no shadow by default and it can not be changed // dynamically. From 67edcc8f9192948498bc36b697e63b494f35ebb2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 16:12:58 -0800 Subject: [PATCH 344/688] Initially set resizable property on Linux --- atom/browser/native_window_views.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 97a2ee05a33..3605abbd3ff 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -120,11 +120,11 @@ NativeWindowViews::NativeWindowViews( minimizable_(true) { options.Get(options::kTitle, &title_); options.Get(options::kAutoHideMenuBar, &menu_bar_autohide_); + options.Get(options::kResizable, &resizable_); #if defined(OS_WIN) // On Windows we rely on the CanResize() to indicate whether window can be // resized, and it should be set before window is created. - options.Get(options::kResizable, &resizable_); options.Get(options::kMinimizable, &minimizable_); options.Get(options::kMaximizable, &maximizable_); #endif From bda5bb4a74416fed3b0577677e458c5b2e416a02 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 16:15:04 -0800 Subject: [PATCH 345/688] Add missing semicolon --- spec/api-browser-window-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 8c45b43f553..c11d177a73e 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -543,7 +543,7 @@ describe('browser-window module', function() { assert.equal(w.isResizable(), true); }); }); - }) + }); describe('window states', function() { // Not implemented on Linux. From 33978455b807647ab75c411639c717f245fe04e8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 5 Mar 2016 12:00:06 +0900 Subject: [PATCH 346/688] Bump v0.36.10 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index 0bccc254b1b..7f78bee91b1 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.36.9', + 'version%': '0.36.10', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index b3eb7d8efaa..54b4f4d6179 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.36.9 + 0.36.10 CFBundleShortVersionString - 0.36.9 + 0.36.10 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 2dee1c0e433..9acd36f43a2 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,36,9,0 - PRODUCTVERSION 0,36,9,0 + FILEVERSION 0,36,10,0 + PRODUCTVERSION 0,36,10,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.36.9" + VALUE "FileVersion", "0.36.10" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.36.9" + VALUE "ProductVersion", "0.36.10" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 136c375e2ac..c4291437e5b 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 36 -#define ATOM_PATCH_VERSION 9 +#define ATOM_PATCH_VERSION 10 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index 504bdd6a4f7..ca232158068 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.36.9", + "version": "0.36.10", "devDependencies": { "asar": "^0.10.0", "eslint": "^2.1.0", From d5f5cdb45ab122a1d6b8e9290ef4b3b26764f5b3 Mon Sep 17 00:00:00 2001 From: Daniel Pham Date: Sat, 5 Mar 2016 01:39:13 -0500 Subject: [PATCH 347/688] :apple:Fix 'isMaximized()' for non resizable windows --- atom/browser/native_window_mac.mm | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9d9f2a2392d..46448594c36 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -583,7 +583,16 @@ void NativeWindowMac::Unmaximize() { } bool NativeWindowMac::IsMaximized() { - return [window_ isZoomed]; + if (([window_ styleMask] & NSResizableWindowMask) != 0) { + return [window_ isZoomed]; + } else { + NSRect rectScreen = [[NSScreen mainScreen] visibleFrame]; + NSRect rectWindow = [window_ frame]; + return (rectScreen.origin.x == rectWindow.origin.x && + rectScreen.origin.y == rectWindow.origin.y && + rectScreen.size.width == rectWindow.size.width && + rectScreen.size.height == rectWindow.size.height); + } } void NativeWindowMac::Minimize() { From 23b92ef9ecc9bf89bd7776068d03fa0458c264c2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 5 Mar 2016 18:57:46 +0900 Subject: [PATCH 348/688] Fix passing certificate to select-client-certificate's callback --- atom/browser/api/atom_api_app.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index e54d7fee176..0c035af49b7 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -132,19 +132,20 @@ void OnClientCertificateSelected( std::shared_ptr delegate, mate::Arguments* args) { mate::Dictionary cert_data; - if (!(args->Length() == 1 && args->GetNext(&cert_data))) { + if (!args->GetNext(&cert_data)) { args->ThrowError(); return; } - std::string encoded_data; - cert_data.Get("data", &encoded_data); + v8::Local data; + if (!cert_data.Get("data", &data)) + return; - auto certs = - net::X509Certificate::CreateCertificateListFromBytes( - encoded_data.data(), encoded_data.size(), - net::X509Certificate::FORMAT_AUTO); - delegate->ContinueWithCertificate(certs[0].get()); + auto certs = net::X509Certificate::CreateCertificateListFromBytes( + node::Buffer::Data(data), node::Buffer::Length(data), + net::X509Certificate::FORMAT_AUTO); + if (certs.size() > 0) + delegate->ContinueWithCertificate(certs[0].get()); } void PassLoginInformation(scoped_refptr login_handler, From 5f95fea3e278b4e6261d9a304a9e313e0c0cf516 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 5 Mar 2016 21:20:02 +0900 Subject: [PATCH 349/688] docs: OS X also has progress bar --- docs/tutorial/desktop-environment-integration.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index a72d68b3cf3..c35eea944be 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -246,12 +246,14 @@ __Launcher shortcuts of Audacious:__ ![audacious](https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles?action=AttachFile&do=get&target=shortcuts.png) -## Progress Bar in Taskbar (Windows & Unity) +## Progress Bar in Taskbar (Windows, OS X, Unity) On Windows a taskbar button can be used to display a progress bar. This enables a window to provide progress information to the user without the user having to switch to the window itself. +On OS X the progress bar will be displayed as a part of the dock icon. + The Unity DE also has a similar feature that allows you to specify the progress bar in the launcher. @@ -259,10 +261,6 @@ __Progress bar in taskbar button:__ ![Taskbar Progress Bar](https://cloud.githubusercontent.com/assets/639601/5081682/16691fda-6f0e-11e4-9676-49b6418f1264.png) -__Progress bar in Unity launcher:__ - -![Unity Launcher](https://cloud.githubusercontent.com/assets/639601/5081747/4a0a589e-6f0f-11e4-803f-91594716a546.png) - To set the progress bar for a Window, you can use the [BrowserWindow.setProgressBar][setprogressbar] API: From 2be368bded41425fa682381e4e723970a74a2652 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 5 Mar 2016 21:38:06 +0900 Subject: [PATCH 350/688] SetFullScreen should not work at all when not fullscreenable This follows the logic of OS X. --- atom/browser/native_window_views.cc | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index a0c2e3f170b..93eb7b88d89 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -363,29 +363,27 @@ bool NativeWindowViews::IsMinimized() { } void NativeWindowViews::SetFullScreen(bool fullscreen) { + if (!IsFullScreenable()) + return; + #if defined(OS_WIN) // There is no native fullscreen state on Windows. if (fullscreen) { - if (IsFullScreenable()) { - last_window_state_ = ui::SHOW_STATE_FULLSCREEN; - NotifyWindowEnterFullScreen(); - } + last_window_state_ = ui::SHOW_STATE_FULLSCREEN; + NotifyWindowEnterFullScreen(); } else { last_window_state_ = ui::SHOW_STATE_NORMAL; NotifyWindowLeaveFullScreen(); } // We set the new value after notifying, so we can handle the size event // correctly. - if (IsFullScreenable()) - window_->SetFullscreen(fullscreen); + window_->SetFullscreen(fullscreen); #else - if (!fullscreen || (fullscreen && IsFullScreenable())) { - if (IsVisible()) - window_->SetFullscreen(fullscreen); - else - window_->native_widget_private()->ShowWithWindowState( - ui::SHOW_STATE_FULLSCREEN); - } + if (IsVisible()) + window_->SetFullscreen(fullscreen); + else + window_->native_widget_private()->ShowWithWindowState( + ui::SHOW_STATE_FULLSCREEN); #endif } From 114801d41242b162af786f9fefc0b646273210e3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 5 Mar 2016 21:54:41 +0900 Subject: [PATCH 351/688] Remove the duplicate logic on OS X --- atom/browser/native_window.cc | 11 +++++------ atom/browser/native_window_mac.mm | 14 ++------------ 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 16154be6bea..20400437fce 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -133,18 +133,17 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { if (options.Get(options::kAlwaysOnTop, &top) && top) { SetAlwaysOnTop(true); } - - // Disable fullscreen button when 'fullscreenable' is false or 'fullscreen' - // is specified to false. + // Disable fullscreen button if 'fullscreen' is specified to false. bool fullscreenable = true; - options.Get(options::kFullScreenable, &fullscreenable); bool fullscreen = false; if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) fullscreenable = false; + // Overriden by 'fullscreenable'. + options.Get(options::kFullScreenable, &fullscreenable); SetFullScreenable(fullscreenable); - if (fullscreen) + if (fullscreen) { SetFullScreen(true); - + } bool skip; if (options.Get(options::kSkipTaskbar, &skip) && skip) { SetSkipTaskbar(skip); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9d9f2a2392d..3fc45478514 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -482,19 +482,9 @@ NativeWindowMac::NativeWindowMac( options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor); [window_ setDisableAutoHideCursor:disableAutoHideCursor]; - // Disable fullscreen button when 'fullscreenable' is false or 'fullscreen' - // is specified to false. - bool fullscreenable = true; - options.Get(options::kFullScreenable, &fullscreenable); - bool fullscreen = false; - if (options.Get(options::kFullscreen, &fullscreen) && !fullscreen) - fullscreenable = false; - SetFullScreenable(fullscreenable); - - // Disable zoom button if window is not resizable - if (!maximizable) { + // Disable zoom button if window is not resizable. + if (!maximizable) SetMaximizable(false); - } NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; From 2515425cd5525f2bab4ba6ba3d497a6f7a1c9c09 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 6 Mar 2016 15:04:05 +0900 Subject: [PATCH 352/688] Remove duplicated keyboard code --- atom/browser/ui/accelerator_util.cc | 113 ++++------------ atom/common/keyboard_util.cc | 127 +++++++++++++----- atom/common/keyboard_util.h | 9 +- .../native_mate_converters/blink_converter.cc | 21 ++- 4 files changed, 135 insertions(+), 135 deletions(-) diff --git a/atom/browser/ui/accelerator_util.cc b/atom/browser/ui/accelerator_util.cc index 39138d8e49b..f683c99c637 100644 --- a/atom/browser/ui/accelerator_util.cc +++ b/atom/browser/ui/accelerator_util.cc @@ -18,13 +18,12 @@ namespace accelerator_util { -bool StringToAccelerator(const std::string& description, +bool StringToAccelerator(const std::string& shortcut, ui::Accelerator* accelerator) { - if (!base::IsStringASCII(description)) { + if (!base::IsStringASCII(shortcut)) { LOG(ERROR) << "The accelerator string can only contain ASCII characters"; return false; } - std::string shortcut(base::ToLowerASCII(description)); std::vector tokens = base::SplitString( shortcut, "+", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); @@ -33,95 +32,35 @@ bool StringToAccelerator(const std::string& description, int modifiers = ui::EF_NONE; ui::KeyboardCode key = ui::VKEY_UNKNOWN; for (size_t i = 0; i < tokens.size(); i++) { - // We use straight comparing instead of map because the accelerator tends - // to be correct and usually only uses few special tokens. - if (tokens[i].size() == 1) { - bool shifted = false; - key = atom::KeyboardCodeFromCharCode(tokens[i][0], &shifted); - if (shifted) + bool shifted = false; + ui::KeyboardCode code = atom::KeyboardCodeFromStr(tokens[i], &shifted); + if (shifted) + modifiers |= ui::EF_SHIFT_DOWN; + switch (code) { + // The token can be a modifier. + case ui::VKEY_SHIFT: modifiers |= ui::EF_SHIFT_DOWN; - } else if (tokens[i] == "ctrl" || tokens[i] == "control") { - modifiers |= ui::EF_CONTROL_DOWN; - } else if (tokens[i] == "super") { - modifiers |= ui::EF_COMMAND_DOWN; -#if defined(OS_MACOSX) - } else if (tokens[i] == "cmd" || tokens[i] == "command") { - modifiers |= ui::EF_COMMAND_DOWN; -#endif - } else if (tokens[i] == "commandorcontrol" || tokens[i] == "cmdorctrl") { -#if defined(OS_MACOSX) - modifiers |= ui::EF_COMMAND_DOWN; -#else - modifiers |= ui::EF_CONTROL_DOWN; -#endif - } else if (tokens[i] == "alt") { - modifiers |= ui::EF_ALT_DOWN; - } else if (tokens[i] == "shift") { - modifiers |= ui::EF_SHIFT_DOWN; - } else if (tokens[i] == "plus") { - modifiers |= ui::EF_SHIFT_DOWN; - key = ui::VKEY_OEM_PLUS; - } else if (tokens[i] == "tab") { - key = ui::VKEY_TAB; - } else if (tokens[i] == "space") { - key = ui::VKEY_SPACE; - } else if (tokens[i] == "backspace") { - key = ui::VKEY_BACK; - } else if (tokens[i] == "delete") { - key = ui::VKEY_DELETE; - } else if (tokens[i] == "insert") { - key = ui::VKEY_INSERT; - } else if (tokens[i] == "enter" || tokens[i] == "return") { - key = ui::VKEY_RETURN; - } else if (tokens[i] == "up") { - key = ui::VKEY_UP; - } else if (tokens[i] == "down") { - key = ui::VKEY_DOWN; - } else if (tokens[i] == "left") { - key = ui::VKEY_LEFT; - } else if (tokens[i] == "right") { - key = ui::VKEY_RIGHT; - } else if (tokens[i] == "home") { - key = ui::VKEY_HOME; - } else if (tokens[i] == "end") { - key = ui::VKEY_END; - } else if (tokens[i] == "pageup") { - key = ui::VKEY_PRIOR; - } else if (tokens[i] == "pagedown") { - key = ui::VKEY_NEXT; - } else if (tokens[i] == "esc" || tokens[i] == "escape") { - key = ui::VKEY_ESCAPE; - } else if (tokens[i] == "volumemute") { - key = ui::VKEY_VOLUME_MUTE; - } else if (tokens[i] == "volumeup") { - key = ui::VKEY_VOLUME_UP; - } else if (tokens[i] == "volumedown") { - key = ui::VKEY_VOLUME_DOWN; - } else if (tokens[i] == "medianexttrack") { - key = ui::VKEY_MEDIA_NEXT_TRACK; - } else if (tokens[i] == "mediaprevioustrack") { - key = ui::VKEY_MEDIA_PREV_TRACK; - } else if (tokens[i] == "mediastop") { - key = ui::VKEY_MEDIA_STOP; - } else if (tokens[i] == "mediaplaypause") { - key = ui::VKEY_MEDIA_PLAY_PAUSE; - } else if (tokens[i].size() > 1 && tokens[i][0] == 'f') { - // F1 - F24. - int n; - if (base::StringToInt(tokens[i].c_str() + 1, &n) && n > 0 && n < 25) { - key = static_cast(ui::VKEY_F1 + n - 1); - } else { - LOG(WARNING) << tokens[i] << "is not available on keyboard"; - return false; - } - } else { - LOG(WARNING) << "Invalid accelerator token: " << tokens[i]; - return false; + break; + case ui::VKEY_CONTROL: + modifiers |= ui::EF_CONTROL_DOWN; + break; + case ui::VKEY_MENU: + modifiers |= ui::EF_ALT_DOWN; + break; + case ui::VKEY_COMMAND: + modifiers |= ui::EF_COMMAND_DOWN; + break; + case ui::VKEY_ALTGR: + modifiers |= ui::EF_ALTGR_DOWN; + break; + // Or it is a normal key. + default: + key = code; } } if (key == ui::VKEY_UNKNOWN) { - LOG(WARNING) << "The accelerator doesn't contain a valid key"; + LOG(WARNING) << shortcut << " doesn't contain a valid key"; return false; } diff --git a/atom/common/keyboard_util.cc b/atom/common/keyboard_util.cc index 1884246d233..d860bc0c46c 100644 --- a/atom/common/keyboard_util.cc +++ b/atom/common/keyboard_util.cc @@ -3,12 +3,19 @@ // found in the LICENSE file. #include + #include "atom/common/keyboard_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" namespace atom { -// Return key code of the char. +namespace { + +// Return key code of the char, and also determine whether the SHIFT key is +// pressed. ui::KeyboardCode KeyboardCodeFromCharCode(base::char16 c, bool* shifted) { + c = base::ToLowerASCII(c); *shifted = false; switch (c) { case 0x08: return ui::VKEY_BACK; @@ -72,38 +79,98 @@ ui::KeyboardCode KeyboardCodeFromCharCode(base::char16 c, bool* shifted) { } } -// Return key code of the char. -ui::KeyboardCode KeyboardCodeFromKeyIdentifier(const std::string& chr) { - if (chr == "enter") return ui::VKEY_RETURN; - if (chr == "backspace") return ui::VKEY_BACK; - if (chr == "delete") return ui::VKEY_DELETE; - if (chr == "tab") return ui::VKEY_TAB; - if (chr == "escape") return ui::VKEY_ESCAPE; - if (chr == "control") return ui::VKEY_CONTROL; +// Return key code represented by |str|. +ui::KeyboardCode KeyboardCodeFromKeyIdentifier(const std::string& s, + bool* shifted) { + std::string str = base::ToLowerASCII(s); + if (str == "ctrl" || str == "control") { + return ui::VKEY_CONTROL; + } else if (str == "super" || str == "cmd" || str == "command" || + str == "meta") { + return ui::VKEY_COMMAND; + } else if (str == "commandorcontrol" || str == "cmdorctrl") { #if defined(OS_MACOSX) - if (chr == "command" - || chr == "cmd" - || chr == "meta") return ui::VKEY_COMMAND; - if (chr == "option") return ui::VKEY_MENU; + return ui::VKEY_COMMAND; +#else + return ui::VKEY_CONTROL; #endif -#if defined(OS_WIN) - if (chr == "meta") return ui::VKEY_LWIN; - if (chr == "altgr") return ui::VKEY_ALTGR; -#endif - if (chr == "alt") return ui::VKEY_MENU; - if (chr == "shift") return ui::VKEY_SHIFT; - if (chr == "end") return ui::VKEY_END; - if (chr == "home") return ui::VKEY_HOME; - if (chr == "insert") return ui::VKEY_INSERT; - if (chr == "left") return ui::VKEY_LEFT; - if (chr == "up") return ui::VKEY_UP; - if (chr == "right") return ui::VKEY_RIGHT; - if (chr == "down") return ui::VKEY_DOWN; - if (chr == "pageup") return ui::VKEY_PRIOR; - if (chr == "pagedown") return ui::VKEY_NEXT; - if (chr == "printscreen") return ui::VKEY_SNAPSHOT; + } else if (str == "alt" || str == "option") { + return ui::VKEY_MENU; + } else if (str == "shift") { + return ui::VKEY_SHIFT; + } else if (str == "altgr") { + return ui::VKEY_ALTGR; + } else if (str == "plus") { + *shifted = true; + return ui::VKEY_OEM_PLUS; + } else if (str == "tab") { + return ui::VKEY_TAB; + } else if (str == "space") { + return ui::VKEY_SPACE; + } else if (str == "backspace") { + return ui::VKEY_BACK; + } else if (str == "delete") { + return ui::VKEY_DELETE; + } else if (str == "insert") { + return ui::VKEY_INSERT; + } else if (str == "enter" || str == "return") { + return ui::VKEY_RETURN; + } else if (str == "up") { + return ui::VKEY_UP; + } else if (str == "down") { + return ui::VKEY_DOWN; + } else if (str == "left") { + return ui::VKEY_LEFT; + } else if (str == "right") { + return ui::VKEY_RIGHT; + } else if (str == "home") { + return ui::VKEY_HOME; + } else if (str == "end") { + return ui::VKEY_END; + } else if (str == "pageup") { + return ui::VKEY_PRIOR; + } else if (str == "pagedown") { + return ui::VKEY_NEXT; + } else if (str == "esc" || str == "escape") { + return ui::VKEY_ESCAPE; + } else if (str == "volumemute") { + return ui::VKEY_VOLUME_MUTE; + } else if (str == "volumeup") { + return ui::VKEY_VOLUME_UP; + } else if (str == "volumedown") { + return ui::VKEY_VOLUME_DOWN; + } else if (str == "medianexttrack") { + return ui::VKEY_MEDIA_NEXT_TRACK; + } else if (str == "mediaprevioustrack") { + return ui::VKEY_MEDIA_PREV_TRACK; + } else if (str == "mediastop") { + return ui::VKEY_MEDIA_STOP; + } else if (str == "mediaplaypause") { + return ui::VKEY_MEDIA_PLAY_PAUSE; + } else if (str == "printscreen") { + return ui::VKEY_SNAPSHOT; + } else if (str.size() > 1 && str[0] == 'f') { + // F1 - F24. + int n; + if (base::StringToInt(str.c_str() + 1, &n) && n > 0 && n < 25) { + return static_cast(ui::VKEY_F1 + n - 1); + } else { + LOG(WARNING) << str << "is not available on keyboard"; + return ui::VKEY_UNKNOWN; + } + } else { + LOG(WARNING) << "Invalid accelerator token: " << str; + return ui::VKEY_UNKNOWN; + } +} - return ui::VKEY_UNKNOWN; +} // namespace + +ui::KeyboardCode KeyboardCodeFromStr(const std::string& str, bool* shifted) { + if (str.size() == 1) + return KeyboardCodeFromCharCode(str[0], shifted); + else + return KeyboardCodeFromKeyIdentifier(str, shifted); } } // namespace atom diff --git a/atom/common/keyboard_util.h b/atom/common/keyboard_util.h index d3168d4447e..c9d1b809e8f 100644 --- a/atom/common/keyboard_util.h +++ b/atom/common/keyboard_util.h @@ -6,17 +6,14 @@ #define ATOM_COMMON_KEYBOARD_UTIL_H_ #include + #include "ui/events/keycodes/keyboard_codes.h" -#include "base/strings/string_util.h" namespace atom { -// Return key code of the char, and also determine whether the SHIFT key is +// Return key code of the |str|, and also determine whether the SHIFT key is // pressed. -ui::KeyboardCode KeyboardCodeFromCharCode(base::char16 c, bool* shifted); - -// Return key code of the char from a string representation of the char -ui::KeyboardCode KeyboardCodeFromKeyIdentifier(const std::string& chr); +ui::KeyboardCode KeyboardCodeFromStr(const std::string& str, bool* shifted); } // namespace atom diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index fdb894b3346..c58f830eb02 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -159,25 +159,22 @@ bool Converter::FromV8( return false; if (!ConvertFromV8(isolate, val, static_cast(out))) return false; - base::char16 code; - std::string identifier; - bool shifted = false; - if (dict.Get("keyCode", &code)) - out->windowsKeyCode = atom::KeyboardCodeFromCharCode(code, &shifted); - else if (dict.Get("keyCode", &identifier)) - out->windowsKeyCode = atom::KeyboardCodeFromKeyIdentifier( - base::ToLowerASCII(identifier)); + std::string str; + bool shifted = false; + if (dict.Get("keyCode", &str)) + out->windowsKeyCode = atom::KeyboardCodeFromStr(str, &shifted); else return false; if (shifted) out->modifiers |= blink::WebInputEvent::ShiftKey; out->setKeyIdentifierFromWindowsKeyCode(); - if (out->type == blink::WebInputEvent::Char || - out->type == blink::WebInputEvent::RawKeyDown) { - out->text[0] = code; - out->unmodifiedText[0] = code; + if ((out->type == blink::WebInputEvent::Char || + out->type == blink::WebInputEvent::RawKeyDown) && + str.size() == 1) { + out->text[0] = str[0]; + out->unmodifiedText[0] = str[0]; } return true; } From b7a40f309761f4a54a2171fbeeab129677a8134e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 6 Mar 2016 15:12:04 +0900 Subject: [PATCH 353/688] docs: Add missing key codes --- docs/api/accelerator.md | 3 +++ docs/api/web-contents.md | 10 +++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/api/accelerator.md b/docs/api/accelerator.md index 8858d18e856..93d1f244c6b 100644 --- a/docs/api/accelerator.md +++ b/docs/api/accelerator.md @@ -23,6 +23,8 @@ The `Super` key is mapped to the `Windows` key on Windows and Linux and * `Control` (or `Ctrl` for short) * `CommandOrControl` (or `CmdOrCtrl` for short) * `Alt` +* `Option` +* `AltGr` * `Shift` * `Super` @@ -44,3 +46,4 @@ The `Super` key is mapped to the `Windows` key on Windows and Linux and * `Escape` (or `Esc` for short) * `VolumeUp`, `VolumeDown` and `VolumeMute` * `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` and `MediaPlayPause` +* `PrintScreen` diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 66ab545bf21..8eda16b6860 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -764,13 +764,9 @@ Sends an input `event` to the page. For keyboard events, the `event` object also have following properties: -* `keyCode` Char or String (**required**) - The character that will be sent - as the keyboard event. Can be a single UTF-8 character, or the name of the - key that generates the event. Accepted key names are `enter`, `backspace`, - `delete`, `tab`, `escape`, `control`, `alt`, `altgr` (Windows only), `shift`, - `end`, `home`, `insert`, `left`, `up`, `right`, `down`, `pageUp`, `pageDown`, - `printScreen`, `meta`, `cmd` (OSX only), `command` (OSX only), `option` - (OSX only) +* `keyCode` String (**required**) - The character that will be sent + as the keyboard event. Should only use the valid key codes in + [Accelerator](accelerator.md). For mouse events, the `event` object also have following properties: From f9f20957a4d71be4d2f44ab4626638850735e422 Mon Sep 17 00:00:00 2001 From: Dongjoon Hyun Date: Sat, 5 Mar 2016 23:28:39 -0800 Subject: [PATCH 354/688] Fix link name. --- docs/api/synopsis.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/synopsis.md b/docs/api/synopsis.md index d14d52a39b3..f2009e75520 100644 --- a/docs/api/synopsis.md +++ b/docs/api/synopsis.md @@ -49,7 +49,7 @@ To run your app, read [Run your app](../tutorial/quick-start.md#run-your-app). ## Destructuring assignment If you are using CoffeeScript or Babel, you can also use -[destructuring assignment][desctructuring-assignment] to make it easier to use +[destructuring assignment][destructuring-assignment] to make it easier to use built-in modules: ```javascript @@ -79,5 +79,5 @@ require('electron').hideInternalModules() ``` [gui]: https://en.wikipedia.org/wiki/Graphical_user_interface -[desctructuring-assignment]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment +[destructuring-assignment]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment [issue-387]: https://github.com/atom/electron/issues/387 From 68b453770bc36539f14e19ca94f7726a238c3e79 Mon Sep 17 00:00:00 2001 From: Daniel Pham Date: Sun, 6 Mar 2016 10:55:47 -0500 Subject: [PATCH 355/688] :apple: Rename 'isDarkModeEnabled' to 'isDarkMode' --- atom/browser/api/atom_api_app.cc | 4 ++-- atom/browser/browser.h | 4 ++-- atom/browser/browser_mac.mm | 2 +- docs/api/app.md | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index fc1afb6d35c..961637852be 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -376,8 +376,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( #if defined(OS_MACOSX) .SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("show", base::Bind(&Browser::Show, browser)) - .SetMethod("isDarkModeEnabled", - base::Bind(&Browser::IsDarkModeEnabled, browser)) + .SetMethod("isDarkMode", + base::Bind(&Browser::IsDarkMode, browser)) #endif #if defined(OS_WIN) .SetMethod("setUserTasks", diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 8ea52370027..1d0b4aec8ba 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -83,8 +83,8 @@ class Browser : public WindowListObserver { // Show the application. void Show(); - // Check if Dark Mode enabled. - bool IsDarkModeEnabled(); + // Check if the system is in Dark Mode. + bool IsDarkMode(); // Bounce the dock icon. enum BounceType { diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index f5859df97aa..5988e662043 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -26,7 +26,7 @@ void Browser::Show() { [[AtomApplication sharedApplication] unhide:nil]; } -bool Browser::IsDarkModeEnabled() { +bool Browser::IsDarkMode() { NSString *mode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; return [mode isEqualToString: @"Dark"]; } diff --git a/docs/api/app.md b/docs/api/app.md index 8cc9c6e3747..f18c978fadd 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -465,9 +465,9 @@ if (browserOptions.transparent) { } ``` -### `app.isDarkModeEnabled()` _OS X_ +### `app.isDarkMode()` _OS X_ -This method returns `true` if Dark Mode is enabled, and `false` otherwise. +This method returns `true` if the system is in Dark Mode, and `false` otherwise. ### `app.commandLine.appendSwitch(switch[, value])` From 672552304283652f53f0b22f244655f6651cccd5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 09:43:04 -0800 Subject: [PATCH 356/688] Remove CoffeeScript from styleguide --- docs/development/coding-style.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/development/coding-style.md b/docs/development/coding-style.md index a86ee32417d..f28b737921a 100644 --- a/docs/development/coding-style.md +++ b/docs/development/coding-style.md @@ -17,17 +17,23 @@ document. The document mentions some special types, scoped types (that automatically release their memory when going out of scope), logging mechanisms etc. -## CoffeeScript - -For CoffeeScript, we follow GitHub's [Style -Guide](https://github.com/styleguide/javascript) and the following rules: +## JavaScript * Files should **NOT** end with new line, because we want to match Google's styles. * File names should be concatenated with `-` instead of `_`, e.g. - `file-name.coffee` rather than `file_name.coffee`, because in + `file-name.js` rather than `file_name.js`, because in [github/atom](https://github.com/github/atom) module names are usually in - the `module-name` form. This rule only applies to `.coffee` files. + the `module-name` form. This rule only applies to `.js` files. +* Use newer ES6/ES2015 syntax where appropriate + * [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) + for requires and other constants + * [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) + for defining variables + * [Arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) + instead of `function () { }` + * [Template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) + instead of string concatenation using `+` ## API Names From 686af28f547b656b703b8ec443dcea92751d64a1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 09:45:13 -0800 Subject: [PATCH 357/688] Mention indent and semicolons --- docs/development/coding-style.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/development/coding-style.md b/docs/development/coding-style.md index f28b737921a..5523c072b11 100644 --- a/docs/development/coding-style.md +++ b/docs/development/coding-style.md @@ -19,6 +19,8 @@ etc. ## JavaScript +* Use a two space indent, no hard tabs. +* End lines with a `;` * Files should **NOT** end with new line, because we want to match Google's styles. * File names should be concatenated with `-` instead of `_`, e.g. From 1c68aae43ecbc02d3b04b1b054f32202de093acc Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 09:46:05 -0800 Subject: [PATCH 358/688] Mention npm run lint --- docs/development/coding-style.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/development/coding-style.md b/docs/development/coding-style.md index 5523c072b11..edc18549a72 100644 --- a/docs/development/coding-style.md +++ b/docs/development/coding-style.md @@ -2,6 +2,9 @@ These are the style guidelines for coding in Electron. +You can run `npm run lint` to show all coding style issues detected by `cpplint` +and `eslint`. + ## C++ and Python For C++ and Python, we follow Chromium's [Coding From 4ec79d5d1805e0743010cc8ca155f6075e8090aa Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 09:53:20 -0800 Subject: [PATCH 359/688] Add Linux exclusion to describe --- spec/api-browser-window-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index c11d177a73e..88b897eb449 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -545,7 +545,7 @@ describe('browser-window module', function() { }); }); - describe('window states', function() { + describe('window states (excluding Linux)', function() { // Not implemented on Linux. if (process.platform == 'linux') return; From 38acc7090b8e4dff4612816040e853493328eee5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 10:11:30 -0800 Subject: [PATCH 360/688] Contrain size in ctor on non-resizable windows --- atom/browser/native_window_views.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 3605abbd3ff..78769f252a8 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -218,6 +218,12 @@ NativeWindowViews::NativeWindowViews( std::string window_type; if (options.Get(options::kType, &window_type)) SetWindowType(GetAcceleratedWidget(), window_type); + + if (!resizable_) { + gfx::Size content_size = GetContentSize(); + SetContentSizeConstraints( + extensions::SizeConstraints(content_size, content_size)); + } #endif // Add web view. From 993b878925bf5d6c21493bdb1bf1209b2ab25511 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 10:37:01 -0800 Subject: [PATCH 361/688] :art: --- spec/api-browser-window-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 88b897eb449..731ae1cb86f 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -527,7 +527,7 @@ describe('browser-window module', function() { }); }); - describe('window states', function () { + describe('window states', function() { describe('resizable state', function() { it('can be changed with resizable option', function() { w.destroy(); From 7de37859f071d7fa910277097d6092eb116b20c9 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 13:48:33 -0800 Subject: [PATCH 362/688] Set resizable on Linux from InitWithOptions --- atom/browser/native_window.cc | 6 ++++++ atom/browser/native_window_views.cc | 7 ------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c25534f7f18..80679bdb056 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -115,6 +115,12 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { } else { SetSizeConstraints(size_constraints); } +#if defined(USE_X11) + bool resizable; + if (options.Get(options::kResizable, &resizable)) { + SetResizable(resizable); + } +#endif #if defined(OS_WIN) || defined(USE_X11) bool closable; if (options.Get(options::kClosable, &closable)) { diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 78769f252a8..a2c9e8e62d9 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -120,7 +120,6 @@ NativeWindowViews::NativeWindowViews( minimizable_(true) { options.Get(options::kTitle, &title_); options.Get(options::kAutoHideMenuBar, &menu_bar_autohide_); - options.Get(options::kResizable, &resizable_); #if defined(OS_WIN) // On Windows we rely on the CanResize() to indicate whether window can be @@ -218,12 +217,6 @@ NativeWindowViews::NativeWindowViews( std::string window_type; if (options.Get(options::kType, &window_type)) SetWindowType(GetAcceleratedWidget(), window_type); - - if (!resizable_) { - gfx::Size content_size = GetContentSize(); - SetContentSizeConstraints( - extensions::SizeConstraints(content_size, content_size)); - } #endif // Add web view. From ad3f4a26fd38887969abb14a927170ec613d3467 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 13:53:57 -0800 Subject: [PATCH 363/688] Restore setting resizable property from ctor on Windows --- atom/browser/native_window_views.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index a2c9e8e62d9..97a2ee05a33 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -124,6 +124,7 @@ NativeWindowViews::NativeWindowViews( #if defined(OS_WIN) // On Windows we rely on the CanResize() to indicate whether window can be // resized, and it should be set before window is created. + options.Get(options::kResizable, &resizable_); options.Get(options::kMinimizable, &minimizable_); options.Get(options::kMaximizable, &maximizable_); #endif From 04c8bc38b2152b253920223e5e228f4bb20f52b0 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 13:58:49 -0800 Subject: [PATCH 364/688] Tweak lint sentence --- docs/development/coding-style.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/development/coding-style.md b/docs/development/coding-style.md index edc18549a72..5d70c24c9b0 100644 --- a/docs/development/coding-style.md +++ b/docs/development/coding-style.md @@ -2,8 +2,8 @@ These are the style guidelines for coding in Electron. -You can run `npm run lint` to show all coding style issues detected by `cpplint` -and `eslint`. +You can run `npm run lint` to show any style issues detected by `cpplint` and +`eslint`. ## C++ and Python From 4b65610d40eee32b767891745c912f416d63e6d5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 15:27:16 -0800 Subject: [PATCH 365/688] Add specs for realpath of unpacked asar path --- spec/asar-spec.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 060074390f1..6660ce8979d 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -317,6 +317,13 @@ describe('asar package', function() { assert.equal(r, path.join(parent, 'a.asar', 'dir1')); }); + it('returns real path of an unpacked file', function() { + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('unpack.asar', 'a.txt'); + var r = fs.realpathSync(path.join(parent, p)); + assert.equal(r, path.join(parent, p)); + }); + it('throws ENOENT error when can not find file', function() { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'not-exist'); @@ -377,6 +384,17 @@ describe('asar package', function() { done(); }); }); + + it('returns real path of an unpacked file', function() { + var parent = fs.realpathSync(path.join(fixtures, 'asar')); + var p = path.join('unpack.asar', 'a.txt'); + fs.realpath(path.join(parent, p), function(err, r) { + assert.equal(err, null); + assert.equal(r, path.join(parent, p)); + done(); + }); + }); + it('throws ENOENT error when can not find file', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('a.asar', 'not-exist'); From 4b6639c9fd49d9c7c2e482e23c127f7c9e691d92 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 15:30:33 -0800 Subject: [PATCH 366/688] Add missing done param --- spec/asar-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 6660ce8979d..f6f4bb71dbc 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -385,7 +385,7 @@ describe('asar package', function() { }); }); - it('returns real path of an unpacked file', function() { + it('returns real path of an unpacked file', function(done) { var parent = fs.realpathSync(path.join(fixtures, 'asar')); var p = path.join('unpack.asar', 'a.txt'); fs.realpath(path.join(parent, p), function(err, r) { From 4ded709307e0406afa04e2636104818dc45747a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Machist=C3=A9=20N=2E=20Quintana?= Date: Mon, 7 Mar 2016 15:42:32 -0800 Subject: [PATCH 367/688] Map selectors for delete and pasteAndMatchStyle to roles --- atom/browser/ui/cocoa/atom_menu_controller.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/atom/browser/ui/cocoa/atom_menu_controller.mm b/atom/browser/ui/cocoa/atom_menu_controller.mm index 9c8c99da9aa..6761c51704f 100644 --- a/atom/browser/ui/cocoa/atom_menu_controller.mm +++ b/atom/browser/ui/cocoa/atom_menu_controller.mm @@ -32,6 +32,8 @@ Role kRolesMap[] = { { @selector(cut:), "cut" }, { @selector(copy:), "copy" }, { @selector(paste:), "paste" }, + { @selector(delete:), "delete"}, + { @selector(pasteAndMatchStyle:), "paste-and-match-style" }, { @selector(selectAll:), "selectall" }, { @selector(performMiniaturize:), "minimize" }, { @selector(performClose:), "close" }, From 03434f45bb7cca242bf196857fcff077d1d0c33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Machist=C3=A9=20N=2E=20Quintana?= Date: Mon, 7 Mar 2016 15:50:33 -0800 Subject: [PATCH 368/688] Map webContents.delete to role --- atom/browser/api/lib/menu-item.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/lib/menu-item.js b/atom/browser/api/lib/menu-item.js index eef8881cf52..4f449ecc015 100644 --- a/atom/browser/api/lib/menu-item.js +++ b/atom/browser/api/lib/menu-item.js @@ -11,7 +11,8 @@ rolesMap = { paste: 'paste', selectall: 'selectAll', minimize: 'minimize', - close: 'close' + close: 'close', + delete: 'delete' }; // Maps methods that should be called directly on the BrowserWindow instance From eae5cc9d2c6da51e239be43053b350b8d2b5d0b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Machist=C3=A9=20N=2E=20Quintana?= Date: Mon, 7 Mar 2016 15:53:09 -0800 Subject: [PATCH 369/688] :art: [ci skip] --- atom/browser/ui/cocoa/atom_menu_controller.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/ui/cocoa/atom_menu_controller.mm b/atom/browser/ui/cocoa/atom_menu_controller.mm index 6761c51704f..0754da0cf5e 100644 --- a/atom/browser/ui/cocoa/atom_menu_controller.mm +++ b/atom/browser/ui/cocoa/atom_menu_controller.mm @@ -32,7 +32,7 @@ Role kRolesMap[] = { { @selector(cut:), "cut" }, { @selector(copy:), "copy" }, { @selector(paste:), "paste" }, - { @selector(delete:), "delete"}, + { @selector(delete:), "delete" }, { @selector(pasteAndMatchStyle:), "paste-and-match-style" }, { @selector(selectAll:), "selectall" }, { @selector(performMiniaturize:), "minimize" }, From 2bfc7aa152ec7466b0d151bf5ab93efd016ff8ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Machist=C3=A9=20N=2E=20Quintana?= Date: Mon, 7 Mar 2016 16:01:46 -0800 Subject: [PATCH 370/688] Add mapping for performZoom --- atom/browser/ui/cocoa/atom_menu_controller.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/browser/ui/cocoa/atom_menu_controller.mm b/atom/browser/ui/cocoa/atom_menu_controller.mm index 0754da0cf5e..24098914b7c 100644 --- a/atom/browser/ui/cocoa/atom_menu_controller.mm +++ b/atom/browser/ui/cocoa/atom_menu_controller.mm @@ -37,6 +37,7 @@ Role kRolesMap[] = { { @selector(selectAll:), "selectall" }, { @selector(performMiniaturize:), "minimize" }, { @selector(performClose:), "close" }, + { @selector(performZoom:), "zoom" }, }; } // namespace From eb064240f87095df3c6960f0a799d787777e987a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Machist=C3=A9=20N=2E=20Quintana?= Date: Mon, 7 Mar 2016 16:11:58 -0800 Subject: [PATCH 371/688] :memo: Link to OS X Cocoa Event Handling guide on actions --- docs/api/menu.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/api/menu.md b/docs/api/menu.md index 7d05f88aa2b..f62cf0da5b1 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -227,6 +227,8 @@ Sends the `action` to the first responder of application. This is used for emulating default Cocoa menu behaviors, usually you would just use the `role` property of `MenuItem`. +See the [OS X Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7) for more information on OS X's native actions. + ### `Menu.buildFromTemplate(template)` * `template` Array From f47851f1e70854627ac3860f3c9be8bfe0e04831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Machist=C3=A9=20N=2E=20Quintana?= Date: Mon, 7 Mar 2016 16:19:00 -0800 Subject: [PATCH 372/688] :memo: :art: Hard wrap --- docs/api/menu.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index f62cf0da5b1..529113509f8 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -227,7 +227,8 @@ Sends the `action` to the first responder of application. This is used for emulating default Cocoa menu behaviors, usually you would just use the `role` property of `MenuItem`. -See the [OS X Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7) for more information on OS X's native actions. +See the [OS X Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7) +for more information on OS X's native actions. ### `Menu.buildFromTemplate(template)` From dda7740399b08516da4eb3ce6a7a5f847090dd63 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 12:03:13 -0800 Subject: [PATCH 373/688] Add failing spec for native image path normalization --- spec/native-image-spec.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 spec/native-image-spec.js diff --git a/spec/native-image-spec.js b/spec/native-image-spec.js new file mode 100644 index 00000000000..bdc0a06b424 --- /dev/null +++ b/spec/native-image-spec.js @@ -0,0 +1,13 @@ +const assert = require('assert'); +const nativeImage = require('electron').nativeImage; +const path = require('path'); + +describe('nativeImage module', function () { + describe('createFromPath(path)', function () { + it('normalizes paths', function () { + const nonAbsolutePath = path.join(__dirname, 'fixtures', 'api') + path.sep + '..' + path.sep + path.join('assets', 'logo.png'); + const image = nativeImage.createFromPath(nonAbsolutePath); + assert(!image.isEmpty()); + }); + }); +}); From b90c0c78959b422e50dde8c72714b1f96219ef83 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 12:05:36 -0800 Subject: [PATCH 374/688] Use MakeAbsoluteFilePath when creating native image from path --- atom/common/api/atom_api_native_image.cc | 16 ++++++++++++---- spec/native-image-spec.js | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index a810069e71b..b229c4bb398 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -13,6 +13,7 @@ #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/node_includes.h" #include "base/base64.h" +#include "base/files/file_util.h" #include "base/strings/string_util.h" #include "base/strings/pattern.h" #include "native_mate/dictionary.h" @@ -254,17 +255,24 @@ mate::Handle NativeImage::CreateFromJPEG( mate::Handle NativeImage::CreateFromPath( v8::Isolate* isolate, const base::FilePath& path) { gfx::ImageSkia image_skia; - if (path.MatchesExtension(FILE_PATH_LITERAL(".ico"))) { + + base::FilePath absolute_path = MakeAbsoluteFilePath(path); + // MakeAbsoluteFilePath returns an empty path on failures + if (absolute_path.empty()) { + absolute_path = path; + } + + if (absolute_path.MatchesExtension(FILE_PATH_LITERAL(".ico"))) { #if defined(OS_WIN) - ReadImageSkiaFromICO(&image_skia, path); + ReadImageSkiaFromICO(&image_skia, absolute_path); #endif } else { - PopulateImageSkiaRepsFromPath(&image_skia, path); + PopulateImageSkiaRepsFromPath(&image_skia, absolute_path); } gfx::Image image(image_skia); mate::Handle handle = Create(isolate, image); #if defined(OS_MACOSX) - if (IsTemplateFilename(path)) + if (IsTemplateFilename(absolute_path)) handle->SetTemplateImage(true); #endif return handle; diff --git a/spec/native-image-spec.js b/spec/native-image-spec.js index bdc0a06b424..e72682a10a1 100644 --- a/spec/native-image-spec.js +++ b/spec/native-image-spec.js @@ -4,7 +4,7 @@ const path = require('path'); describe('nativeImage module', function () { describe('createFromPath(path)', function () { - it('normalizes paths', function () { + it('normalizes the path', function () { const nonAbsolutePath = path.join(__dirname, 'fixtures', 'api') + path.sep + '..' + path.sep + path.join('assets', 'logo.png'); const image = nativeImage.createFromPath(nonAbsolutePath); assert(!image.isEmpty()); From 145d5abe8007b55fe75403ebec4021199053f4f9 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 12:09:53 -0800 Subject: [PATCH 375/688] Mention explicit using original path on failures --- atom/common/api/atom_api_native_image.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index b229c4bb398..b1f0e9c5a6f 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -257,7 +257,7 @@ mate::Handle NativeImage::CreateFromPath( gfx::ImageSkia image_skia; base::FilePath absolute_path = MakeAbsoluteFilePath(path); - // MakeAbsoluteFilePath returns an empty path on failures + // MakeAbsoluteFilePath returns an empty path on failures so use original path if (absolute_path.empty()) { absolute_path = path; } From 8f820e09be43616ffd65ffc00cd43e6153b1a615 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 14:54:12 -0800 Subject: [PATCH 376/688] Use template string and arrow functions --- spec/native-image-spec.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/spec/native-image-spec.js b/spec/native-image-spec.js index e72682a10a1..88588eb1922 100644 --- a/spec/native-image-spec.js +++ b/spec/native-image-spec.js @@ -1,11 +1,13 @@ +'use strict'; + const assert = require('assert'); const nativeImage = require('electron').nativeImage; const path = require('path'); -describe('nativeImage module', function () { - describe('createFromPath(path)', function () { - it('normalizes the path', function () { - const nonAbsolutePath = path.join(__dirname, 'fixtures', 'api') + path.sep + '..' + path.sep + path.join('assets', 'logo.png'); +describe('nativeImage module', () => { + describe('createFromPath(path)', () => { + it('normalizes the path', () => { + const nonAbsolutePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; const image = nativeImage.createFromPath(nonAbsolutePath); assert(!image.isEmpty()); }); From 8215d661caee2b02f73a0b9a47024a953f7e0e8a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 4 Mar 2016 14:58:34 -0800 Subject: [PATCH 377/688] Add api- prefix to spec --- spec/{native-image-spec.js => api-native-image-spec.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spec/{native-image-spec.js => api-native-image-spec.js} (100%) diff --git a/spec/native-image-spec.js b/spec/api-native-image-spec.js similarity index 100% rename from spec/native-image-spec.js rename to spec/api-native-image-spec.js From 7692edf50ec4805fb362150180a1e6b5249d842e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 09:28:08 -0800 Subject: [PATCH 378/688] Assert image size as well --- spec/api-native-image-spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index 88588eb1922..688819cab1b 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -10,6 +10,8 @@ describe('nativeImage module', () => { const nonAbsolutePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; const image = nativeImage.createFromPath(nonAbsolutePath); assert(!image.isEmpty()); + assert.equal(image.getSize().height, 190); + assert.equal(image.getSize().width, 538); }); }); }); From 9c88a5c1ab8fb1537418cb5d2c705251d24b56c6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 09:35:35 -0800 Subject: [PATCH 379/688] Check ReferencesParent before calling MakeAbsoluteFilePath --- atom/common/api/atom_api_native_image.cc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index b1f0e9c5a6f..d26fdab8c60 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -120,6 +120,20 @@ bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image, return succeed; } +base::FilePath MakePathAbsolute(const base::FilePath& path) { + if (!path.ReferencesParent()) { + return path; + } + + base::FilePath absolute_path = MakeAbsoluteFilePath(path); + // MakeAbsoluteFilePath returns an empty path on failures so use original path + if (absolute_path.empty()) { + return path; + } else { + return absolute_path; + } +} + #if defined(OS_MACOSX) bool IsTemplateFilename(const base::FilePath& path) { return (base::MatchPattern(path.value(), "*Template.*") || @@ -255,12 +269,7 @@ mate::Handle NativeImage::CreateFromJPEG( mate::Handle NativeImage::CreateFromPath( v8::Isolate* isolate, const base::FilePath& path) { gfx::ImageSkia image_skia; - - base::FilePath absolute_path = MakeAbsoluteFilePath(path); - // MakeAbsoluteFilePath returns an empty path on failures so use original path - if (absolute_path.empty()) { - absolute_path = path; - } + base::FilePath absolute_path = MakePathAbsolute(path); if (absolute_path.MatchesExtension(FILE_PATH_LITERAL(".ico"))) { #if defined(OS_WIN) From 97930fcd84402674960b1a3503c5ea6df7012492 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 14:19:24 -0800 Subject: [PATCH 380/688] Add specs for more image path cases --- spec/api-native-image-spec.js | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index 688819cab1b..4b21231e406 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -6,9 +6,30 @@ const path = require('path'); describe('nativeImage module', () => { describe('createFromPath(path)', () => { - it('normalizes the path', () => { - const nonAbsolutePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; - const image = nativeImage.createFromPath(nonAbsolutePath); + it('returns an empty image for invalid paths', () => { + assert(nativeImage.createFromPath('').isEmpty()); + assert(nativeImage.createFromPath('does-not-exist.png').isEmpty()); + }); + + it('loads images from paths relative to the current working directory', () => { + const imagePath = `.${path.sep}${path.join('spec', 'fixtures', 'assets', 'logo.png')}`; + const image = nativeImage.createFromPath(imagePath); + assert(!image.isEmpty()); + assert.equal(image.getSize().height, 190); + assert.equal(image.getSize().width, 538); + }) + + it('loads images from paths with `.` segments', () => { + const imagePath = `${path.join(__dirname, 'fixtures')}${path.sep}.${path.sep}${path.join('assets', 'logo.png')}`; + const image = nativeImage.createFromPath(imagePath); + assert(!image.isEmpty()); + assert.equal(image.getSize().height, 190); + assert.equal(image.getSize().width, 538); + }); + + it('loads images from path with `..` segments', () => { + const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; + const image = nativeImage.createFromPath(imagePath); assert(!image.isEmpty()); assert.equal(image.getSize().height, 190); assert.equal(image.getSize().width, 538); From 0dba0b9cad445eae58bff85dcf3333622a8b4833 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 14:21:24 -0800 Subject: [PATCH 381/688] MakePathAbsolute -> NormalizePath --- atom/common/api/atom_api_native_image.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index d26fdab8c60..53f77bd41f8 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -120,7 +120,7 @@ bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image, return succeed; } -base::FilePath MakePathAbsolute(const base::FilePath& path) { +base::FilePath NormalizePath(const base::FilePath& path) { if (!path.ReferencesParent()) { return path; } @@ -269,7 +269,7 @@ mate::Handle NativeImage::CreateFromJPEG( mate::Handle NativeImage::CreateFromPath( v8::Isolate* isolate, const base::FilePath& path) { gfx::ImageSkia image_skia; - base::FilePath absolute_path = MakePathAbsolute(path); + base::FilePath absolute_path = NormalizePath(path); if (absolute_path.MatchesExtension(FILE_PATH_LITERAL(".ico"))) { #if defined(OS_WIN) From 022c2c0d8cb9a52d3939ec64180744632377a8b4 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 14:22:16 -0800 Subject: [PATCH 382/688] absolute_path -> normalize_path --- atom/common/api/atom_api_native_image.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 53f77bd41f8..3d000b6d5d9 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -269,19 +269,19 @@ mate::Handle NativeImage::CreateFromJPEG( mate::Handle NativeImage::CreateFromPath( v8::Isolate* isolate, const base::FilePath& path) { gfx::ImageSkia image_skia; - base::FilePath absolute_path = NormalizePath(path); + base::FilePath image_path = NormalizePath(path); - if (absolute_path.MatchesExtension(FILE_PATH_LITERAL(".ico"))) { + if (image_path.MatchesExtension(FILE_PATH_LITERAL(".ico"))) { #if defined(OS_WIN) - ReadImageSkiaFromICO(&image_skia, absolute_path); + ReadImageSkiaFromICO(&image_skia, image_path); #endif } else { - PopulateImageSkiaRepsFromPath(&image_skia, absolute_path); + PopulateImageSkiaRepsFromPath(&image_skia, image_path); } gfx::Image image(image_skia); mate::Handle handle = Create(isolate, image); #if defined(OS_MACOSX) - if (IsTemplateFilename(absolute_path)) + if (IsTemplateFilename(image_path)) handle->SetTemplateImage(true); #endif return handle; From 44376374b0010dcbe8830838fb4d8940e3d1ecf7 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 14:22:55 -0800 Subject: [PATCH 383/688] path -> paths --- spec/api-native-image-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index 4b21231e406..c2950c674b4 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -27,7 +27,7 @@ describe('nativeImage module', () => { assert.equal(image.getSize().width, 538); }); - it('loads images from path with `..` segments', () => { + it('loads images from paths with `..` segments', () => { const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; const image = nativeImage.createFromPath(imagePath); assert(!image.isEmpty()); From 4c23e3950a2b2d0ef5d311877ab078d1cdaa1548 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 16:45:10 -0800 Subject: [PATCH 384/688] Add missing semicolon --- spec/api-native-image-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index c2950c674b4..043a914578c 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -17,7 +17,7 @@ describe('nativeImage module', () => { assert(!image.isEmpty()); assert.equal(image.getSize().height, 190); assert.equal(image.getSize().width, 538); - }) + }); it('loads images from paths with `.` segments', () => { const imagePath = `${path.join(__dirname, 'fixtures')}${path.sep}.${path.sep}${path.join('assets', 'logo.png')}`; From 11f64b714da79cf959cfbe8a6270ddc7fc87bb34 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Tue, 8 Mar 2016 10:47:23 +0800 Subject: [PATCH 385/688] menuItem add --- docs-translations/zh-CN/api/menu-item.md | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 docs-translations/zh-CN/api/menu-item.md diff --git a/docs-translations/zh-CN/api/menu-item.md b/docs-translations/zh-CN/api/menu-item.md new file mode 100644 index 00000000000..3d5eceedcb9 --- /dev/null +++ b/docs-translations/zh-CN/api/menu-item.md @@ -0,0 +1,57 @@ +# 菜单项 +菜单项模块允许你向应用或[menu][1]添加选项。 + +查看[menu][1]例子。 + +## 类:MenuItem +使用下面的方法创建一个新的 `MenuItem` + +###new MenuItem(options) +* `options` Object + * `click` Function - 当菜单项被点击的时候,使用 `click(menuItem,browserWindow)` 调用 + * `role` String - 定义菜单项的行为,在指定 `click` 属性时将会被忽略 + * `type` String - 取值 `normal`,`separator`,`checkbox`or`radio` + * `label` String + * `sublabel` String + * `accelerator` [Accelerator][2] + * `icon` [NativeImage][3] + * `enabled` Boolean + * `visible` Boolean + * `checked` Boolean + * `submenu` Menu - 应当作为 `submenu` 菜单项的特定类型,当它作为 `type: 'submenu'` 菜单项的特定类型时可以忽略。如果它的值不是 `Menu`,将自动转为 `Menu.buildFromTemplate`。 + * `id` String - 标志一个菜单的唯一性。如果被定义使用,它将被用作这个菜单项的参考位置属性。 + * `position` String - 定义给定的菜单的具体指定位置信息。 + +在创建菜单项时,如果有匹配的方法,建议指定 `role` 属性,不需要人为操作它的行为,这样菜单使用可以给用户最好的体验。 + + +`role`属性值可以为: + +* `undo` +* `redo` +* `cut` +* `copy` +* `paste` +* `selectall` +* `minimize` - 最小化当前窗口 +* `close` - 关闭当前窗口 + +在 OS X 上,`role` 还可以有以下值: + +* `about` - 匹配 `orderFrontStandardAboutPanel` 行为 +* `hide` - 匹配 `hide` 行为 +* `hideothers` - 匹配 `hideOtherApplications` 行为 +* `unhide` - 匹配 `unhideAllApplications` 行为 +* `front` - 匹配 `arrangeInFront` 行为 +* `window` - "Window" 菜单项 +* `help` - "Help" 菜单项 +* `services` - "Services" 菜单项 + + + + + + + [1]:https://github.com/heyunjiang/electron/blob/master/docs-translations/zh-CN/api/menu.md + [2]:https://github.com/heyunjiang/electron/blob/master/docs/api/accelerator.md + [3]:https://github.com/heyunjiang/electron/blob/master/docs/api/native-image.md \ No newline at end of file From 0c92d440772ea36a521bfb8fb11d436b8f396c73 Mon Sep 17 00:00:00 2001 From: Dongjoon Hyun Date: Mon, 7 Mar 2016 20:22:03 -0800 Subject: [PATCH 386/688] Fix typos in comments. --- atom/browser/api/lib/menu.js | 2 +- atom/browser/atom_browser_main_parts.h | 2 +- atom/browser/ui/views/global_menu_bar_x11.h | 2 +- atom/common/crash_reporter/win/crash_service.cc | 2 +- .../chrome/browser/chrome_notification_types.h | 12 ++++++------ 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/atom/browser/api/lib/menu.js b/atom/browser/api/lib/menu.js index 62c771af6c6..5af577872db 100644 --- a/atom/browser/api/lib/menu.js +++ b/atom/browser/api/lib/menu.js @@ -7,7 +7,7 @@ const bindings = process.atomBinding('menu'); // Automatically generated radio menu item's group id. var nextGroupId = 0; -// Search between seperators to find a radio menu item and return its group id, +// Search between separators to find a radio menu item and return its group id, // otherwise generate a group id. var generateGroupId = function(items, pos) { var i, item, j, k, ref1, ref2, ref3; diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index c1c0c89c678..e1053a257b9 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -31,7 +31,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { static AtomBrowserMainParts* Get(); - // Sets the exit code, will fail if the the message loop is not ready. + // Sets the exit code, will fail if the message loop is not ready. bool SetExitCode(int code); // Gets the exit code diff --git a/atom/browser/ui/views/global_menu_bar_x11.h b/atom/browser/ui/views/global_menu_bar_x11.h index d9e818ce3eb..9049fbf606d 100644 --- a/atom/browser/ui/views/global_menu_bar_x11.h +++ b/atom/browser/ui/views/global_menu_bar_x11.h @@ -40,7 +40,7 @@ class GlobalMenuBarX11 { explicit GlobalMenuBarX11(NativeWindowViews* window); virtual ~GlobalMenuBarX11(); - // Creates the object path for DbusemenuServer which is attached to |xid|. + // Creates the object path for DbusmenuServer which is attached to |xid|. static std::string GetPathForWindow(gfx::AcceleratedWidget xid); void SetMenu(ui::MenuModel* menu_model); diff --git a/atom/common/crash_reporter/win/crash_service.cc b/atom/common/crash_reporter/win/crash_service.cc index 67e22381aef..b8032f696fc 100644 --- a/atom/common/crash_reporter/win/crash_service.cc +++ b/atom/common/crash_reporter/win/crash_service.cc @@ -211,7 +211,7 @@ bool CrashService::Initialize(const base::string16& application_name, std::wstring pipe_name = kTestPipeName; int max_reports = -1; - // The checkpoint file allows CrashReportSender to enforce the the maximum + // The checkpoint file allows CrashReportSender to enforce the maximum // reports per day quota. Does not seem to serve any other purpose. base::FilePath checkpoint_path = operating_dir.Append(kCheckPointFile); diff --git a/chromium_src/chrome/browser/chrome_notification_types.h b/chromium_src/chrome/browser/chrome_notification_types.h index eb5ed40342d..05df960c5ea 100644 --- a/chromium_src/chrome/browser/chrome_notification_types.h +++ b/chromium_src/chrome/browser/chrome_notification_types.h @@ -32,7 +32,7 @@ enum NotificationType { NOTIFICATION_BROWSER_CLOSING, // This message is sent after a window has been closed. The source is a - // Source containing the affected Browser. No details are exptected. + // Source containing the affected Browser. No details are expected. NOTIFICATION_BROWSER_CLOSED, // This message is sent when closing a browser has been cancelled, either by @@ -411,7 +411,7 @@ enum NotificationType { // the source is a Profile. NOTIFICATION_EXTENSION_LOADED_DEPRECATED, - // An error occured while attempting to load an extension. The details are a + // An error occurred while attempting to load an extension. The details are a // string with details about why the load failed. NOTIFICATION_EXTENSION_LOAD_ERROR, @@ -434,7 +434,7 @@ enum NotificationType { // The details are an InstalledExtensionInfo, and the source is a Profile. NOTIFICATION_EXTENSION_INSTALLED, - // An error occured during extension install. The details are a string with + // An error occurred during extension install. The details are a string with // details about why the install failed. NOTIFICATION_EXTENSION_INSTALL_ERROR, @@ -625,7 +625,7 @@ enum NotificationType { // TabSpecificContentSettings object, there are no details. NOTIFICATION_COLLECTED_COOKIES_SHOWN, - // Sent when a non-default setting in the the notification content settings + // Sent when a non-default setting in the notification content settings // map has changed. The source is the DesktopNotificationService, the // details are None. NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED, @@ -776,7 +776,7 @@ enum NotificationType { NOTIFICATION_USER_LIST_CHANGED, // Sent when the screen lock state has changed. The source is - // ScreenLocker and the details is a bool specifing that the + // ScreenLocker and the details is a bool specifying that the // screen is locked. When details is a false, the source object // is being deleted, so the receiver shouldn't use the screen locker // object. @@ -838,7 +838,7 @@ enum NotificationType { // which was installed. NOTIFICATION_APP_INSTALLED_TO_NTP, - // Similar to NOTIFICATION_APP_INSTALLED_TO_NTP but used to nofity ash AppList + // Similar to NOTIFICATION_APP_INSTALLED_TO_NTP but used to notify ash AppList // about installed app. Source is the profile in which the app is installed // and Details is the string ID of the extension. NOTIFICATION_APP_INSTALLED_TO_APPLIST, From 89328c873c6ce6ee379e6cdf69ab064c88aa9373 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Tue, 8 Mar 2016 16:30:09 +0800 Subject: [PATCH 387/688] add api doc begin 2.5 --- docs-translations/zh-CN/api/synopsis.md | 71 ++++++++ .../tutorial/chrome-command-line-switches.md | 158 ++++++++++++++++++ docs-translations/zh-CN/tutorial/process.md | 48 ++++++ 3 files changed, 277 insertions(+) create mode 100644 docs-translations/zh-CN/api/synopsis.md create mode 100644 docs-translations/zh-CN/tutorial/chrome-command-line-switches.md create mode 100644 docs-translations/zh-CN/tutorial/process.md diff --git a/docs-translations/zh-CN/api/synopsis.md b/docs-translations/zh-CN/api/synopsis.md new file mode 100644 index 00000000000..a1a2a6d0122 --- /dev/null +++ b/docs-translations/zh-CN/api/synopsis.md @@ -0,0 +1,71 @@ +# 简介 + +所有的[Node.js's built-in modules][1]在Electron中都可用,并且所有的node的第三方组件也可以放心使用(包括[自身的模块][2])。 + +Electron也提供了一些额外的内置组件来开发传统桌面应用。一些组件只可以在主进程中使用,一些只可以在渲染进程中使用,但是也有部分可以在这2种进程中都可使用。 + +基本规则:GUI模块或者系统底层的模块只可以在主进程中使用。要使用这些模块,你应当很熟悉[主进程vs渲染进程][3]脚本的概念。 + +主进程脚本看起来像个普通的nodejs脚本 + +```javascript +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; + +var window = null; + +app.on('ready', function() { + window = new BrowserWindow({width: 800, height: 600}); + window.loadURL('https://github.com'); +}); +``` + +渲染进程和传统的web界面一样,除了它具有使用node模块的能力: + +```html + + + + + + +``` + +如果想运行应用,参考 `Run your app` 。 + +## 解构任务 + +如果你使用的是CoffeeScript或Babel,你可以使用[destructuring assignment][4]来让使用内置模块更简单: + +```javascript +const {app, BrowserWindow} = require('electron'); +``` + +然而如果你使用的是普通的JavaScript,你就需要等到Chrome支持ES6了。 + +##使用内置模块时禁用旧样式 + +在版本v0.35.0之前,所有的内置模块都需要按造 `require('module-name')` 形式来使用,虽然它有很多[弊端][5],我们仍然在老的应用中友好的支持它。 + +为了完整的禁用旧样式,你可以设置环境变量 `ELECTRON_HIDE_INTERNAL_MODULES ` : + +```javascript +process.env.ELECTRON_HIDE_INTERNAL_MODULES = 'true' +``` + +或者调用 `hideInternalModules` API: + +```javascript +require('electron').hideInternalModules() +``` + + + [1]:http://nodejs.org/api/ + [2]:https://github.com/heyunjiang/electron/blob/master/docs/tutorial/using-native-node-modules.md + [3]:https://github.com/heyunjiang/electron/blob/master/docs/tutorial/quick-start.md#the-main-process + [4]:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment + [5]:https://github.com/atom/electron/issues/387 \ No newline at end of file diff --git a/docs-translations/zh-CN/tutorial/chrome-command-line-switches.md b/docs-translations/zh-CN/tutorial/chrome-command-line-switches.md new file mode 100644 index 00000000000..14e4a431bcc --- /dev/null +++ b/docs-translations/zh-CN/tutorial/chrome-command-line-switches.md @@ -0,0 +1,158 @@ +# 支持的 Chrome 命令行开关 + +这页列出了Chrome浏览器和Electron支持的命令行开关. 你也可以在[app][app]模块的[ready][ready]事件发出之前使用[app.commandLine.appendSwitch][append-switch] 来添加它们到你应用的main脚本里面: + +```javascript +const app = require('electron').app; +app.commandLine.appendSwitch('remote-debugging-port', '8315'); +app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1'); + +app.on('ready', function() { + // Your code here +}); +``` + +## --client-certificate=`path` + +设置客户端的证书文件 `path` . + +## --ignore-connections-limit=`domains` + +忽略用 `,` 分隔的 `domains` 列表的连接限制. + +## --disable-http-cache + +禁用 HTTP 请求的 磁盘缓存. + +## --remote-debugging-port=`port` + +在指定的 `端口` 通过 HTTP 开启远程调试. + +## --js-flags=`flags` + +Specifies the flags passed to JS engine. It has to be passed when starting +Electron if you want to enable the `flags` in the main process. + +```bash +$ electron --js-flags="--harmony_proxies --harmony_collections" your-app +``` + +## --proxy-server=`address:port` + +Use a specified proxy server, which overrides the system setting. This switch +only affects requests with HTTP protocol, including HTTPS and WebSocket +requests. It is also noteworthy that not all proxy servers support HTTPS and +WebSocket requests. + +## --proxy-bypass-list=`hosts` + +Instructs Electron to bypass the proxy server for the given semi-colon-separated +list of hosts. This flag has an effect only if used in tandem with +`--proxy-server`. + +For example: + +```javascript +app.commandLine.appendSwitch('proxy-bypass-list', ';*.google.com;*foo.com;1.2.3.4:5678') +``` + +Will use the proxy server for all hosts except for local addresses (`localhost`, +`127.0.0.1` etc.), `google.com` subdomains, hosts that contain the suffix +`foo.com` and anything at `1.2.3.4:5678`. + +## --proxy-pac-url=`url` + +Uses the PAC script at the specified `url`. + +## --no-proxy-server + +Don't use a proxy server and always make direct connections. Overrides any other +proxy server flags that are passed. + +## --host-rules=`rules` + +A comma-separated list of `rules` that control how hostnames are mapped. + +For example: + +* `MAP * 127.0.0.1` Forces all hostnames to be mapped to 127.0.0.1 +* `MAP *.google.com proxy` Forces all google.com subdomains to be resolved to + "proxy". +* `MAP test.com [::1]:77` Forces "test.com" to resolve to IPv6 loopback. Will + also force the port of the resulting socket address to be 77. +* `MAP * baz, EXCLUDE www.google.com` Remaps everything to "baz", except for + "www.google.com". + +These mappings apply to the endpoint host in a net request (the TCP connect +and host resolver in a direct connection, and the `CONNECT` in an HTTP proxy +connection, and the endpoint host in a `SOCKS` proxy connection). + +## --host-resolver-rules=`rules` + +Like `--host-rules` but these `rules` only apply to the host resolver. + +## --ignore-certificate-errors + +Ignores certificate related errors. + +## --ppapi-flash-path=`path` + +Sets the `path` of the pepper flash plugin. + +## --ppapi-flash-version=`version` + +Sets the `version` of the pepper flash plugin. + +## --log-net-log=`path` + +Enables net log events to be saved and writes them to `path`. + +## --ssl-version-fallback-min=`version` + +Sets the minimum SSL/TLS version ("tls1", "tls1.1" or "tls1.2") that TLS +fallback will accept. + +## --cipher-suite-blacklist=`cipher_suites` + +Specifies comma-separated list of SSL cipher suites to disable. + +## --disable-renderer-backgrounding + +Prevents Chromium from lowering the priority of invisible pages' renderer +processes. + +This flag is global to all renderer processes, if you only want to disable +throttling in one window, you can take the hack of +[playing silent audio][play-silent-audio]. + +## --enable-logging + +Prints Chromium's logging into console. + +This switch can not be used in `app.commandLine.appendSwitch` since it is parsed +earlier than user's app is loaded, but you can set the `ELECTRON_ENABLE_LOGGING` +environment variable to achieve the same effect. + +## --v=`log_level` + +Gives the default maximal active V-logging level; 0 is the default. Normally +positive values are used for V-logging levels. + +This switch only works when `--enable-logging` is also passed. + +## --vmodule=`pattern` + +Gives the per-module maximal V-logging levels to override the value given by +`--v`. E.g. `my_module=2,foo*=3` would change the logging level for all code in +source files `my_module.*` and `foo*.*`. + +Any pattern containing a forward or backward slash will be tested against the +whole pathname and not just the module. E.g. `*/foo/bar/*=2` would change the +logging level for all code in the source files under a `foo/bar` directory. + +This switch only works when `--enable-logging` is also passed. + +[app]: app.md +[append-switch]: app.md#appcommandlineappendswitchswitch-value +[ready]: app.md#event-ready +[play-silent-audio]: https://github.com/atom/atom/pull/9485/files \ No newline at end of file diff --git a/docs-translations/zh-CN/tutorial/process.md b/docs-translations/zh-CN/tutorial/process.md new file mode 100644 index 00000000000..d07741247aa --- /dev/null +++ b/docs-translations/zh-CN/tutorial/process.md @@ -0,0 +1,48 @@ +# 进程 + +Electron 中的 `process` 对象 与 upstream node 中的有以下的不同点: + +* `process.type` String - 进程类型, 可以是 `browser` (i.e. main process) + 或 `renderer`. +* `process.versions['electron']` String - Electron的版本. +* `process.versions['chrome']` String - Chromium的版本. +* `process.resourcesPath` String - JavaScript源代码路径. +* `process.mas` Boolean - 在Mac App Store 创建, 它的值为 `true`, 在其它的地方值为 `undefined`. + +## 事件 + +### 事件: 'loaded' + +在Electron已经加载了其内部预置脚本和它准备加载主进程或渲染进程的时候触发. + +当node被完全关闭的时候,它可以被预加载脚本使用来添加(原文: removed)与node无关的全局符号来回退到全局范围: + +```js +// preload.js +var _setImmediate = setImmediate; +var _clearImmediate = clearImmediate; +process.once('loaded', function() { + global.setImmediate = _setImmediate; + global.clearImmediate = _clearImmediate; +}); +``` + +## 属性 + +### `process.noAsar` + +设置它为 `true` 可以使 `asar` 文件在node的内置模块中实效. + +## 方法 + +`process` 对象有如下方法: + +### `process.hang()` + +使当前进程的主线成挂起. + +### `process.setFdLimit(maxDescriptors)` _OS X_ _Linux_ + +* `maxDescriptors` Integer + +设置文件描述符软限制于 `maxDescriptors` 或硬限制与os, 无论它是否低于当前进程. \ No newline at end of file From d35996b4a0cfe5388f879f47110d80f235505690 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Tue, 8 Mar 2016 19:57:53 +0800 Subject: [PATCH 388/688] position modify --- .../zh-CN/api/chrome-command-line-switches.md | 144 ++++++++++++++++ .../zh-CN/{tutorial => api}/process.md | 0 .../tutorial/chrome-command-line-switches.md | 158 ------------------ 3 files changed, 144 insertions(+), 158 deletions(-) create mode 100644 docs-translations/zh-CN/api/chrome-command-line-switches.md rename docs-translations/zh-CN/{tutorial => api}/process.md (100%) delete mode 100644 docs-translations/zh-CN/tutorial/chrome-command-line-switches.md diff --git a/docs-translations/zh-CN/api/chrome-command-line-switches.md b/docs-translations/zh-CN/api/chrome-command-line-switches.md new file mode 100644 index 00000000000..234f3c63b1e --- /dev/null +++ b/docs-translations/zh-CN/api/chrome-command-line-switches.md @@ -0,0 +1,144 @@ +# 支持的 Chrome 命令行开关 + +这页列出了Chrome浏览器和Electron支持的命令行开关. 你也可以在[app][app]模块的[ready][ready]事件发出之前使用[app.commandLine.appendSwitch][append-switch] 来添加它们到你应用的main脚本里面: + +```javascript +const app = require('electron').app; +app.commandLine.appendSwitch('remote-debugging-port', '8315'); +app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1'); + +app.on('ready', function() { + // Your code here +}); +``` + +## --client-certificate=`path` + +设置客户端的证书文件 `path` . + +## --ignore-connections-limit=`domains` + +忽略用 `,` 分隔的 `domains` 列表的连接限制. + +## --disable-http-cache + +禁用 HTTP 请求. + +## --remote-debugging-port=`port` + +在指定的 `端口` 通过 HTTP 开启远程调试. + +## --js-flags=`flags` + +指定引擎过渡到 JS 引擎. + +在启动Electron时,如果你想在主进程中激活 `flags` ,它将被转换. + +```bash +$ electron --js-flags="--harmony_proxies --harmony_collections" your-app +``` + +## --proxy-server=`address:port` + +使用一个特定的代理服务器,它将比系统设置的优先级更高.这个开关只有在使用 HTTP 协议时有效,它包含 HTTPS 和 WebSocket 请求. 值得注意的是,不是所有的代理服务器都支持 HTTPS 和 WebSocket 请求. + +## --proxy-bypass-list=`hosts` + +让 Electron 使用(原文:bypass) 提供的以 semi-colon 分隔的hosts列表的代理服务器.这个开关只有在使用 `--proxy-server` 时有效. + +例如: + +```javascript +app.commandLine.appendSwitch('proxy-bypass-list', ';*.google.com;*foo.com;1.2.3.4:5678') +``` + + +将会为所有的hosts使用代理服务器,除了本地地址 (`localhost`, +`127.0.0.1` etc.), `google.com` 子域, 以 `foo.com` 结尾的hosts,和所有类似 `1.2.3.4:5678`的. + +## --proxy-pac-url=`url` + +在指定的 `url` 上使用 PAC 脚本. + +## --no-proxy-server + +不使用代理服务并且总是使用直接连接.忽略所有的合理代理标志. + +## --host-rules=`rules` + +一个逗号分隔的 `rule` 列表来控制主机名如何映射. + +例如: + +* `MAP * 127.0.0.1` 强制所有主机名映射到 127.0.0.1 +* `MAP *.google.com proxy` 强制所有 google.com 子域 使用 "proxy". +* `MAP test.com [::1]:77` 强制 "test.com" 使用 IPv6 回环地址. 也强制使用端口 77. +* `MAP * baz, EXCLUDE www.google.com` 重新全部映射到 "baz", 除了 + "www.google.com". + +这些映射适用于终端网络请求 +(TCP 连接 +和 主机解析 以直接连接的方式, 和 `CONNECT` 以代理连接, 还有 终端 host 使用 `SOCKS` 代理连接). + +## --host-resolver-rules=`rules` + +类似 `--host-rules` ,但是 `rules` 只适合主机解析. + +## --ignore-certificate-errors + +忽略与证书相关的错误. + +## --ppapi-flash-path=`path` + +设置Pepper Flash插件的路径 `path` . + +## --ppapi-flash-version=`version` + +设置Pepper Flash插件版本号. + +## --log-net-log=`path` + +使网络日志事件能够被读写到 `path`. + +## --ssl-version-fallback-min=`version` + +设置最简化的 SSL/TLS 版本号 ("tls1", "tls1.1" or "tls1.2"),TLS 可接受回退. + +## --cipher-suite-blacklist=`cipher_suites` + +指定逗号分隔的 SSL 密码套件 列表实效. + +## --disable-renderer-backgrounding + +防止 Chromium 降低隐藏的渲染进程优先级. + +这个标志对所有渲染进程全局有效,如果你只想在一个窗口中禁止使用,你可以采用 hack 方法[playing silent audio][play-silent-audio]. + +## --enable-logging + +打印 Chromium 信息输出到控制台. + +如果在用户应用加载完成之前解析`app.commandLine.appendSwitch` ,这个开关将实效,但是你可以设置 `ELECTRON_ENABLE_LOGGING` 环境变量来达到相同的效果. + +## --v=`log_level` + +设置默认最大活跃 V-logging 标准; 默认为 0.通常 V-logging 标准值为肯定值. + +This switch only works when `--enable-logging` is also passed. + +## --vmodule=`pattern` + +Gives the per-module maximal V-logging levels to override the value given by +`--v`. E.g. `my_module=2,foo*=3` would change the logging level for all code in +source files `my_module.*` and `foo*.*`. + +Any pattern containing a forward or backward slash will be tested against the +whole pathname and not just the module. E.g. `*/foo/bar/*=2` would change the +logging level for all code in the source files under a `foo/bar` directory. + +This switch only works when `--enable-logging` is also passed. + +[app]: app.md +[append-switch]: app.md#appcommandlineappendswitchswitch-value +[ready]: app.md#event-ready +[play-silent-audio]: https://github.com/atom/atom/pull/9485/files \ No newline at end of file diff --git a/docs-translations/zh-CN/tutorial/process.md b/docs-translations/zh-CN/api/process.md similarity index 100% rename from docs-translations/zh-CN/tutorial/process.md rename to docs-translations/zh-CN/api/process.md diff --git a/docs-translations/zh-CN/tutorial/chrome-command-line-switches.md b/docs-translations/zh-CN/tutorial/chrome-command-line-switches.md deleted file mode 100644 index 14e4a431bcc..00000000000 --- a/docs-translations/zh-CN/tutorial/chrome-command-line-switches.md +++ /dev/null @@ -1,158 +0,0 @@ -# 支持的 Chrome 命令行开关 - -这页列出了Chrome浏览器和Electron支持的命令行开关. 你也可以在[app][app]模块的[ready][ready]事件发出之前使用[app.commandLine.appendSwitch][append-switch] 来添加它们到你应用的main脚本里面: - -```javascript -const app = require('electron').app; -app.commandLine.appendSwitch('remote-debugging-port', '8315'); -app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1'); - -app.on('ready', function() { - // Your code here -}); -``` - -## --client-certificate=`path` - -设置客户端的证书文件 `path` . - -## --ignore-connections-limit=`domains` - -忽略用 `,` 分隔的 `domains` 列表的连接限制. - -## --disable-http-cache - -禁用 HTTP 请求的 磁盘缓存. - -## --remote-debugging-port=`port` - -在指定的 `端口` 通过 HTTP 开启远程调试. - -## --js-flags=`flags` - -Specifies the flags passed to JS engine. It has to be passed when starting -Electron if you want to enable the `flags` in the main process. - -```bash -$ electron --js-flags="--harmony_proxies --harmony_collections" your-app -``` - -## --proxy-server=`address:port` - -Use a specified proxy server, which overrides the system setting. This switch -only affects requests with HTTP protocol, including HTTPS and WebSocket -requests. It is also noteworthy that not all proxy servers support HTTPS and -WebSocket requests. - -## --proxy-bypass-list=`hosts` - -Instructs Electron to bypass the proxy server for the given semi-colon-separated -list of hosts. This flag has an effect only if used in tandem with -`--proxy-server`. - -For example: - -```javascript -app.commandLine.appendSwitch('proxy-bypass-list', ';*.google.com;*foo.com;1.2.3.4:5678') -``` - -Will use the proxy server for all hosts except for local addresses (`localhost`, -`127.0.0.1` etc.), `google.com` subdomains, hosts that contain the suffix -`foo.com` and anything at `1.2.3.4:5678`. - -## --proxy-pac-url=`url` - -Uses the PAC script at the specified `url`. - -## --no-proxy-server - -Don't use a proxy server and always make direct connections. Overrides any other -proxy server flags that are passed. - -## --host-rules=`rules` - -A comma-separated list of `rules` that control how hostnames are mapped. - -For example: - -* `MAP * 127.0.0.1` Forces all hostnames to be mapped to 127.0.0.1 -* `MAP *.google.com proxy` Forces all google.com subdomains to be resolved to - "proxy". -* `MAP test.com [::1]:77` Forces "test.com" to resolve to IPv6 loopback. Will - also force the port of the resulting socket address to be 77. -* `MAP * baz, EXCLUDE www.google.com` Remaps everything to "baz", except for - "www.google.com". - -These mappings apply to the endpoint host in a net request (the TCP connect -and host resolver in a direct connection, and the `CONNECT` in an HTTP proxy -connection, and the endpoint host in a `SOCKS` proxy connection). - -## --host-resolver-rules=`rules` - -Like `--host-rules` but these `rules` only apply to the host resolver. - -## --ignore-certificate-errors - -Ignores certificate related errors. - -## --ppapi-flash-path=`path` - -Sets the `path` of the pepper flash plugin. - -## --ppapi-flash-version=`version` - -Sets the `version` of the pepper flash plugin. - -## --log-net-log=`path` - -Enables net log events to be saved and writes them to `path`. - -## --ssl-version-fallback-min=`version` - -Sets the minimum SSL/TLS version ("tls1", "tls1.1" or "tls1.2") that TLS -fallback will accept. - -## --cipher-suite-blacklist=`cipher_suites` - -Specifies comma-separated list of SSL cipher suites to disable. - -## --disable-renderer-backgrounding - -Prevents Chromium from lowering the priority of invisible pages' renderer -processes. - -This flag is global to all renderer processes, if you only want to disable -throttling in one window, you can take the hack of -[playing silent audio][play-silent-audio]. - -## --enable-logging - -Prints Chromium's logging into console. - -This switch can not be used in `app.commandLine.appendSwitch` since it is parsed -earlier than user's app is loaded, but you can set the `ELECTRON_ENABLE_LOGGING` -environment variable to achieve the same effect. - -## --v=`log_level` - -Gives the default maximal active V-logging level; 0 is the default. Normally -positive values are used for V-logging levels. - -This switch only works when `--enable-logging` is also passed. - -## --vmodule=`pattern` - -Gives the per-module maximal V-logging levels to override the value given by -`--v`. E.g. `my_module=2,foo*=3` would change the logging level for all code in -source files `my_module.*` and `foo*.*`. - -Any pattern containing a forward or backward slash will be tested against the -whole pathname and not just the module. E.g. `*/foo/bar/*=2` would change the -logging level for all code in the source files under a `foo/bar` directory. - -This switch only works when `--enable-logging` is also passed. - -[app]: app.md -[append-switch]: app.md#appcommandlineappendswitchswitch-value -[ready]: app.md#event-ready -[play-silent-audio]: https://github.com/atom/atom/pull/9485/files \ No newline at end of file From c8a2246952eb25eac7aaad43af862cc3303bb9d9 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Tue, 8 Mar 2016 20:40:54 +0800 Subject: [PATCH 389/688] complete command line switch && add enviroment variables --- .../zh-CN/api/chrome-command-line-switches.md | 12 ++--- .../zh-CN/api/environment-variables.md | 53 +++++++++++++++++++ 2 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 docs-translations/zh-CN/api/environment-variables.md diff --git a/docs-translations/zh-CN/api/chrome-command-line-switches.md b/docs-translations/zh-CN/api/chrome-command-line-switches.md index 234f3c63b1e..e197626302b 100644 --- a/docs-translations/zh-CN/api/chrome-command-line-switches.md +++ b/docs-translations/zh-CN/api/chrome-command-line-switches.md @@ -124,19 +124,15 @@ app.commandLine.appendSwitch('proxy-bypass-list', ';*.google.com;*foo.com 设置默认最大活跃 V-logging 标准; 默认为 0.通常 V-logging 标准值为肯定值. -This switch only works when `--enable-logging` is also passed. +这个开关只有在 `--enable-logging` 开启时有效. ## --vmodule=`pattern` -Gives the per-module maximal V-logging levels to override the value given by -`--v`. E.g. `my_module=2,foo*=3` would change the logging level for all code in -source files `my_module.*` and `foo*.*`. +赋予每个模块最大的 V-logging levels 来覆盖 `--v` 给的值.E.g. `my_module=2,foo*=3` 会改变所有源文件 `my_module.*` and `foo*.*` 的代码中的 logging level . -Any pattern containing a forward or backward slash will be tested against the -whole pathname and not just the module. E.g. `*/foo/bar/*=2` would change the -logging level for all code in the source files under a `foo/bar` directory. +任何包含向前的(forward slash)或者向后的(backward slash)模式将被测试用于阻止整个路径名,并且不仅是E.g模块.`*/foo/bar/*=2` 将会改变所有在 `foo/bar` 下的源文件代码中的 logging level . -This switch only works when `--enable-logging` is also passed. +这个开关只有在 `--enable-logging` 开启时有效. [app]: app.md [append-switch]: app.md#appcommandlineappendswitchswitch-value diff --git a/docs-translations/zh-CN/api/environment-variables.md b/docs-translations/zh-CN/api/environment-variables.md new file mode 100644 index 00000000000..0a35eb59dfd --- /dev/null +++ b/docs-translations/zh-CN/api/environment-variables.md @@ -0,0 +1,53 @@ +# 环境变量 + +一些 Electron 的行为受到环境变量的控制,因为他们的初始化比命令行和应用代码更早. + +POSIX shells 的例子: + +```bash +$ export ELECTRON_ENABLE_LOGGING=true +$ electron +``` + +Windows 控制台: + +```powershell +> set ELECTRON_ENABLE_LOGGING=true +> electron +``` + +## `ELECTRON_RUN_AS_NODE` + +类似node.js普通进程启动方式. + +## `ELECTRON_ENABLE_LOGGING` + +打印 Chrome 的内部日志到控制台. + +## `ELECTRON_LOG_ASAR_READS` + +当 Electron 读取 ASA 文档,把 read offset 和文档路径做日志记录到系统 `tmpdir`.结果文件将提供给 ASAR 模块来优化文档组织. + +## `ELECTRON_ENABLE_STACK_DUMPING` + +当 Electron 崩溃的时候,打印堆栈记录到控制台. + +如果 `crashReporter` 已经启动那么这个环境变量实效. + +## `ELECTRON_DEFAULT_ERROR_MODE` _Windows_ + +当 Electron 崩溃的时候,显示windows的崩溃对话框. + +如果 `crashReporter` 已经启动那么这个环境变量实效. + +## `ELECTRON_NO_ATTACH_CONSOLE` _Windows_ + +不可使用当前控制台. + +## `ELECTRON_FORCE_WINDOW_MENU_BAR` _Linux_ + +不可再 Linux 上使用全局菜单栏. + +## `ELECTRON_HIDE_INTERNAL_MODULES` + +关闭旧的内置模块如 `require('ipc')` 的通用模块. \ No newline at end of file From 70aa9b06eef549ea66f6b9242043c7be81f0d9d0 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 17:12:09 -0800 Subject: [PATCH 390/688] Move JavaScript to root lib/ folder --- {atom/browser/api/lib => lib/browser/api}/app.js | 0 {atom/browser/api/lib => lib/browser/api}/auto-updater.js | 0 .../lib => lib/browser/api}/auto-updater/auto-updater-native.js | 0 .../api/lib => lib/browser/api}/auto-updater/auto-updater-win.js | 0 .../lib => lib/browser/api}/auto-updater/squirrel-update-win.js | 0 {atom/browser/api/lib => lib/browser/api}/browser-window.js | 0 {atom/browser/api/lib => lib/browser/api}/content-tracing.js | 0 {atom/browser/api/lib => lib/browser/api}/dialog.js | 0 {atom/browser/api/lib => lib/browser/api}/exports/electron.js | 0 {atom/browser/api/lib => lib/browser/api}/global-shortcut.js | 0 {atom/browser/api/lib => lib/browser/api}/ipc-main.js | 0 {atom/browser/api/lib => lib/browser/api}/ipc.js | 0 {atom/browser/api/lib => lib/browser/api}/menu-item.js | 0 {atom/browser/api/lib => lib/browser/api}/menu.js | 0 .../browser/api/lib => lib/browser/api}/navigation-controller.js | 0 {atom/browser/api/lib => lib/browser/api}/power-monitor.js | 0 {atom/browser/api/lib => lib/browser/api}/power-save-blocker.js | 0 {atom/browser/api/lib => lib/browser/api}/protocol.js | 0 {atom/browser/api/lib => lib/browser/api}/screen.js | 0 {atom/browser/api/lib => lib/browser/api}/session.js | 0 {atom/browser/api/lib => lib/browser/api}/tray.js | 0 {atom/browser/api/lib => lib/browser/api}/web-contents.js | 0 {atom/browser/lib => lib/browser}/chrome-extension.js | 0 {atom/browser/lib => lib/browser}/desktop-capturer.js | 0 {atom/browser/lib => lib/browser}/guest-view-manager.js | 0 {atom/browser/lib => lib/browser}/guest-window-manager.js | 0 {atom/browser/lib => lib/browser}/init.js | 0 {atom/browser/lib => lib/browser}/objects-registry.js | 0 {atom/browser/lib => lib/browser}/rpc-server.js | 0 {atom/common/api/lib => lib/common/api}/callbacks-registry.js | 0 {atom/common/api/lib => lib/common/api}/clipboard.js | 0 {atom/common/api/lib => lib/common/api}/crash-reporter.js | 0 {atom/common/api/lib => lib/common/api}/deprecate.js | 0 {atom/common/api/lib => lib/common/api}/deprecations.js | 0 {atom/common/api/lib => lib/common/api}/exports/electron.js | 0 {atom/common/api/lib => lib/common/api}/native-image.js | 0 {atom/common/api/lib => lib/common/api}/shell.js | 0 {atom/common/lib => lib/common}/asar.js | 0 {atom/common/lib => lib/common}/asar_init.js | 0 {atom/common/lib => lib/common}/init.js | 0 {atom/common/lib => lib/common}/reset-search-paths.js | 0 {atom/renderer/api/lib => lib/renderer/api}/desktop-capturer.js | 0 {atom/renderer/api/lib => lib/renderer/api}/exports/electron.js | 0 {atom/renderer/api/lib => lib/renderer/api}/ipc-renderer.js | 0 {atom/renderer/api/lib => lib/renderer/api}/ipc.js | 0 {atom/renderer/api/lib => lib/renderer/api}/remote.js | 0 {atom/renderer/api/lib => lib/renderer/api}/screen.js | 0 {atom/renderer/api/lib => lib/renderer/api}/web-frame.js | 0 {atom/renderer/lib => lib/renderer}/chrome-api.js | 0 {atom/renderer/lib => lib/renderer}/init.js | 0 {atom/renderer/lib => lib/renderer}/inspector.js | 0 {atom/renderer/lib => lib/renderer}/override.js | 0 .../renderer/lib => lib/renderer}/web-view/guest-view-internal.js | 0 .../renderer/lib => lib/renderer}/web-view/web-view-attributes.js | 0 .../renderer/lib => lib/renderer}/web-view/web-view-constants.js | 0 {atom/renderer/lib => lib/renderer}/web-view/web-view.js | 0 56 files changed, 0 insertions(+), 0 deletions(-) rename {atom/browser/api/lib => lib/browser/api}/app.js (100%) rename {atom/browser/api/lib => lib/browser/api}/auto-updater.js (100%) rename {atom/browser/api/lib => lib/browser/api}/auto-updater/auto-updater-native.js (100%) rename {atom/browser/api/lib => lib/browser/api}/auto-updater/auto-updater-win.js (100%) rename {atom/browser/api/lib => lib/browser/api}/auto-updater/squirrel-update-win.js (100%) rename {atom/browser/api/lib => lib/browser/api}/browser-window.js (100%) rename {atom/browser/api/lib => lib/browser/api}/content-tracing.js (100%) rename {atom/browser/api/lib => lib/browser/api}/dialog.js (100%) rename {atom/browser/api/lib => lib/browser/api}/exports/electron.js (100%) rename {atom/browser/api/lib => lib/browser/api}/global-shortcut.js (100%) rename {atom/browser/api/lib => lib/browser/api}/ipc-main.js (100%) rename {atom/browser/api/lib => lib/browser/api}/ipc.js (100%) rename {atom/browser/api/lib => lib/browser/api}/menu-item.js (100%) rename {atom/browser/api/lib => lib/browser/api}/menu.js (100%) rename {atom/browser/api/lib => lib/browser/api}/navigation-controller.js (100%) rename {atom/browser/api/lib => lib/browser/api}/power-monitor.js (100%) rename {atom/browser/api/lib => lib/browser/api}/power-save-blocker.js (100%) rename {atom/browser/api/lib => lib/browser/api}/protocol.js (100%) rename {atom/browser/api/lib => lib/browser/api}/screen.js (100%) rename {atom/browser/api/lib => lib/browser/api}/session.js (100%) rename {atom/browser/api/lib => lib/browser/api}/tray.js (100%) rename {atom/browser/api/lib => lib/browser/api}/web-contents.js (100%) rename {atom/browser/lib => lib/browser}/chrome-extension.js (100%) rename {atom/browser/lib => lib/browser}/desktop-capturer.js (100%) rename {atom/browser/lib => lib/browser}/guest-view-manager.js (100%) rename {atom/browser/lib => lib/browser}/guest-window-manager.js (100%) rename {atom/browser/lib => lib/browser}/init.js (100%) rename {atom/browser/lib => lib/browser}/objects-registry.js (100%) rename {atom/browser/lib => lib/browser}/rpc-server.js (100%) rename {atom/common/api/lib => lib/common/api}/callbacks-registry.js (100%) rename {atom/common/api/lib => lib/common/api}/clipboard.js (100%) rename {atom/common/api/lib => lib/common/api}/crash-reporter.js (100%) rename {atom/common/api/lib => lib/common/api}/deprecate.js (100%) rename {atom/common/api/lib => lib/common/api}/deprecations.js (100%) rename {atom/common/api/lib => lib/common/api}/exports/electron.js (100%) rename {atom/common/api/lib => lib/common/api}/native-image.js (100%) rename {atom/common/api/lib => lib/common/api}/shell.js (100%) rename {atom/common/lib => lib/common}/asar.js (100%) rename {atom/common/lib => lib/common}/asar_init.js (100%) rename {atom/common/lib => lib/common}/init.js (100%) rename {atom/common/lib => lib/common}/reset-search-paths.js (100%) rename {atom/renderer/api/lib => lib/renderer/api}/desktop-capturer.js (100%) rename {atom/renderer/api/lib => lib/renderer/api}/exports/electron.js (100%) rename {atom/renderer/api/lib => lib/renderer/api}/ipc-renderer.js (100%) rename {atom/renderer/api/lib => lib/renderer/api}/ipc.js (100%) rename {atom/renderer/api/lib => lib/renderer/api}/remote.js (100%) rename {atom/renderer/api/lib => lib/renderer/api}/screen.js (100%) rename {atom/renderer/api/lib => lib/renderer/api}/web-frame.js (100%) rename {atom/renderer/lib => lib/renderer}/chrome-api.js (100%) rename {atom/renderer/lib => lib/renderer}/init.js (100%) rename {atom/renderer/lib => lib/renderer}/inspector.js (100%) rename {atom/renderer/lib => lib/renderer}/override.js (100%) rename {atom/renderer/lib => lib/renderer}/web-view/guest-view-internal.js (100%) rename {atom/renderer/lib => lib/renderer}/web-view/web-view-attributes.js (100%) rename {atom/renderer/lib => lib/renderer}/web-view/web-view-constants.js (100%) rename {atom/renderer/lib => lib/renderer}/web-view/web-view.js (100%) diff --git a/atom/browser/api/lib/app.js b/lib/browser/api/app.js similarity index 100% rename from atom/browser/api/lib/app.js rename to lib/browser/api/app.js diff --git a/atom/browser/api/lib/auto-updater.js b/lib/browser/api/auto-updater.js similarity index 100% rename from atom/browser/api/lib/auto-updater.js rename to lib/browser/api/auto-updater.js diff --git a/atom/browser/api/lib/auto-updater/auto-updater-native.js b/lib/browser/api/auto-updater/auto-updater-native.js similarity index 100% rename from atom/browser/api/lib/auto-updater/auto-updater-native.js rename to lib/browser/api/auto-updater/auto-updater-native.js diff --git a/atom/browser/api/lib/auto-updater/auto-updater-win.js b/lib/browser/api/auto-updater/auto-updater-win.js similarity index 100% rename from atom/browser/api/lib/auto-updater/auto-updater-win.js rename to lib/browser/api/auto-updater/auto-updater-win.js diff --git a/atom/browser/api/lib/auto-updater/squirrel-update-win.js b/lib/browser/api/auto-updater/squirrel-update-win.js similarity index 100% rename from atom/browser/api/lib/auto-updater/squirrel-update-win.js rename to lib/browser/api/auto-updater/squirrel-update-win.js diff --git a/atom/browser/api/lib/browser-window.js b/lib/browser/api/browser-window.js similarity index 100% rename from atom/browser/api/lib/browser-window.js rename to lib/browser/api/browser-window.js diff --git a/atom/browser/api/lib/content-tracing.js b/lib/browser/api/content-tracing.js similarity index 100% rename from atom/browser/api/lib/content-tracing.js rename to lib/browser/api/content-tracing.js diff --git a/atom/browser/api/lib/dialog.js b/lib/browser/api/dialog.js similarity index 100% rename from atom/browser/api/lib/dialog.js rename to lib/browser/api/dialog.js diff --git a/atom/browser/api/lib/exports/electron.js b/lib/browser/api/exports/electron.js similarity index 100% rename from atom/browser/api/lib/exports/electron.js rename to lib/browser/api/exports/electron.js diff --git a/atom/browser/api/lib/global-shortcut.js b/lib/browser/api/global-shortcut.js similarity index 100% rename from atom/browser/api/lib/global-shortcut.js rename to lib/browser/api/global-shortcut.js diff --git a/atom/browser/api/lib/ipc-main.js b/lib/browser/api/ipc-main.js similarity index 100% rename from atom/browser/api/lib/ipc-main.js rename to lib/browser/api/ipc-main.js diff --git a/atom/browser/api/lib/ipc.js b/lib/browser/api/ipc.js similarity index 100% rename from atom/browser/api/lib/ipc.js rename to lib/browser/api/ipc.js diff --git a/atom/browser/api/lib/menu-item.js b/lib/browser/api/menu-item.js similarity index 100% rename from atom/browser/api/lib/menu-item.js rename to lib/browser/api/menu-item.js diff --git a/atom/browser/api/lib/menu.js b/lib/browser/api/menu.js similarity index 100% rename from atom/browser/api/lib/menu.js rename to lib/browser/api/menu.js diff --git a/atom/browser/api/lib/navigation-controller.js b/lib/browser/api/navigation-controller.js similarity index 100% rename from atom/browser/api/lib/navigation-controller.js rename to lib/browser/api/navigation-controller.js diff --git a/atom/browser/api/lib/power-monitor.js b/lib/browser/api/power-monitor.js similarity index 100% rename from atom/browser/api/lib/power-monitor.js rename to lib/browser/api/power-monitor.js diff --git a/atom/browser/api/lib/power-save-blocker.js b/lib/browser/api/power-save-blocker.js similarity index 100% rename from atom/browser/api/lib/power-save-blocker.js rename to lib/browser/api/power-save-blocker.js diff --git a/atom/browser/api/lib/protocol.js b/lib/browser/api/protocol.js similarity index 100% rename from atom/browser/api/lib/protocol.js rename to lib/browser/api/protocol.js diff --git a/atom/browser/api/lib/screen.js b/lib/browser/api/screen.js similarity index 100% rename from atom/browser/api/lib/screen.js rename to lib/browser/api/screen.js diff --git a/atom/browser/api/lib/session.js b/lib/browser/api/session.js similarity index 100% rename from atom/browser/api/lib/session.js rename to lib/browser/api/session.js diff --git a/atom/browser/api/lib/tray.js b/lib/browser/api/tray.js similarity index 100% rename from atom/browser/api/lib/tray.js rename to lib/browser/api/tray.js diff --git a/atom/browser/api/lib/web-contents.js b/lib/browser/api/web-contents.js similarity index 100% rename from atom/browser/api/lib/web-contents.js rename to lib/browser/api/web-contents.js diff --git a/atom/browser/lib/chrome-extension.js b/lib/browser/chrome-extension.js similarity index 100% rename from atom/browser/lib/chrome-extension.js rename to lib/browser/chrome-extension.js diff --git a/atom/browser/lib/desktop-capturer.js b/lib/browser/desktop-capturer.js similarity index 100% rename from atom/browser/lib/desktop-capturer.js rename to lib/browser/desktop-capturer.js diff --git a/atom/browser/lib/guest-view-manager.js b/lib/browser/guest-view-manager.js similarity index 100% rename from atom/browser/lib/guest-view-manager.js rename to lib/browser/guest-view-manager.js diff --git a/atom/browser/lib/guest-window-manager.js b/lib/browser/guest-window-manager.js similarity index 100% rename from atom/browser/lib/guest-window-manager.js rename to lib/browser/guest-window-manager.js diff --git a/atom/browser/lib/init.js b/lib/browser/init.js similarity index 100% rename from atom/browser/lib/init.js rename to lib/browser/init.js diff --git a/atom/browser/lib/objects-registry.js b/lib/browser/objects-registry.js similarity index 100% rename from atom/browser/lib/objects-registry.js rename to lib/browser/objects-registry.js diff --git a/atom/browser/lib/rpc-server.js b/lib/browser/rpc-server.js similarity index 100% rename from atom/browser/lib/rpc-server.js rename to lib/browser/rpc-server.js diff --git a/atom/common/api/lib/callbacks-registry.js b/lib/common/api/callbacks-registry.js similarity index 100% rename from atom/common/api/lib/callbacks-registry.js rename to lib/common/api/callbacks-registry.js diff --git a/atom/common/api/lib/clipboard.js b/lib/common/api/clipboard.js similarity index 100% rename from atom/common/api/lib/clipboard.js rename to lib/common/api/clipboard.js diff --git a/atom/common/api/lib/crash-reporter.js b/lib/common/api/crash-reporter.js similarity index 100% rename from atom/common/api/lib/crash-reporter.js rename to lib/common/api/crash-reporter.js diff --git a/atom/common/api/lib/deprecate.js b/lib/common/api/deprecate.js similarity index 100% rename from atom/common/api/lib/deprecate.js rename to lib/common/api/deprecate.js diff --git a/atom/common/api/lib/deprecations.js b/lib/common/api/deprecations.js similarity index 100% rename from atom/common/api/lib/deprecations.js rename to lib/common/api/deprecations.js diff --git a/atom/common/api/lib/exports/electron.js b/lib/common/api/exports/electron.js similarity index 100% rename from atom/common/api/lib/exports/electron.js rename to lib/common/api/exports/electron.js diff --git a/atom/common/api/lib/native-image.js b/lib/common/api/native-image.js similarity index 100% rename from atom/common/api/lib/native-image.js rename to lib/common/api/native-image.js diff --git a/atom/common/api/lib/shell.js b/lib/common/api/shell.js similarity index 100% rename from atom/common/api/lib/shell.js rename to lib/common/api/shell.js diff --git a/atom/common/lib/asar.js b/lib/common/asar.js similarity index 100% rename from atom/common/lib/asar.js rename to lib/common/asar.js diff --git a/atom/common/lib/asar_init.js b/lib/common/asar_init.js similarity index 100% rename from atom/common/lib/asar_init.js rename to lib/common/asar_init.js diff --git a/atom/common/lib/init.js b/lib/common/init.js similarity index 100% rename from atom/common/lib/init.js rename to lib/common/init.js diff --git a/atom/common/lib/reset-search-paths.js b/lib/common/reset-search-paths.js similarity index 100% rename from atom/common/lib/reset-search-paths.js rename to lib/common/reset-search-paths.js diff --git a/atom/renderer/api/lib/desktop-capturer.js b/lib/renderer/api/desktop-capturer.js similarity index 100% rename from atom/renderer/api/lib/desktop-capturer.js rename to lib/renderer/api/desktop-capturer.js diff --git a/atom/renderer/api/lib/exports/electron.js b/lib/renderer/api/exports/electron.js similarity index 100% rename from atom/renderer/api/lib/exports/electron.js rename to lib/renderer/api/exports/electron.js diff --git a/atom/renderer/api/lib/ipc-renderer.js b/lib/renderer/api/ipc-renderer.js similarity index 100% rename from atom/renderer/api/lib/ipc-renderer.js rename to lib/renderer/api/ipc-renderer.js diff --git a/atom/renderer/api/lib/ipc.js b/lib/renderer/api/ipc.js similarity index 100% rename from atom/renderer/api/lib/ipc.js rename to lib/renderer/api/ipc.js diff --git a/atom/renderer/api/lib/remote.js b/lib/renderer/api/remote.js similarity index 100% rename from atom/renderer/api/lib/remote.js rename to lib/renderer/api/remote.js diff --git a/atom/renderer/api/lib/screen.js b/lib/renderer/api/screen.js similarity index 100% rename from atom/renderer/api/lib/screen.js rename to lib/renderer/api/screen.js diff --git a/atom/renderer/api/lib/web-frame.js b/lib/renderer/api/web-frame.js similarity index 100% rename from atom/renderer/api/lib/web-frame.js rename to lib/renderer/api/web-frame.js diff --git a/atom/renderer/lib/chrome-api.js b/lib/renderer/chrome-api.js similarity index 100% rename from atom/renderer/lib/chrome-api.js rename to lib/renderer/chrome-api.js diff --git a/atom/renderer/lib/init.js b/lib/renderer/init.js similarity index 100% rename from atom/renderer/lib/init.js rename to lib/renderer/init.js diff --git a/atom/renderer/lib/inspector.js b/lib/renderer/inspector.js similarity index 100% rename from atom/renderer/lib/inspector.js rename to lib/renderer/inspector.js diff --git a/atom/renderer/lib/override.js b/lib/renderer/override.js similarity index 100% rename from atom/renderer/lib/override.js rename to lib/renderer/override.js diff --git a/atom/renderer/lib/web-view/guest-view-internal.js b/lib/renderer/web-view/guest-view-internal.js similarity index 100% rename from atom/renderer/lib/web-view/guest-view-internal.js rename to lib/renderer/web-view/guest-view-internal.js diff --git a/atom/renderer/lib/web-view/web-view-attributes.js b/lib/renderer/web-view/web-view-attributes.js similarity index 100% rename from atom/renderer/lib/web-view/web-view-attributes.js rename to lib/renderer/web-view/web-view-attributes.js diff --git a/atom/renderer/lib/web-view/web-view-constants.js b/lib/renderer/web-view/web-view-constants.js similarity index 100% rename from atom/renderer/lib/web-view/web-view-constants.js rename to lib/renderer/web-view/web-view-constants.js diff --git a/atom/renderer/lib/web-view/web-view.js b/lib/renderer/web-view/web-view.js similarity index 100% rename from atom/renderer/lib/web-view/web-view.js rename to lib/renderer/web-view/web-view.js From 6e3cb9e8eb71282b99b5fcc5ade1edb2f9712fe1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 17:22:38 -0800 Subject: [PATCH 391/688] Update paths for new JS location --- filenames.gypi | 112 ++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/filenames.gypi b/filenames.gypi index abb11453210..f9e19550c89 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -8,64 +8,64 @@ 'atom/browser/resources/mac/atom.icns', ], 'js_sources': [ - 'atom/browser/api/lib/app.js', - 'atom/browser/api/lib/auto-updater.js', - 'atom/browser/api/lib/auto-updater/auto-updater-native.js', - 'atom/browser/api/lib/auto-updater/auto-updater-win.js', - 'atom/browser/api/lib/auto-updater/squirrel-update-win.js', - 'atom/browser/api/lib/browser-window.js', - 'atom/browser/api/lib/content-tracing.js', - 'atom/browser/api/lib/dialog.js', - 'atom/browser/api/lib/exports/electron.js', - 'atom/browser/api/lib/global-shortcut.js', - 'atom/browser/api/lib/ipc.js', - 'atom/browser/api/lib/ipc-main.js', - 'atom/browser/api/lib/menu.js', - 'atom/browser/api/lib/menu-item.js', - 'atom/browser/api/lib/navigation-controller.js', - 'atom/browser/api/lib/power-monitor.js', - 'atom/browser/api/lib/power-save-blocker.js', - 'atom/browser/api/lib/protocol.js', - 'atom/browser/api/lib/session.js', - 'atom/browser/api/lib/screen.js', - 'atom/browser/api/lib/tray.js', - 'atom/browser/api/lib/web-contents.js', - 'atom/browser/lib/chrome-extension.js', - 'atom/browser/lib/desktop-capturer.js', - 'atom/browser/lib/guest-view-manager.js', - 'atom/browser/lib/guest-window-manager.js', - 'atom/browser/lib/init.js', - 'atom/browser/lib/objects-registry.js', - 'atom/browser/lib/rpc-server.js', - 'atom/common/api/lib/callbacks-registry.js', - 'atom/common/api/lib/clipboard.js', - 'atom/common/api/lib/crash-reporter.js', - 'atom/common/api/lib/deprecate.js', - 'atom/common/api/lib/deprecations.js', - 'atom/common/api/lib/exports/electron.js', - 'atom/common/api/lib/native-image.js', - 'atom/common/api/lib/shell.js', - 'atom/common/lib/init.js', - 'atom/common/lib/reset-search-paths.js', - 'atom/renderer/lib/chrome-api.js', - 'atom/renderer/lib/init.js', - 'atom/renderer/lib/inspector.js', - 'atom/renderer/lib/override.js', - 'atom/renderer/lib/web-view/guest-view-internal.js', - 'atom/renderer/lib/web-view/web-view.js', - 'atom/renderer/lib/web-view/web-view-attributes.js', - 'atom/renderer/lib/web-view/web-view-constants.js', - 'atom/renderer/api/lib/desktop-capturer.js', - 'atom/renderer/api/lib/exports/electron.js', - 'atom/renderer/api/lib/ipc.js', - 'atom/renderer/api/lib/ipc-renderer.js', - 'atom/renderer/api/lib/remote.js', - 'atom/renderer/api/lib/screen.js', - 'atom/renderer/api/lib/web-frame.js', + 'lib/browser/api/app.js', + 'lib/browser/api/auto-updater.js', + 'lib/browser/api/auto-updater/auto-updater-native.js', + 'lib/browser/api/auto-updater/auto-updater-win.js', + 'lib/browser/api/auto-updater/squirrel-update-win.js', + 'lib/browser/api/browser-window.js', + 'lib/browser/api/content-tracing.js', + 'lib/browser/api/dialog.js', + 'lib/browser/api/exports/electron.js', + 'lib/browser/api/global-shortcut.js', + 'lib/browser/api/ipc.js', + 'lib/browser/api/ipc-main.js', + 'lib/browser/api/menu.js', + 'lib/browser/api/menu-item.js', + 'lib/browser/api/navigation-controller.js', + 'lib/browser/api/power-monitor.js', + 'lib/browser/api/power-save-blocker.js', + 'lib/browser/api/protocol.js', + 'lib/browser/api/session.js', + 'lib/browser/api/screen.js', + 'lib/browser/api/tray.js', + 'lib/browser/api/web-contents.js', + 'lib/browser/chrome-extension.js', + 'lib/browser/desktop-capturer.js', + 'lib/browser/guest-view-manager.js', + 'lib/browser/guest-window-manager.js', + 'lib/browser/init.js', + 'lib/browser/objects-registry.js', + 'lib/browser/rpc-server.js', + 'lib/common/api/callbacks-registry.js', + 'lib/common/api/clipboard.js', + 'lib/common/api/crash-reporter.js', + 'lib/common/api/deprecate.js', + 'lib/common/api/deprecations.js', + 'lib/common/api/exports/electron.js', + 'lib/common/api/native-image.js', + 'lib/common/api/shell.js', + 'lib/common/init.js', + 'lib/common/reset-search-paths.js', + 'lib/renderer/chrome-api.js', + 'lib/renderer/init.js', + 'lib/renderer/inspector.js', + 'lib/renderer/override.js', + 'lib/renderer/web-view/guest-view-internal.js', + 'lib/renderer/web-view/web-view.js', + 'lib/renderer/web-view/web-view-attributes.js', + 'lib/renderer/web-view/web-view-constants.js', + 'lib/renderer/api/desktop-capturer.js', + 'lib/renderer/api/exports/electron.js', + 'lib/renderer/api/ipc.js', + 'lib/renderer/api/ipc-renderer.js', + 'lib/renderer/api/remote.js', + 'lib/renderer/api/screen.js', + 'lib/renderer/api/web-frame.js', ], 'js2c_sources': [ - 'atom/common/lib/asar.js', - 'atom/common/lib/asar_init.js', + 'lib/common/asar.js', + 'lib/common/asar_init.js', ], 'lib_sources': [ 'atom/app/atom_content_client.cc', From c47ad29124de46b6838e633b15510b10b29c700a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 7 Mar 2016 17:25:01 -0800 Subject: [PATCH 392/688] Move default_app to root of repo --- atom.gyp | 6 +++--- {atom/browser/default_app => default_app}/default_app.js | 0 {atom/browser/default_app => default_app}/index.html | 0 {atom/browser/default_app => default_app}/main.js | 0 {atom/browser/default_app => default_app}/package.json | 0 5 files changed, 3 insertions(+), 3 deletions(-) rename {atom/browser/default_app => default_app}/default_app.js (100%) rename {atom/browser/default_app => default_app}/index.html (100%) rename {atom/browser/default_app => default_app}/main.js (100%) rename {atom/browser/default_app => default_app}/package.json (100%) diff --git a/atom.gyp b/atom.gyp index 7f78bee91b1..b7075301894 100644 --- a/atom.gyp +++ b/atom.gyp @@ -69,7 +69,7 @@ { 'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Resources', 'files': [ - 'atom/browser/default_app', + 'default_app', ], }, ], @@ -171,7 +171,7 @@ { 'destination': '<(PRODUCT_DIR)/resources', 'files': [ - 'atom/browser/default_app', + 'default_app', ] }, ], @@ -212,7 +212,7 @@ { 'destination': '<(PRODUCT_DIR)/resources', 'files': [ - 'atom/browser/default_app', + 'default_app', ] }, ], diff --git a/atom/browser/default_app/default_app.js b/default_app/default_app.js similarity index 100% rename from atom/browser/default_app/default_app.js rename to default_app/default_app.js diff --git a/atom/browser/default_app/index.html b/default_app/index.html similarity index 100% rename from atom/browser/default_app/index.html rename to default_app/index.html diff --git a/atom/browser/default_app/main.js b/default_app/main.js similarity index 100% rename from atom/browser/default_app/main.js rename to default_app/main.js diff --git a/atom/browser/default_app/package.json b/default_app/package.json similarity index 100% rename from atom/browser/default_app/package.json rename to default_app/package.json From f109591d030801f96d33beb7c5e6bd3e1edb20a3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 8 Mar 2016 11:03:25 -0800 Subject: [PATCH 393/688] Look for JS in lib dir --- tools/js2asar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/js2asar.py b/tools/js2asar.py index a17212419e1..cb02e33de65 100755 --- a/tools/js2asar.py +++ b/tools/js2asar.py @@ -29,7 +29,7 @@ def copy_js(js_source_files, output_dir): def call_asar(archive, output_dir): - js_dir = os.path.join(output_dir, 'atom') + js_dir = os.path.join(output_dir, 'lib') asar = os.path.join(SOURCE_ROOT, 'node_modules', 'asar', 'bin', 'asar') subprocess.check_call([find_node(), asar, 'pack', js_dir, archive]) From 006c77a00fb26572592af51e5201fc7a602e1e3c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 8 Mar 2016 11:07:42 -0800 Subject: [PATCH 394/688] Update requires paths --- atom/common/node_bindings.cc | 1 - lib/browser/api/exports/electron.js | 2 +- lib/browser/init.js | 8 ++++---- lib/renderer/api/exports/electron.js | 2 +- lib/renderer/api/remote.js | 2 +- lib/renderer/init.js | 8 ++++---- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 69e7906ffbb..608cc94b09a 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -165,7 +165,6 @@ node::Environment* NodeBindings::CreateEnvironment( base::FilePath script_path = resources_path.Append(FILE_PATH_LITERAL("atom.asar")) .Append(process_type) - .Append(FILE_PATH_LITERAL("lib")) .Append(FILE_PATH_LITERAL("init.js")); std::string script_path_str = script_path.AsUTF8Unsafe(); args.insert(args.begin() + 1, script_path_str.c_str()); diff --git a/lib/browser/api/exports/electron.js b/lib/browser/api/exports/electron.js index 7f97fcdbc4c..ea9dd6eb5a2 100644 --- a/lib/browser/api/exports/electron.js +++ b/lib/browser/api/exports/electron.js @@ -1,4 +1,4 @@ -const common = require('../../../../common/api/lib/exports/electron'); +const common = require('../../../common/api/exports/electron'); // Import common modules. diff --git a/lib/browser/init.js b/lib/browser/init.js index 4769faee0a3..d6a18361d69 100644 --- a/lib/browser/init.js +++ b/lib/browser/init.js @@ -11,19 +11,19 @@ var slice = [].slice; process.argv.splice(1, 1); // Clear search paths. -require(path.resolve(__dirname, '..', '..', 'common', 'lib', 'reset-search-paths')); +require(path.resolve(__dirname, '..', 'common', 'reset-search-paths')); // Import common settings. -require(path.resolve(__dirname, '..', '..', 'common', 'lib', 'init')); +require(path.resolve(__dirname, '..', 'common', 'init')); var globalPaths = Module.globalPaths; if (!process.env.ELECTRON_HIDE_INTERNAL_MODULES) { - globalPaths.push(path.resolve(__dirname, '..', 'api', 'lib')); + globalPaths.push(path.resolve(__dirname, 'api')); } // Expose public APIs. -globalPaths.push(path.resolve(__dirname, '..', 'api', 'lib', 'exports')); +globalPaths.push(path.resolve(__dirname, 'api', 'exports')); if (process.platform === 'win32') { // Redirect node's console to use our own implementations, since node can not diff --git a/lib/renderer/api/exports/electron.js b/lib/renderer/api/exports/electron.js index 3f0d3254cb8..34a498fcc06 100644 --- a/lib/renderer/api/exports/electron.js +++ b/lib/renderer/api/exports/electron.js @@ -1,4 +1,4 @@ -const common = require('../../../../common/api/lib/exports/electron'); +const common = require('../../../common/api/exports/electron'); // Import common modules. common.defineProperties(exports); diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index 07aa2478293..42435d8304c 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -244,7 +244,7 @@ ipcRenderer.on('ATOM_RENDERER_RELEASE_CALLBACK', function(event, id) { }); // List all built-in modules in browser process. -const browserModules = require('../../../browser/api/lib/exports/electron'); +const browserModules = require('../../browser/api/exports/electron'); // And add a helper receiver for each one. var fn = function(name) { diff --git a/lib/renderer/init.js b/lib/renderer/init.js index 166e64237de..334aebda9cf 100644 --- a/lib/renderer/init.js +++ b/lib/renderer/init.js @@ -9,19 +9,19 @@ const Module = require('module'); process.argv.splice(1, 1); // Clear search paths. -require(path.resolve(__dirname, '..', '..', 'common', 'lib', 'reset-search-paths')); +require(path.resolve(__dirname, '..', 'common', 'reset-search-paths')); // Import common settings. -require(path.resolve(__dirname, '..', '..', 'common', 'lib', 'init')); +require(path.resolve(__dirname, '..','common', 'init')); var globalPaths = Module.globalPaths; if (!process.env.ELECTRON_HIDE_INTERNAL_MODULES) { - globalPaths.push(path.resolve(__dirname, '..', 'api', 'lib')); + globalPaths.push(path.resolve(__dirname, 'api')); } // Expose public APIs. -globalPaths.push(path.resolve(__dirname, '..', 'api', 'lib', 'exports')); +globalPaths.push(path.resolve(__dirname, 'api', 'exports')); // The global variable will be used by ipc for event dispatching var v8Util = process.atomBinding('v8_util'); From 418efbe6608ca3710a6edf684fb1d11eac74defa Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 8 Mar 2016 11:10:31 -0800 Subject: [PATCH 395/688] Remove unneeded resolve calls --- lib/browser/init.js | 8 ++++---- lib/renderer/init.js | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/browser/init.js b/lib/browser/init.js index d6a18361d69..e1105df9b13 100644 --- a/lib/browser/init.js +++ b/lib/browser/init.js @@ -11,19 +11,19 @@ var slice = [].slice; process.argv.splice(1, 1); // Clear search paths. -require(path.resolve(__dirname, '..', 'common', 'reset-search-paths')); +require('../common/reset-search-paths'); // Import common settings. -require(path.resolve(__dirname, '..', 'common', 'init')); +require('../common/init'); var globalPaths = Module.globalPaths; if (!process.env.ELECTRON_HIDE_INTERNAL_MODULES) { - globalPaths.push(path.resolve(__dirname, 'api')); + globalPaths.push(path.join(__dirname, 'api')); } // Expose public APIs. -globalPaths.push(path.resolve(__dirname, 'api', 'exports')); +globalPaths.push(path.join(__dirname, 'api', 'exports')); if (process.platform === 'win32') { // Redirect node's console to use our own implementations, since node can not diff --git a/lib/renderer/init.js b/lib/renderer/init.js index 334aebda9cf..45ea2d45654 100644 --- a/lib/renderer/init.js +++ b/lib/renderer/init.js @@ -9,19 +9,19 @@ const Module = require('module'); process.argv.splice(1, 1); // Clear search paths. -require(path.resolve(__dirname, '..', 'common', 'reset-search-paths')); +require('../common/reset-search-paths'); // Import common settings. -require(path.resolve(__dirname, '..','common', 'init')); +require('../common/init'); var globalPaths = Module.globalPaths; if (!process.env.ELECTRON_HIDE_INTERNAL_MODULES) { - globalPaths.push(path.resolve(__dirname, 'api')); + globalPaths.push(path.join(__dirname, 'api')); } // Expose public APIs. -globalPaths.push(path.resolve(__dirname, 'api', 'exports')); +globalPaths.push(path.join(__dirname, 'api', 'exports')); // The global variable will be used by ipc for event dispatching var v8Util = process.atomBinding('v8_util'); From 4c9f5b71f7ecaea2436bc647f4491d3974b89e44 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 8 Mar 2016 11:11:35 -0800 Subject: [PATCH 396/688] Run eslint over lib folder --- script/eslint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/eslint.py b/script/eslint.py index 7b912e0e1d6..4fbc5788570 100755 --- a/script/eslint.py +++ b/script/eslint.py @@ -24,7 +24,7 @@ def main(): settings = ['--quiet', '--config'] sourceConfig = os.path.join('script', 'eslintrc-base.json') - sourceFiles = ['atom'] + sourceFiles = ['lib'] execute([eslint] + settings + [sourceConfig] + sourceFiles) specConfig = os.path.join('script', 'eslintrc-spec.json') From 2e9fd7ce77faf451526464eaeb06521d31b9150d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 8 Mar 2016 11:22:13 -0800 Subject: [PATCH 397/688] Update common api path --- lib/common/init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/init.js b/lib/common/init.js index a4766c4a7f9..923ef910886 100644 --- a/lib/common/init.js +++ b/lib/common/init.js @@ -14,7 +14,7 @@ process.atomBinding = function(name) { if (!process.env.ELECTRON_HIDE_INTERNAL_MODULES) { // Add common/api/lib to module search paths. - Module.globalPaths.push(path.resolve(__dirname, '..', 'api', 'lib')); + Module.globalPaths.push(path.join(__dirname, 'api')); } From c3b058cea37eae064532ebac036eb67ed5db41e1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 8 Mar 2016 11:22:58 -0800 Subject: [PATCH 398/688] Update path to ipc.js --- spec/asar-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/asar-spec.js b/spec/asar-spec.js index f6f4bb71dbc..0e0a7f89f17 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -17,7 +17,7 @@ describe('asar package', function() { it('does not leak fd', function() { var readCalls = 1; while(readCalls <= 10000) { - fs.readFileSync(path.join(process.resourcesPath, 'atom.asar', 'renderer', 'api', 'lib', 'ipc.js')); + fs.readFileSync(path.join(process.resourcesPath, 'atom.asar', 'renderer', 'api', 'ipc.js')); readCalls++; } }); From 937668097aabfe200b3c3324c84cfb49a96b14a2 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Wed, 9 Mar 2016 17:00:01 +0800 Subject: [PATCH 399/688] web-view-tag first finish --- docs-translations/zh-CN/api/web-view-tag.md | 690 ++++++++++++++++++++ 1 file changed, 690 insertions(+) create mode 100644 docs-translations/zh-CN/api/web-view-tag.md diff --git a/docs-translations/zh-CN/api/web-view-tag.md b/docs-translations/zh-CN/api/web-view-tag.md new file mode 100644 index 00000000000..819d57cb459 --- /dev/null +++ b/docs-translations/zh-CN/api/web-view-tag.md @@ -0,0 +1,690 @@ +# `` 标签 + +使用 `webview` 标签来把 'guest' 内容(例如 web pages )嵌入到你的 Electron app 中. guest内容包含在 `webview` 容器中.一个嵌入你的应用的page控制着guest内容如何布局摆放和表达含义. + +与 `iframe` 不同, `webview` 和你的应用运行的是不同的进程. 它不拥有渲染进程的权限,并且应用和嵌入内容之间的交互全部都是异步的.因为这能保证应用的安全性不受嵌入内容的影响. + +## 例子 + +把一个 web page 嵌入到你的app,首先添加 `webview` 标签到你的app待嵌入page(展示 guest content). 在一个最简单的 `webview` 中,它包含了 web page 的文件路径和一个控制 `webview` 容器展示效果的css样式: + +```html + +``` + +如果想随时控制 guest 内容,可以添加 JavaScript 脚本来监听 `webview` 事件使用 `webview` 方法来做出响应. 这里是2个事件监听的例子:一个监听 web page 准备加载,另一个监听 web page 停止加载,并且在加载的时候显示一条 "loading..." 信息: + +```html + +``` + +## 标签属性 + +`webview` 标签有下面一些属性 : + +### `src` + +```html + +``` + +将一个可用的url做为这个属性的初始值添加到顶部导航. + +如果把当前页的src添加进去将加载当前page. + + `src`同样可以填 data urls,例如 +`data:text/plain,Hello, world!`. + +### `autosize` + +```html + +``` + +如果这个属性的值为 "on" , `webview` 容器将会根据属性`minwidth`, `minheight`, `maxwidth`, 和 +`maxheight` 的值在它们之间自适应. 只有在 `autosize` 开启的时候这个约束才会有效. 当 `autosize` 开启的时候, `webview` 容器的 size 只能在上面那四个属性值之间. + +### `nodeintegration` + +```html + +``` + +如果这个属性的值为 "on" , `webview` 中的 guest page 将整合node,并且拥有可以使用系统底层的资源,例如 `require` 和 `process` . + +### `plugins` + +```html + +``` + +如果这个属性的值为 "on" , `webview` 中的 guest page 就可以使用浏览器插件。 + +### `preload` + +```html + +``` + +在 guest page 中的其他脚本执行之前预加载一个指定的脚本。规定预加载脚本的url须如 `file:` 或者 `asar:`,因为它在是 guest page 中通过通过 `require` 命令加载的。 + +如果 guest page 没有整合 node ,这个脚本将试图使用真个 Node APIs ,但是在这个脚本执行完毕时,之前由node插入的全局对象会被删除。 + + +### `httpreferrer` + +```html + +``` + +为 guest page 设置 referrer URL。 + +### `useragent` + +```html + +``` + +在 guest page 加载之前为其设置用户代理。如果页面已经加载了,可以使用 `setUserAgent` 方法来改变用户代理。 + +### `disablewebsecurity` + +```html + +``` + +如果这个属性的值为 "on" , guest page会禁用web安全控制. + +### partition + +```html + + +``` + +为page设置session。如果初始值为 `partition` ,这个 page 将会为app中的所有 page 应用同一个持续有效的 session。如果没有 `persist:` 前缀, 这个 page 将会使用一个历史 session 。通过分配使用相同的 `partition`, 所有的page都可以分享相同的session。如果 `partition` 没有设置,那app将使用默认的session. + +这个值只能在在第一个渲染进程之前设置修改,之后修改的话会无效并且抛出一个DOM异常. + +### `allowpopups` + +```html + +``` + +如果这个属性的值为 "on" ,将允许 guest page 打开一个新窗口。 + +### `blinkfeatures` + +```html + +``` + +这个属性的值为一个用逗号分隔的列表,它的值指定特性被启用。你可以从[setFeatureEnabledFromString][blink-feature-string]函数找到完整的支持特性。 + +## 方法 + + `webview` 的方法集合: + +**注意:** webview 元素必须在使用这些方法之前加载完毕。 + +**例如** + +```javascript +webview.addEventListener("dom-ready", function() { + webview.openDevTools(); +}); +``` + +### `.loadURL(url[, options])` + +* `url` URL +* `options` Object (可选) + * `httpReferrer` String - 一个http类型的url. + * `userAgent` String -用于发起请求的用户代理. + * `extraHeaders` String - 额外的headers,用 "\n"分隔. + +加载 webview 中的 `url`,`url` 必须包含协议前缀,例如 `http://` 或 `file://`. + +### `.getURL()` + +从 guest page 中返回 url. + +### `.getTitle()` + +从 guest page 中返回 title. + +### `.isLoading()` + +返回一个 guest page 是否仍在加载资源的布尔值. + +### `.isWaitingForResponse()` + +返回一个 guest page 是否正在等待page的主要资源做出回应的布尔值. + + +### `.stop()` + +停止渲染. + +### `.reload()` + +重新加载 guest page. + +### `.reloadIgnoringCache()` + +忽视缓存,重新加载 guest page. + +### `.canGoBack()` + +返回一个 guest page 是否能够回退的布尔值. + +### `.canGoForward()` + +返回一个 guest page 是否能够前进的布尔值. + +### `.canGoToOffset(offset)` + +* `offset` Integer + +返回一个 guest page 是否能够前进到 `offset` 的布尔值. + +### `.clearHistory()` + +清除导航历史. + +### `.goBack()` + +guest page 回退. + +### `.goForward()` + +guest page 前进. + +### `.goToIndex(index)` + +* `index` Integer + +guest page 导航到指定的绝对位置. + +### `.goToOffset(offset)` + +* `offset` Integer + +guest page 导航到指定的相对位置. + +### `.isCrashed()` + +返回一个 渲染进程是否崩溃 的布尔值. + +### `.setUserAgent(userAgent)` + +* `userAgent` String + +重新设置用户代理. + +### `.getUserAgent()` + +返回用户代理名字,返回类型:`String`. + +### `.insertCSS(css)` + +* `css` String + +插入css. + +### `.executeJavaScript(code, userGesture, callback)` + +* `code` String +* `userGesture` Boolean - 默认 `false`. +* `callback` Function (可选) - 回调函数. + * `result` + +评估 `code` ,如果 `userGesture` 值为 true ,它将在这个page里面创建用户手势. HTML APIs ,如 `requestFullScreen`,它需要用户响应,那么将自动通过这个参数优化. + +### `.openDevTools()` + +为 guest page 打开开发工具调试窗口. + +### `.closeDevTools()` + +为 guest page 关闭开发工具调试窗口. + +### `.isDevToolsOpened()` + +返回一个 guest page 是否打开了开发工具调试窗口的布尔值. + +### `.isDevToolsFocused()` + +返回一个 guest page 是否聚焦了开发工具调试窗口的布尔值. + +### `.inspectElement(x, y)` + +* `x` Integer +* `y` Integer + +开始检查 guest page 在 (`x`, `y`) 位置的元素. + +### `.inspectServiceWorker()` + +在 guest page 中为服务人员打开开发工具. + +### `.setAudioMuted(muted)` + +* `muted` Boolean +设置 guest page 流畅(muted). + +### `.isAudioMuted()` + +返回一个 guest page 是否流畅的布尔值. + +### `.undo()` + +在page中编辑执行 `undo` 命令. + +### `.redo()` + +在page中编辑执行 `redo` 命令. + +### `.cut()` + +在page中编辑执行 `cut` 命令. + +### `.copy()` + +在page中编辑执行 `copy` 命令. + +### `.paste()` + +在page中编辑执行 `paste` 命令. + +### `.pasteAndMatchStyle()` + +在page中编辑执行 `pasteAndMatchStyle` 命令. + +### `.delete()` + +在page中编辑执行 `delete` 命令. + +### `.selectAll()` + +在page中编辑执行 `selectAll` 命令. + +### `.unselect()` + +在page中编辑执行 `unselect` 命令. + +### `.replace(text)` + +* `text` String + +在page中编辑执行 `replace` 命令. + +### `.replaceMisspelling(text)` + +* `text` String + +在page中编辑执行 `replaceMisspelling` 命令. + +### `.insertText(text)` + +* `text` String + +插入文本. + +### `.findInPage(text[, options])` + +* `text` String - 搜索内容,不能为空. +* `options` Object (可选) + * `forward` Boolean - 向前或向后, 默认为 `true`. + * `findNext` Boolean - 是否查找的第一个结果, + 默认为 `false`. + * `matchCase` Boolean - 是否区分大小写, + 默认为 `false`. + * `wordStart` Boolean - 是否只查找首字母. + 默认为 `false`. + * `medialCapitalAsWordStart` Boolean - 当配合 `wordStart`的时候,接受一个文字中的匹配项,要求匹配项是以大写字母开头后面跟小写字母或者没有字母。可以接受一些其他单词内部匹配, 默认为 `false`. + +发起一个请求来寻找页面中的所有匹配 `text` 的地方并且返回一个 `Integer`来表示这个请求用的请求Id. 这个请求结果可以通过订阅[`found-in-page`](web-view-tag.md#event-found-in-page) 事件来取得. + +### `.stopFindInPage(action)` + +* `action` String - 指定一个行为来接替停止 + [`.findInPage`](web-view-tag.md#webviewtagfindinpage) 请求. + * `clearSelection` - 转变为一个普通的 selection. + * `keepSelection` - 清除 selection. + * `activateSelection` - 聚焦并点击 selection node. + +使用 `action` 停止 `findInPage` 请求. + +### `.print([options])` + +打印输出 `webview` 的 web page. 类似 `webContents.print([options])`. + +### `.printToPDF(options, callback)` + +以pdf格式打印输出 `webview` 的 web page. 类似 `webContents.printToPDF(options, callback)`. + +### `.send(channel[, arg1][, arg2][, ...])` + +* `channel` String +* `arg` (可选) + +通过 `channel` 向渲染进程发出异步消息,你也可以发送任意的参数。 +渲染进程通过`ipcRenderer` 模块监听 `channel` 事件来控制消息. + +例子 +[webContents.send](web-contents.md#webcontentssendchannel-args). + +### `.sendInputEvent(event)` + +* `event` Object + +向 page 发送输入事件. + +查看 [webContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent) +关于 `event` 对象的相信介绍. + +### `.getWebContents()` + +返回和这个 `webview` 相关的 [WebContents](web-contents.md). + +## DOM 事件 + +`webview` 可用下面的 DOM 事件: + +### Event: 'load-commit' + +返回: + +* `url` String +* `isMainFrame` Boolean + +加载完成触发. 这个包含当前文档的导航和副框架的文档加载,但是不包含异步资源加载. + +### Event: 'did-finish-load' + +在导航加载完成时触发,也就是tab 的 spinner停止spinning,并且加载事件处理. + +### Event: 'did-fail-load' + +Returns: + +* `errorCode` Integer +* `errorDescription` String +* `validatedURL` String + +类似 `did-finish-load` ,在加载失败或取消是触发,例如提出 `window.stop()`. + +### Event: 'did-frame-finish-load' + +返回: + +* `isMainFrame` Boolean + +当一个 frame 完成 加载时触发. + +### Event: 'did-start-loading' + +开始加载时触发. + +### Event: 'did-stop-loading' + +停止家在时触发. + +### Event: 'did-get-response-details' + +返回: + +* `status` Boolean +* `newURL` String +* `originalURL` String +* `httpResponseCode` Integer +* `requestMethod` String +* `referrer` String +* `headers` Object + +当获得返回详情的时候触发. + +`status` 指示 socket 连接来下载资源. + +### Event: 'did-get-redirect-request' + +返回: + +* `oldURL` String +* `newURL` String +* `isMainFrame` Boolean + +当重定向请求资源被接收的时候触发. + +### Event: 'dom-ready' + +当指定的frame文档加载完毕时触发. + +### Event: 'page-title-updated' + +返回: + +* `title` String +* `explicitSet` Boolean + +当导航中的页面title被设置时触发. +在title通过文档路径异步加载时`explicitSet`为false. + +### Event: 'page-favicon-updated' + +返回: + +* `favicons` Array - Array of URLs. + +当page收到了图标url时触发. + +### Event: 'enter-html-full-screen' + +当通过HTML API使界面进入全屏时触发. + +### Event: 'leave-html-full-screen' + +当通过HTML API使界面退出全屏时触发. + +### Event: 'console-message' + +返回: + +* `level` Integer +* `message` String +* `line` Integer +* `sourceId` String + +当客户端输出控制台信息的时候触发. + +下面示例代码将所有信息输出到内置控制台,没有考虑到输出等级和其他属性。 + +```javascript +webview.addEventListener('console-message', function(e) { + console.log('Guest page logged a message:', e.message); +}); +``` + +### Event: 'found-in-page' + +返回: + +* `result` Object + * `requestId` Integer + * `finalUpdate` Boolean - 指明下面是否还有更多的回应. + * `matches` Integer (optional) - 匹配数量. + * `selectionArea` Object (optional) - 整合第一个匹配域. + +在请求[`webview.findInPage`](web-view-tag.md#webviewtagfindinpage)结果有效时触发. + +```javascript +webview.addEventListener('found-in-page', function(e) { + if (e.result.finalUpdate) + webview.stopFindInPage("keepSelection"); +}); + +const rquestId = webview.findInPage("test"); +``` + +### Event: 'new-window' + +返回: + +* `url` String +* `frameName` String +* `disposition` String - 可以为 `default`, `foreground-tab`, `background-tab`, + `new-window` 和 `other`. +* `options` Object - 参数应该被用作创建新的 + `BrowserWindow`. + +在 guest page 试图打开一个新的浏览器窗口时触发. + +下面示例代码在系统默认浏览器中打开了一个新的url. + +```javascript +webview.addEventListener('new-window', function(e) { + require('electron').shell.openExternal(e.url); +}); +``` + +### Event: 'will-navigate' + +返回: + +* `url` String + +当用户或page尝试开始导航时触发. +它能在 `window.location` 变化或者用户点击连接的时候触发. + +这个事件在以 APIS 编程方式开始导航时不会触发,例如 `.loadURL` 和 `.back`. + +在页面内部导航跳转也将不回触发这个事件,例如点击锚链接或更新 `window.location.hash`.使用 `did-navigate-in-page` 来实现页内跳转事件. + +使用 `event.preventDefault()` 并不会起什么用. + +### Event: 'did-navigate' + +返回: + +* `url` String + +当导航结束时触发. + +在页面内部导航跳转也将不回触发这个事件,例如点击锚链接或更新 `window.location.hash`.使用 `did-navigate-in-page` 来实现页内跳转事件. + +### Event: 'did-navigate-in-page' + +返回: + +* `url` String + +当页内导航发生时触发. +当业内导航发生时,page url改变了,但是不会跳出 page . 例如在锚链接被电击或DOM `hashchange` 事件发生时触发. + +### Event: 'close' + +在 guest page试图关闭自己的时候触发. + +下面的示例代码指示了在客户端试图关闭自己的时候将改变导航连接为`about:blank`. + +```javascript +webview.addEventListener('close', function() { + webview.src = 'about:blank'; +}); +``` + +### Event: 'ipc-message' + +返回: + +* `channel` String +* `args` Array + +在 guest page 向嵌入页发送一个异步消息的时候触发. + +你可以很简单的使用 `sendToHost` 方法和 `ipc-message` 事件在 guest page 和 嵌入页(embedder page)之间通信: + +```javascript +// In embedder page. +webview.addEventListener('ipc-message', function(event) { + console.log(event.channel); + // Prints "pong" +}); +webview.send('ping'); +``` + +```javascript +// In guest page. +var ipcRenderer = require('electron').ipcRenderer; +ipcRenderer.on('ping', function() { + ipcRenderer.sendToHost('pong'); +}); +``` + +### Event: 'crashed' + +在渲染进程崩溃的时候触发. + +### Event: 'gpu-crashed' + +在GPU进程崩溃的时候触发. + +### Event: 'plugin-crashed' + +返回: + +* `name` String +* `version` String + +在插件进程崩溃的时候触发. + +### Event: 'destroyed' + +在界面内容销毁的时候触发. + +### Event: 'media-started-playing' + +在媒体准备播放的时候触发. + +### Event: 'media-paused' + +在媒体暂停播放或播放放毕的时候触发. + +### Event: 'did-change-theme-color' + +在页面的主体色改变的时候触发. +在使用 meta 标签的时候这就很常见了: + +```html + +``` + +### Event: 'devtools-opened' + +在开发者工具打开的时候触发. + +### Event: 'devtools-closed' + +在开发者工具关闭的时候触发. + +### Event: 'devtools-focused' + +在开发者工具获取焦点的时候触发. + +[blink-feature-string]: https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/platform/RuntimeEnabledFeatures.cpp&sq=package:chromium&type=cs&l=527 \ No newline at end of file From 0b8c2545b98435654a3a437efad1ff43655ad623 Mon Sep 17 00:00:00 2001 From: Daniel Pham Date: Tue, 8 Mar 2016 22:31:13 -0500 Subject: [PATCH 400/688] :memo: Document 'app.focus()' [ci skip] --- docs/api/app.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index f18c978fadd..36b55244a4d 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -248,14 +248,6 @@ This method guarantees that all `beforeunload` and `unload` event handlers are correctly executed. It is possible that a window cancels the quitting by returning `false` in the `beforeunload` event handler. -### `app.hide()` _OS X_ - -Hides all application windows without minimizing them. - -### `app.show()` _OS X_ - -Shows application windows after they were hidden. Does not automatically focus them. - ### `app.exit(exitCode)` * `exitCode` Integer @@ -265,6 +257,18 @@ Exits immediately with `exitCode`. All windows will be closed immediately without asking user and the `before-quit` and `will-quit` events will not be emitted. +### `app.focus()` + +On Linux, focuses on the first visible window. On OS X, makes the application the active app. On Windows, focuses on the application's first window. + +### `app.hide()` _OS X_ + +Hides all application windows without minimizing them. + +### `app.show()` _OS X_ + +Shows application windows after they were hidden. Does not automatically focus them. + ### `app.getAppPath()` Returns the current application directory. From 51f60d8d73c4d01c8c00a8ee87fd807da31a0cad Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Wed, 9 Mar 2016 23:23:22 +0800 Subject: [PATCH 401/688] add window.open --- docs-translations/zh-CN/api/web-view-tag.md | 4 +- docs-translations/zh-CN/api/window-open.md | 60 +++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 docs-translations/zh-CN/api/window-open.md diff --git a/docs-translations/zh-CN/api/web-view-tag.md b/docs-translations/zh-CN/api/web-view-tag.md index 819d57cb459..f1f3ef9080c 100644 --- a/docs-translations/zh-CN/api/web-view-tag.md +++ b/docs-translations/zh-CN/api/web-view-tag.md @@ -1,6 +1,6 @@ # `` 标签 -使用 `webview` 标签来把 'guest' 内容(例如 web pages )嵌入到你的 Electron app 中. guest内容包含在 `webview` 容器中.一个嵌入你的应用的page控制着guest内容如何布局摆放和表达含义. +使用 `webview` 标签来把 'guest' 内容(例如 web pages )嵌入到你的 Electron app 中. guest内容包含在 `webview` 容器中.一个嵌入你应用的page控制着guest内容如何布局摆放和表达含义. 与 `iframe` 不同, `webview` 和你的应用运行的是不同的进程. 它不拥有渲染进程的权限,并且应用和嵌入内容之间的交互全部都是异步的.因为这能保证应用的安全性不受嵌入内容的影响. @@ -64,7 +64,7 @@ ``` -如果这个属性的值为 "on" , `webview` 中的 guest page 将整合node,并且拥有可以使用系统底层的资源,例如 `require` 和 `process` . +如果设置了这个属性, `webview` 中的 guest page 将整合node,并且拥有可以使用系统底层的资源,例如 `require` 和 `process` . ### `plugins` diff --git a/docs-translations/zh-CN/api/window-open.md b/docs-translations/zh-CN/api/window-open.md new file mode 100644 index 00000000000..a8ef042b0e3 --- /dev/null +++ b/docs-translations/zh-CN/api/window-open.md @@ -0,0 +1,60 @@ +# `window.open` 函数 + +当在界面中使用 `window.open` 来创建一个新的窗口时候,将会创建一个 `BrowserWindow` 的实例,并且将返回一个标识,这个界面通过标识来对这个新的窗口进行有限的控制. + +这个标识对传统的web界面来说,通过它能对子窗口进行有限的功能性兼容控制. +想要完全的控制这个窗口,可以直接创建一个 `BrowserWindow` . + +新创建的 `BrowserWindow` 默认为继承父窗口的属性参数,想重写属性的话可以在 `features` 中设置他们. + +### `window.open(url[, frameName][, features])` + +* `url` String +* `frameName` String (可选) +* `features` String (可选) + +创建一个新的window并且返回一个 `BrowserWindowProxy` 类的实例. + + `features` 遵循标准浏览器的格式,但是每个feature 应该作为 `BrowserWindow` 参数的一个字段. + +### `window.opener.postMessage(message, targetOrigin)` + +* `message` String +* `targetOrigin` String + +通过指定位置或用 `*` 来代替没有明确位置来向父窗口发送信息. + +## Class: BrowserWindowProxy + +`BrowserWindowProxy` 由`window.open` 创建返回,并且提供了对子窗口的有限功能性控制. + +### `BrowserWindowProxy.blur()` + +取消对子窗口的聚焦. +### `BrowserWindowProxy.close()` + +强行关闭子窗口,忽略卸载事件. + +### `BrowserWindowProxy.closed` + +在子窗口关闭之后恢复正常. + +### `BrowserWindowProxy.eval(code)` + +* `code` String + +评估子窗口的代码. + +### `BrowserWindowProxy.focus()` + +聚焦子窗口(让其现实在最前). + +### `BrowserWindowProxy.postMessage(message, targetOrigin)` + +* `message` String +* `targetOrigin` String + + +通过指定位置或用 `*` 来代替没有明确位置来向子窗口发送信息. + +除了这些方法,子窗口还可以无特性和使用单一方法来实现 `window.opener` 对象. \ No newline at end of file From 4c45c80fb4c373186b70c7c96fee37e3f01d654e Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 10 Mar 2016 00:20:52 +0900 Subject: [PATCH 402/688] :memo: Update as upstream --- docs-translations/ko-KR/api/accelerator.md | 3 +++ docs-translations/ko-KR/api/app.md | 9 +++++++ docs-translations/ko-KR/api/browser-window.md | 12 +++++----- docs-translations/ko-KR/api/menu.md | 4 +++- docs-translations/ko-KR/api/synopsis.md | 4 ++-- docs-translations/ko-KR/api/web-contents.md | 8 ++----- .../ko-KR/development/coding-style.md | 24 +++++++++++++------ .../desktop-environment-integration.md | 14 +++++------ 8 files changed, 48 insertions(+), 30 deletions(-) diff --git a/docs-translations/ko-KR/api/accelerator.md b/docs-translations/ko-KR/api/accelerator.md index 99b549bbb70..90adf414dc3 100644 --- a/docs-translations/ko-KR/api/accelerator.md +++ b/docs-translations/ko-KR/api/accelerator.md @@ -22,6 +22,8 @@ Linux와 Windows에서는 `Command`키가 없으므로 작동하지 않습니다 * `Control` (단축어 `Ctrl`) * `CommandOrControl` (단축어 `CmdOrCtrl`) * `Alt` +* `Option` +* `AltGr` * `Shift` * `Super` @@ -43,5 +45,6 @@ Linux와 Windows에서는 `Command`키가 없으므로 작동하지 않습니다 * `Escape` (단축어 `Esc`) * `VolumeUp`, `VolumeDown` 그리고 `VolumeMute` * `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` 그리고 `MediaPlayPause` +* `PrintScreen` __키코드는 `단축어`로도 사용할 수 있습니다__ diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 048026e0d59..72da6862741 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -236,6 +236,10 @@ app.on('login', function(event, webContents, request, authInfo, callback) { GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입니다. +### Event: 'platform-theme-changed' _OS X_ + +시스템의 다크 모드 테마가 토글되면 발생하는 이벤트입니다. + ## Methods `app` 객체는 다음과 같은 메서드를 가지고 있습니다: @@ -471,6 +475,11 @@ if (browserOptions.transparent) { } ``` +### `app.isDarkMode()` _OS X_ + +이 메서드는 시스템이 다크 모드 상태인 경우 `true`를 반환하고 아닐 경우 `false`를 +반환합니다. + ### `app.commandLine.appendSwitch(switch[, value])` Chrominum의 명령줄에 스위치를 추가합니다. `value`는 추가적인 값을 뜻하며 옵션입니다. diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 8bc4a1545fc..3517f3d500c 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -59,8 +59,8 @@ win.show(); * `alwaysOnTop` Boolean - 윈도우이 언제나 다른 창들 위에 유지되는지 여부. 기본값은 `false`입니다. * `fullscreen` Boolean - 윈도우의 전체화면 활성화 여부. 이 속성을 명시적으로 - `false`로 지정했을 경우, OS X에선 전체화면 버튼이 숨겨지거나 비활성화되고, - Windows에선 최대화 버튼이 비활성화됩니다. 기본값은 `false` 입니다. + `false`로 지정했을 경우, OS X에선 전체화면 버튼이 숨겨지거나 비활성됩니다. 기본값은 + `false` 입니다. * `fullscreenable` Boolean - OS X의 최대화/줌 버튼이 전체화면 모드 또는 윈도우 최대화를 토글할 수 있게 할지 여부입니다. 기본값은 `true` 입니다. * `skipTaskbar` Boolean - 작업표시줄 어플리케이션 아이콘 표시 스킵 여부. 기본값은 @@ -575,17 +575,17 @@ var win = new BrowserWindow({ width: 800, height: 600 }); 사용자에 의해 윈도우를 최대화시킬 수 있는지 여부를 반환합니다. Linux에선 항상 `true`를 반환합니다. -### `win.setFullScreenable(fullscreenable)` _OS X_ +### `win.setFullScreenable(fullscreenable)` * `fullscreenable` Boolean 최대화/줌 버튼이 전체화면 모드 또는 윈도우 최대화를 토글할 수 있게 할지 여부를 -지정합니다. Windows와 Linux에선 아무 일도 일어나지 않습니다. +지정합니다. -### `win.isFullScreenable()` _OS X_ +### `win.isFullScreenable()` 최대화/줌 버튼이 전체화면 모드 또는 윈도우 최대화를 토글할 수 있게 할지 여부를 -반환합니다. Windows와 Linux에선 항상 `true`를 반환합니다. +반환합니다. ### `win.setClosable(closable)` _OS X_ _Windows_ diff --git a/docs-translations/ko-KR/api/menu.md b/docs-translations/ko-KR/api/menu.md index 61c68023b07..1ea8289a9ce 100644 --- a/docs-translations/ko-KR/api/menu.md +++ b/docs-translations/ko-KR/api/menu.md @@ -223,7 +223,9 @@ Linux에선 각 창의 상단에 표시됩니다. `action`을 어플리케이션의 first responder에 전달합니다. 이 메서드는 Cocoa 메뉴 동작을 에뮬레이트 하는데 사용되며 보통 `MenuItem`의 `role` 속성에 사용됩니다. -**참고:** 이 메서드는 OS X에서만 사용할 수 있습니다. +OS X의 네이티브 액션에 대해 자세히 알아보려면 +[OS X Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7) +문서를 참고하세요. ### `Menu.buildFromTemplate(template)` diff --git a/docs-translations/ko-KR/api/synopsis.md b/docs-translations/ko-KR/api/synopsis.md index e70dfbb3349..8f59d12c1ce 100644 --- a/docs-translations/ko-KR/api/synopsis.md +++ b/docs-translations/ko-KR/api/synopsis.md @@ -49,7 +49,7 @@ app.on('ready', function() { ## 분리 할당 만약 CoffeeScript나 Babel을 사용하고 있다면, 빌트인 모듈을 사용할 때 -[분리 할당][desctructuring-assignment]을 통해 직관적으로 사용할 수 있습니다: +[분리 할당][destructuring-assignment]을 통해 직관적으로 사용할 수 있습니다: ```javascript const {app, BrowserWindow} = require('electron') @@ -78,5 +78,5 @@ require('electron').hideInternalModules() ``` [gui]: https://en.wikipedia.org/wiki/Graphical_user_interface -[desctructuring-assignment]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment +[destructuring-assignment]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment [issue-387]: https://github.com/atom/electron/issues/387 diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index ed2f05f1d5a..96b5eacc544 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -758,12 +758,8 @@ Input `event`를 웹 페이지로 전송합니다. 키보드 이벤트들에 대해서는 `event` 객체는 다음 속성들을 사용할 수 있습니다: -* `keyCode` Char or String (**required**) - 키보드 이벤트로 보내지는 문자. 단일 - UTF-8 문자를 사용할 수 있고 이벤트를 발생시키는 다음 키 중 하나를 포함할 수 있습니다: - `enter`, `backspace`, `delete`, `tab`, `escape`, `control`, `alt`, `altgr` - (Windows 전용), `shift`, `end`, `home`, `insert`, `left`, `up`, `right`, - `down`, `pageUp`, `pageDown`, `printScreen`, `meta`, `cmd` (OSX 전용), - `command` (OSX 전용), `option` (OSX 전용) +* `keyCode` String (**required**) - 키보드 이벤트가 발생할 때 보내질 문자. + [Accelerator](accelerator.md)의 올바른 키 코드만 사용해야 합니다. 마우스 이벤트들에 대해서는 `event` 객체는 다음 속성들을 사용할 수 있습니다: diff --git a/docs-translations/ko-KR/development/coding-style.md b/docs-translations/ko-KR/development/coding-style.md index 21ee03fd0a1..dd64e724517 100644 --- a/docs-translations/ko-KR/development/coding-style.md +++ b/docs-translations/ko-KR/development/coding-style.md @@ -2,6 +2,9 @@ 이 가이드는 Electron의 코딩 스타일에 관해 설명합니다. +`npm run lint`를 실행하여 `cpplint`와 `eslint`를 통해 어떤 코딩 스타일 이슈를 확인할 +수 있습니다. + ## C++과 Python C++과 Python 스크립트는 Chromium의 @@ -18,17 +21,24 @@ C++ 코드는 많은 Chromium의 추상화와 타입을 사용합니다. 따라 자동으로 메모리에서 할당을 해제합니다. 스마트 포인터와 같습니다) 그리고 로깅 메커니즘 등을 언급하고 있습니다. -## CoffeeScript - -CoffeeScript의 경우 GitHub의 -[스타일 가이드](https://github.com/styleguide/javascript)를 기본으로 따릅니다. -그리고 추가로 다음 규칙을 따릅니다: +## JavaScript +* 하드 탭(hard tabs) 대신 소프트 탭(2 spaces) 들여쓰기를 사용합니다. +* 항상 구문의 끝은 `;`으로 마쳐야 합니다. * Google의 코딩 스타일에도 맞추기 위해 파일의 끝에는 **절대** 개행을 삽입해선 안됩니다. * 파일 이름의 공백은 `_`대신에 `-`을 사용하여야 합니다. 예를 들어 -`file_name.coffee`를 `file-name.coffee`로 고쳐야합니다. 왜냐하면 +`file_name.js`를 `file-name.js`로 고쳐야합니다. 왜냐하면 [github/atom](https://github.com/github/atom)에서 사용되는 모듈의 이름은 보통 -`module-name` 형식이기 때문입니다. 이 규칙은 '.coffee' 파일에만 적용됩니다. +`module-name` 형식이기 때문입니다. 이 규칙은 '.js' 파일에만 적용됩니다. +* 적절한 곳에 새로운 ES6/ES2015 문법을 사용해도 됩니다. + * [`const`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) + 는 requires와 다른 상수에 사용합니다 + * [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) + 은 변수를 정의할 때 사용합니다 + * [Arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) + 는 `function () { }` 표현 대신에 사용합니다 + * [Template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) + 는 `+`로 문자열을 합치는 대신 사용합니다. ## API 이름 diff --git a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md index 38830b91e82..c72af78a278 100644 --- a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md +++ b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md @@ -239,22 +239,20 @@ __Audacious의 런처 숏컷:__ ![audacious](https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles?action=AttachFile&do=get&target=shortcuts.png) -## Taskbar progress 기능 (Windows & Unity) +## 작업 표시줄 안의 프로그래스 바 (Windows, OS X, Unity) -Windows에선 태스크바의 어플리케이션 버튼에 progress bar를 추가할 수 있습니다. +Windows에선 작업 표시줄의 어플리케이션 버튼에 프로그래스 바를 추가할 수 있습니다. 이 기능은 사용자가 어플리케이션의 창을 열지 않고도 어플리케이션의 작업의 상태 정보를 시각적으로 보여줄 수 있도록 해줍니다. -또한 Unity DE도 런처에 progress bar를 부착할 수 있습니다. +OS X에선 프로그래스바가 dock 아이콘의 일부에 표시됩니다. -__태스크바 버튼의 progress bar:__ +또한 Unity DE도 런처에 프로그래스 바를 부착할 수 있습니다. + +__작업 표시줄 버튼의 프로그래스 바:__ ![Taskbar Progress Bar](https://cloud.githubusercontent.com/assets/639601/5081682/16691fda-6f0e-11e4-9676-49b6418f1264.png) -__Unity 런처의 progress bar:__ - -![Unity Launcher](https://cloud.githubusercontent.com/assets/639601/5081747/4a0a589e-6f0f-11e4-803f-91594716a546.png) - 이 기능은 [BrowserWindow.setProgressBar][setprogressbar] API를 사용하여 구현할 수 있습니다: From ebf509bbe406bc04b97dde4b4581edfb0b5b35c3 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 10 Mar 2016 16:54:07 +0900 Subject: [PATCH 403/688] :memo: Adjust 80 chars per line [ci skip] --- docs/api/app.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/api/app.md b/docs/api/app.md index 36b55244a4d..8935ed894f0 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -259,7 +259,8 @@ and `will-quit` events will not be emitted. ### `app.focus()` -On Linux, focuses on the first visible window. On OS X, makes the application the active app. On Windows, focuses on the application's first window. +On Linux, focuses on the first visible window. On OS X, makes the application +the active app. On Windows, focuses on the application's first window. ### `app.hide()` _OS X_ From 9bc9a1a2bde2b141788f536ec7aaca2cf8091913 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 8 Mar 2016 10:05:44 +0900 Subject: [PATCH 404/688] Upgrade to Chrome 49 --- atom/common/chrome_version.h | 2 +- script/lib/config.py | 2 +- vendor/brightray | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/common/chrome_version.h b/atom/common/chrome_version.h index 37a5c64979e..604e0161c3a 100644 --- a/atom/common/chrome_version.h +++ b/atom/common/chrome_version.h @@ -8,7 +8,7 @@ #ifndef ATOM_COMMON_CHROME_VERSION_H_ #define ATOM_COMMON_CHROME_VERSION_H_ -#define CHROME_VERSION_STRING "47.0.2526.110" +#define CHROME_VERSION_STRING "49.0.2623.64" #define CHROME_VERSION "v" CHROME_VERSION_STRING #endif // ATOM_COMMON_CHROME_VERSION_H_ diff --git a/script/lib/config.py b/script/lib/config.py index d4a055912e4..10319a2df4e 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'ff714bf7ad79b0d278bcd20c3081a69b40be8bb8' +LIBCHROMIUMCONTENT_COMMIT = 'a661ccb38f21859309cc97c1fc313f1360101462' PLATFORM = { 'cygwin': 'win32', diff --git a/vendor/brightray b/vendor/brightray index d06de26dff8..b409ed14a17 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit d06de26dff8b641d9aee4c78ee830b416710f554 +Subproject commit b409ed14a17b9efc9f184e102a1b94e9d573760f From 30643cf1189f37df1215210620353090e9e174cf Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 8 Mar 2016 17:58:59 +0900 Subject: [PATCH 405/688] Update crashpad to lastest branch --- common.gypi | 2 ++ vendor/brightray | 2 +- vendor/crashpad | 2 +- vendor/native_mate | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/common.gypi b/common.gypi index 7c41c3616df..d8c7ee30935 100644 --- a/common.gypi +++ b/common.gypi @@ -4,6 +4,8 @@ 'vendor/brightray/brightray.gypi', ], 'variables': { + # Tell crashpad to build as external project. + 'crashpad_dependencies': 'external', # Required by breakpad. 'os_bsd': 0, 'chromeos': 0, diff --git a/vendor/brightray b/vendor/brightray index b409ed14a17..bde67658749 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit b409ed14a17b9efc9f184e102a1b94e9d573760f +Subproject commit bde67658749c6f947e2dc505cce19e621d2ad2eb diff --git a/vendor/crashpad b/vendor/crashpad index 5b777419c30..60f6e1964d0 160000 --- a/vendor/crashpad +++ b/vendor/crashpad @@ -1 +1 @@ -Subproject commit 5b777419c303d8aa7930239d8ef755475f1ede57 +Subproject commit 60f6e1964d02b5818f038ba618f9cf040fdce962 diff --git a/vendor/native_mate b/vendor/native_mate index e719eab878c..38834cb9974 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit e719eab878c264bb03188d0cd6eb9ad6882bc13a +Subproject commit 38834cb9974da9ddbc06c36f9ff23d7fa1918b03 From 3600645575bdcda35447bd78ef1625dad29dc754 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 8 Mar 2016 21:00:37 +0900 Subject: [PATCH 406/688] Fix the compilation errors from brightray and crashpad --- vendor/brightray | 2 +- vendor/crashpad | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/brightray b/vendor/brightray index bde67658749..2a29ea6c1de 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit bde67658749c6f947e2dc505cce19e621d2ad2eb +Subproject commit 2a29ea6c1de3accd01f1883ac94326220349bbe1 diff --git a/vendor/crashpad b/vendor/crashpad index 60f6e1964d0..db713da7554 160000 --- a/vendor/crashpad +++ b/vendor/crashpad @@ -1 +1 @@ -Subproject commit 60f6e1964d02b5818f038ba618f9cf040fdce962 +Subproject commit db713da7554f565e43c6dcf9a51b59ccc4f06066 From 8d021f25964c79317ed7b3bde3cde18eba59b6e7 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 7 Mar 2016 20:21:47 -0800 Subject: [PATCH 407/688] Goodbye pdf.dll --- atom.gyp | 1 - 1 file changed, 1 deletion(-) diff --git a/atom.gyp b/atom.gyp index b7075301894..f4c6976050e 100644 --- a/atom.gyp +++ b/atom.gyp @@ -143,7 +143,6 @@ ], }, { 'copied_libraries': [ - '<(libchromiumcontent_dir)/pdf.dll', '<(libchromiumcontent_dir)/ffmpeg.dll', ], }], From 7f15a77f3c1c8d59197f8ab0997dff0c108859b7 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 7 Mar 2016 20:32:54 -0800 Subject: [PATCH 408/688] startup helper is renamed --- atom/app/atom_main.cc | 2 +- filenames.gypi | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/atom/app/atom_main.cc b/atom/app/atom_main.cc index 1ffab8d9225..cbd0a85d576 100644 --- a/atom/app/atom_main.cc +++ b/atom/app/atom_main.cc @@ -16,7 +16,7 @@ #include "atom/common/crash_reporter/win/crash_service_main.h" #include "base/environment.h" #include "base/win/windows_version.h" -#include "content/public/app/startup_helper_win.h" +#include "content/public/app/sandbox_helper_win.h" #include "sandbox/win/src/sandbox_types.h" #include "ui/gfx/win/dpi.h" #elif defined(OS_LINUX) // defined(OS_WIN) diff --git a/filenames.gypi b/filenames.gypi index f9e19550c89..baf0202f3ec 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -534,7 +534,6 @@ 'atom/browser/resources/win/resource.h', 'atom/browser/resources/win/atom.ico', 'atom/browser/resources/win/atom.rc', - '<(libchromiumcontent_src_dir)/content/app/startup_helper_win.cc', # Cursors. '<(libchromiumcontent_src_dir)/ui/resources/cursors/aliasb.cur', '<(libchromiumcontent_src_dir)/ui/resources/cursors/cell.cur', From d2944c62a5dd58de13ebed4e7b55529c9c309b74 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 7 Mar 2016 20:38:49 -0800 Subject: [PATCH 409/688] basictypes.h => macros.h --- atom/app/atom_library_main.h | 2 +- atom/browser/auto_updater.h | 2 +- atom/browser/browser.h | 2 +- atom/browser/javascript_environment.h | 2 +- atom/browser/ui/views/global_menu_bar_x11.h | 2 +- atom/browser/ui/win/notify_icon.h | 2 +- atom/browser/window_list.h | 2 +- atom/common/api/object_life_monitor.h | 2 +- atom/common/atom_command_line.h | 2 +- atom/common/crash_reporter/crash_reporter.h | 2 +- atom/common/crash_reporter/linux/crash_dump_handler.h | 2 +- atom/common/crash_reporter/win/crash_service.h | 2 +- atom/common/native_mate_converters/v8_value_converter.h | 2 +- atom/common/node_bindings.h | 2 +- atom/renderer/node_array_buffer_bridge.cc | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/atom/app/atom_library_main.h b/atom/app/atom_library_main.h index 899861f610b..b45e27a4a99 100644 --- a/atom/app/atom_library_main.h +++ b/atom/app/atom_library_main.h @@ -5,7 +5,7 @@ #ifndef ATOM_APP_ATOM_LIBRARY_MAIN_H_ #define ATOM_APP_ATOM_LIBRARY_MAIN_H_ -#include "base/basictypes.h" +#include "base/macros.h" #if defined(OS_MACOSX) extern "C" { diff --git a/atom/browser/auto_updater.h b/atom/browser/auto_updater.h index 9e479d4220d..637545e877f 100644 --- a/atom/browser/auto_updater.h +++ b/atom/browser/auto_updater.h @@ -7,7 +7,7 @@ #include -#include "base/basictypes.h" +#include "base/macros.h" namespace base { class Time; diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 1d0b4aec8ba..d976fae675c 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -8,7 +8,7 @@ #include #include -#include "base/basictypes.h" +#include "base/macros.h" #include "base/compiler_specific.h" #include "base/observer_list.h" #include "base/strings/string16.h" diff --git a/atom/browser/javascript_environment.h b/atom/browser/javascript_environment.h index 20f1667c3b8..07cd602cf00 100644 --- a/atom/browser/javascript_environment.h +++ b/atom/browser/javascript_environment.h @@ -5,7 +5,7 @@ #ifndef ATOM_BROWSER_JAVASCRIPT_ENVIRONMENT_H_ #define ATOM_BROWSER_JAVASCRIPT_ENVIRONMENT_H_ -#include "base/basictypes.h" +#include "base/macros.h" #include "gin/public/isolate_holder.h" namespace atom { diff --git a/atom/browser/ui/views/global_menu_bar_x11.h b/atom/browser/ui/views/global_menu_bar_x11.h index 9049fbf606d..89b2680cabe 100644 --- a/atom/browser/ui/views/global_menu_bar_x11.h +++ b/atom/browser/ui/views/global_menu_bar_x11.h @@ -7,7 +7,7 @@ #include -#include "base/basictypes.h" +#include "base/macros.h" #include "base/compiler_specific.h" #include "ui/base/glib/glib_signal.h" #include "ui/gfx/native_widget_types.h" diff --git a/atom/browser/ui/win/notify_icon.h b/atom/browser/ui/win/notify_icon.h index 23608c7c7ab..53ed49b937c 100644 --- a/atom/browser/ui/win/notify_icon.h +++ b/atom/browser/ui/win/notify_icon.h @@ -11,7 +11,7 @@ #include #include "atom/browser/ui/tray_icon.h" -#include "base/basictypes.h" +#include "base/macros.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/win/scoped_gdi_object.h" diff --git a/atom/browser/window_list.h b/atom/browser/window_list.h index bfb9a2b0aec..3dd87b2c34c 100644 --- a/atom/browser/window_list.h +++ b/atom/browser/window_list.h @@ -7,7 +7,7 @@ #include -#include "base/basictypes.h" +#include "base/macros.h" #include "base/lazy_instance.h" #include "base/observer_list.h" diff --git a/atom/common/api/object_life_monitor.h b/atom/common/api/object_life_monitor.h index 90216d8227a..4c932b94c7b 100644 --- a/atom/common/api/object_life_monitor.h +++ b/atom/common/api/object_life_monitor.h @@ -5,7 +5,7 @@ #ifndef ATOM_COMMON_API_OBJECT_LIFE_MONITOR_H_ #define ATOM_COMMON_API_OBJECT_LIFE_MONITOR_H_ -#include "base/basictypes.h" +#include "base/macros.h" #include "base/memory/weak_ptr.h" #include "v8/include/v8.h" diff --git a/atom/common/atom_command_line.h b/atom/common/atom_command_line.h index 7c8840f7075..56ecb8fbd49 100644 --- a/atom/common/atom_command_line.h +++ b/atom/common/atom_command_line.h @@ -8,7 +8,7 @@ #include #include -#include "base/basictypes.h" +#include "base/macros.h" namespace atom { diff --git a/atom/common/crash_reporter/crash_reporter.h b/atom/common/crash_reporter/crash_reporter.h index 98832fea45d..eebbe16dca8 100644 --- a/atom/common/crash_reporter/crash_reporter.h +++ b/atom/common/crash_reporter/crash_reporter.h @@ -10,7 +10,7 @@ #include #include -#include "base/basictypes.h" +#include "base/macros.h" namespace crash_reporter { diff --git a/atom/common/crash_reporter/linux/crash_dump_handler.h b/atom/common/crash_reporter/linux/crash_dump_handler.h index f600c9e0d1b..00161f02ee5 100644 --- a/atom/common/crash_reporter/linux/crash_dump_handler.h +++ b/atom/common/crash_reporter/linux/crash_dump_handler.h @@ -6,7 +6,7 @@ #ifndef ATOM_COMMON_CRASH_REPORTER_LINUX_CRASH_DUMP_HANDLER_H_ #define ATOM_COMMON_CRASH_REPORTER_LINUX_CRASH_DUMP_HANDLER_H_ -#include "base/basictypes.h" +#include "base/macros.h" #include "vendor/breakpad/src/common/simple_string_dictionary.h" namespace crash_reporter { diff --git a/atom/common/crash_reporter/win/crash_service.h b/atom/common/crash_reporter/win/crash_service.h index 7195ec2a958..c05e0d5bf6e 100644 --- a/atom/common/crash_reporter/win/crash_service.h +++ b/atom/common/crash_reporter/win/crash_service.h @@ -7,7 +7,7 @@ #include -#include "base/basictypes.h" +#include "base/macros.h" #include "base/files/file_path.h" #include "base/synchronization/lock.h" diff --git a/atom/common/native_mate_converters/v8_value_converter.h b/atom/common/native_mate_converters/v8_value_converter.h index 95840c01ba7..632587022d1 100644 --- a/atom/common/native_mate_converters/v8_value_converter.h +++ b/atom/common/native_mate_converters/v8_value_converter.h @@ -5,7 +5,7 @@ #ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_V8_VALUE_CONVERTER_H_ #define ATOM_COMMON_NATIVE_MATE_CONVERTERS_V8_VALUE_CONVERTER_H_ -#include "base/basictypes.h" +#include "base/macros.h" #include "base/compiler_specific.h" #include "v8/include/v8.h" diff --git a/atom/common/node_bindings.h b/atom/common/node_bindings.h index 93ad7714916..16d512d3bed 100644 --- a/atom/common/node_bindings.h +++ b/atom/common/node_bindings.h @@ -5,7 +5,7 @@ #ifndef ATOM_COMMON_NODE_BINDINGS_H_ #define ATOM_COMMON_NODE_BINDINGS_H_ -#include "base/basictypes.h" +#include "base/macros.h" #include "base/memory/weak_ptr.h" #include "v8/include/v8.h" #include "vendor/node/deps/uv/include/uv.h" diff --git a/atom/renderer/node_array_buffer_bridge.cc b/atom/renderer/node_array_buffer_bridge.cc index 80f2530524d..c4b8d26adaa 100644 --- a/atom/renderer/node_array_buffer_bridge.cc +++ b/atom/renderer/node_array_buffer_bridge.cc @@ -4,7 +4,7 @@ #include "atom/renderer/node_array_buffer_bridge.h" -#include "base/basictypes.h" +#include "base/macros.h" #include "atom/common/node_includes.h" #include "native_mate/converter.h" #include "third_party/WebKit/public/web/WebArrayBuffer.h" From 4503aafe6467e0fd2d1d2e8c2234cbc4b663a8d3 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 7 Mar 2016 20:40:10 -0800 Subject: [PATCH 410/688] int32 => int32_t --- atom/browser/api/atom_api_download_item.cc | 2 +- atom/browser/api/atom_api_session.cc | 12 ++++++------ atom/browser/api/atom_api_web_contents.cc | 8 ++++---- atom/browser/api/atom_api_web_contents.h | 10 +++++----- atom/browser/atom_download_manager_delegate.cc | 4 ++-- atom/browser/atom_download_manager_delegate.h | 2 +- atom/common/api/atom_api_clipboard.cc | 4 ++-- atom/common/asar/archive.cc | 8 ++++---- atom/common/asar/archive.h | 4 ++-- .../native_mate_converters/v8_value_converter.cc | 10 +++++----- atom/renderer/api/atom_api_spell_check_client.cc | 2 +- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index 5a8befc9d1d..de3a5b348ee 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -53,7 +53,7 @@ namespace { using WrapDownloadItemCallback = base::Callback)>; WrapDownloadItemCallback g_wrap_download_item; -std::map>> g_download_item_objects; +std::map>> g_download_item_objects; } // namespace diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index e5c5198f034..0f104c76072 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -49,12 +49,12 @@ namespace { struct ClearStorageDataOptions { GURL origin; - uint32 storage_types = StoragePartition::REMOVE_DATA_MASK_ALL; - uint32 quota_types = StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL; + uint32_t storage_types = StoragePartition::REMOVE_DATA_MASK_ALL; + uint32_t quota_types = StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL; }; -uint32 GetStorageMask(const std::vector& storage_types) { - uint32 storage_mask = 0; +uint32_t GetStorageMask(const std::vector& storage_types) { + uint32_t storage_mask = 0; for (const auto& it : storage_types) { auto type = base::ToLowerASCII(it); if (type == "appcache") @@ -77,8 +77,8 @@ uint32 GetStorageMask(const std::vector& storage_types) { return storage_mask; } -uint32 GetQuotaMask(const std::vector& quota_types) { - uint32 quota_mask = 0; +uint32_t GetQuotaMask(const std::vector& quota_types) { + uint32_t quota_mask = 0; for (const auto& it : quota_types) { auto type = base::ToLowerASCII(it); if (type == "temporary") diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 12e0c56ceb6..1f4c9f92b35 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -303,9 +303,9 @@ WebContents::~WebContents() { } bool WebContents::AddMessageToConsole(content::WebContents* source, - int32 level, + int32_t level, const base::string16& message, - int32 line_no, + int32_t line_no, const base::string16& source_id) { if (type_ == BROWSER_WINDOW) { return false; @@ -998,8 +998,8 @@ void WebContents::ReplaceMisspelling(const base::string16& word) { web_contents()->ReplaceMisspelling(word); } -uint32 WebContents::FindInPage(mate::Arguments* args) { - uint32 request_id = GetNextRequestId(); +uint32_t WebContents::FindInPage(mate::Arguments* args) { + uint32_t request_id = GetNextRequestId(); base::string16 search_text; blink::WebFindOptions options; if (!args->GetNext(&search_text) || search_text.empty()) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index a785e1c070d..a008a84913b 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -110,7 +110,7 @@ class WebContents : public mate::TrackableObject, void Unselect(); void Replace(const base::string16& word); void ReplaceMisspelling(const base::string16& word); - uint32 FindInPage(mate::Arguments* args); + uint32_t FindInPage(mate::Arguments* args); void StopFindInPage(content::StopFindAction action); // Focus. @@ -162,9 +162,9 @@ class WebContents : public mate::TrackableObject, // content::WebContentsDelegate: bool AddMessageToConsole(content::WebContents* source, - int32 level, + int32_t level, const base::string16& message, - int32 line_no, + int32_t line_no, const base::string16& source_id) override; bool ShouldCreateWebContents( content::WebContents* web_contents, @@ -270,7 +270,7 @@ class WebContents : public mate::TrackableObject, AtomBrowserContext* GetBrowserContext() const; - uint32 GetNextRequestId() { + uint32_t GetNextRequestId() { return ++request_id_; } @@ -299,7 +299,7 @@ class WebContents : public mate::TrackableObject, Type type_; // Request id used for findInPage request. - uint32 request_id_; + uint32_t request_id_; DISALLOW_COPY_AND_ASSIGN(WebContents); }; diff --git a/atom/browser/atom_download_manager_delegate.cc b/atom/browser/atom_download_manager_delegate.cc index f5bdbbd8598..16c0cf708b8 100644 --- a/atom/browser/atom_download_manager_delegate.cc +++ b/atom/browser/atom_download_manager_delegate.cc @@ -60,7 +60,7 @@ void AtomDownloadManagerDelegate::CreateDownloadPath( } void AtomDownloadManagerDelegate::OnDownloadPathGenerated( - uint32 download_id, + uint32_t download_id, const content::DownloadTargetCallback& callback, const base::FilePath& default_path) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -160,7 +160,7 @@ bool AtomDownloadManagerDelegate::ShouldOpenDownload( void AtomDownloadManagerDelegate::GetNextId( const content::DownloadIdCallback& callback) { - static uint32 next_id = content::DownloadItem::kInvalidId + 1; + static uint32_t next_id = content::DownloadItem::kInvalidId + 1; callback.Run(next_id++); } diff --git a/atom/browser/atom_download_manager_delegate.h b/atom/browser/atom_download_manager_delegate.h index 2df3a7d45a6..5ea3d50d5ae 100644 --- a/atom/browser/atom_download_manager_delegate.h +++ b/atom/browser/atom_download_manager_delegate.h @@ -31,7 +31,7 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate { const std::string& mime_type, const base::FilePath& path, const CreateDownloadPathCallback& callback); - void OnDownloadPathGenerated(uint32 download_id, + void OnDownloadPathGenerated(uint32_t download_id, const content::DownloadTargetCallback& callback, const base::FilePath& default_path); diff --git a/atom/common/api/atom_api_clipboard.cc b/atom/common/api/atom_api_clipboard.cc index 5186e22c8d9..1f75f2cd3fe 100644 --- a/atom/common/api/atom_api_clipboard.cc +++ b/atom/common/api/atom_api_clipboard.cc @@ -109,8 +109,8 @@ base::string16 ReadHtml(mate::Arguments* args) { base::string16 data; base::string16 html; std::string url; - uint32 start; - uint32 end; + uint32_t start; + uint32_t end; ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); clipboard->ReadHTML(GetClipboardType(args), &html, &url, &start, &end); data = html.substr(start, end - start); diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index 35451410a8d..b5a9603acb1 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -90,12 +90,12 @@ bool GetNodeFromPath(std::string path, } bool FillFileInfoWithNode(Archive::FileInfo* info, - uint32 header_size, + uint32_t header_size, const base::DictionaryValue* node) { int size; if (!node->GetInteger("size", &size)) return false; - info->size = static_cast(size); + info->size = static_cast(size); if (node->GetBoolean("unpacked", &info->unpacked) && info->unpacked) return true; @@ -157,8 +157,8 @@ bool Archive::Init() { return false; } - uint32 size; - if (!base::PickleIterator(base::Pickle(buf.data(), buf.size())).ReadUInt32( + uint32_t size; + if (!base::PickleIterator(base::Pickle(buf.data(), buf.size())).ReadUint32_t( &size)) { LOG(ERROR) << "Failed to parse header size from " << path_.value(); return false; diff --git a/atom/common/asar/archive.h b/atom/common/asar/archive.h index de5b9de605a..6bde7bd1ff2 100644 --- a/atom/common/asar/archive.h +++ b/atom/common/asar/archive.h @@ -28,7 +28,7 @@ class Archive { FileInfo() : unpacked(false), executable(false), size(0), offset(0) {} bool unpacked; bool executable; - uint32 size; + uint32_t size; uint64 offset; }; @@ -71,7 +71,7 @@ class Archive { base::FilePath path_; base::File file_; int fd_; - uint32 header_size_; + uint32_t header_size_; scoped_ptr header_; // Cached external temporary files. diff --git a/atom/common/native_mate_converters/v8_value_converter.cc b/atom/common/native_mate_converters/v8_value_converter.cc index 1a729dda535..b35f1eb6a0b 100644 --- a/atom/common/native_mate_converters/v8_value_converter.cc +++ b/atom/common/native_mate_converters/v8_value_converter.cc @@ -169,7 +169,7 @@ v8::Local V8ValueConverter::ToV8Array( CHECK(!child_v8.IsEmpty()); v8::TryCatch try_catch; - result->Set(static_cast(i), child_v8); + result->Set(static_cast(i), child_v8); if (try_catch.HasCaught()) LOG(ERROR) << "Setter for index " << i << " threw an exception."; } @@ -222,8 +222,8 @@ base::Value* V8ValueConverter::FromV8ValueImpl( if (val->IsBoolean()) return new base::FundamentalValue(val->ToBoolean()->Value()); - if (val->IsInt32()) - return new base::FundamentalValue(val->ToInt32()->Value()); + if (val->Isint32_t()) + return new base::FundamentalValue(val->Toint32_t()->Value()); if (val->IsNumber()) return new base::FundamentalValue(val->ToNumber()->Value()); @@ -298,7 +298,7 @@ base::Value* V8ValueConverter::FromV8Array( base::ListValue* result = new base::ListValue(); // Only fields with integer keys are carried over to the ListValue. - for (uint32 i = 0; i < val->Length(); ++i) { + for (uint32_t i = 0; i < val->Length(); ++i) { v8::TryCatch try_catch; v8::Local child_v8 = val->Get(i); if (try_catch.HasCaught()) { @@ -345,7 +345,7 @@ base::Value* V8ValueConverter::FromV8Object( scoped_ptr result(new base::DictionaryValue()); v8::Local property_names(val->GetOwnPropertyNames()); - for (uint32 i = 0; i < property_names->Length(); ++i) { + for (uint32_t i = 0; i < property_names->Length(); ++i) { v8::Local key(property_names->Get(i)); // Extend this test to cover more types as necessary and if sensible. diff --git a/atom/renderer/api/atom_api_spell_check_client.cc b/atom/renderer/api/atom_api_spell_check_client.cc index 25d1e30b0aa..51c5f721f02 100644 --- a/atom/renderer/api/atom_api_spell_check_client.cc +++ b/atom/renderer/api/atom_api_spell_check_client.cc @@ -27,7 +27,7 @@ bool HasWordCharacters(const base::string16& text, int index) { const base::char16* data = text.data(); int length = text.length(); while (index < length) { - uint32 code = 0; + uint32_t code = 0; U16_NEXT(data, index, length, code); UErrorCode error = U_ZERO_ERROR; if (uscript_getScript(code, &error) != USCRIPT_COMMON) From 5fae63a2f5d030ddb49d032bab7c50cc25d20d05 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 8 Mar 2016 23:28:53 +0900 Subject: [PATCH 411/688] Fix compilation errors on OS X --- atom/app/atom_library_main.h | 2 +- atom/app/atom_main_delegate.cc | 2 +- atom/browser/api/atom_api_app.cc | 6 +- atom/browser/api/atom_api_app.h | 3 +- atom/browser/api/atom_api_content_tracing.cc | 15 +--- atom/browser/api/atom_api_cookies.cc | 3 +- atom/browser/api/atom_api_desktop_capturer.cc | 7 +- atom/browser/api/atom_api_download_item.cc | 4 +- atom/browser/api/atom_api_download_item.h | 4 +- atom/browser/api/atom_api_protocol.h | 4 +- atom/browser/api/atom_api_web_contents.cc | 14 ++-- atom/browser/api/atom_api_web_contents.h | 9 +-- atom/browser/api/frame_subscriber.cc | 2 +- atom/browser/atom_browser_client.cc | 7 +- atom/browser/atom_browser_client.h | 3 +- atom/browser/atom_browser_context.cc | 7 +- atom/browser/atom_permission_manager.cc | 20 ++++++ atom/browser/atom_permission_manager.h | 7 ++ .../atom_resource_dispatcher_host_delegate.cc | 4 +- .../atom_resource_dispatcher_host_delegate.h | 13 ++-- ...atom_speech_recognition_manager_delegate.h | 1 + atom/browser/common_web_contents_delegate.cc | 7 +- atom/browser/javascript_environment.cc | 1 + atom/browser/native_window.cc | 9 +-- atom/browser/net/asar/url_request_asar_job.cc | 72 +++++++++---------- atom/browser/net/asar/url_request_asar_job.h | 12 ++-- atom/browser/net/atom_network_delegate.cc | 8 +-- atom/browser/net/js_asker.h | 2 +- atom/browser/net/url_request_fetch_job.cc | 16 ++--- atom/browser/net/url_request_fetch_job.h | 4 +- atom/browser/node_debugger.cc | 2 +- atom/browser/ui/accelerator_util_mac.mm | 2 +- atom/browser/ui/message_box_mac.mm | 2 +- atom/browser/web_view_guest_delegate.cc | 11 +-- atom/common/api/atom_api_asar.cc | 4 +- atom/common/api/atom_bindings.h | 1 + atom/common/asar/archive.cc | 4 +- atom/common/asar/archive.h | 2 +- atom/common/asar/scoped_temporary_file.cc | 2 +- atom/common/asar/scoped_temporary_file.h | 2 +- .../crash_reporter/crash_reporter_mac.mm | 3 +- .../native_mate_converters/net_converter.cc | 8 +-- .../v8_value_converter.cc | 4 +- atom/common/node_bindings.cc | 2 +- .../api/atom_api_spell_check_client.cc | 60 +--------------- .../api/atom_api_spell_check_client.h | 2 - chromium_src/chrome/browser/browser_process.h | 2 +- .../extensions/global_shortcut_listener.h | 2 +- .../chrome/browser/media/desktop_media_list.h | 1 - .../media/native_desktop_media_list.cc | 17 ++--- .../browser/media/native_desktop_media_list.h | 1 - .../browser/printing/pdf_to_emf_converter.cc | 2 +- .../chrome/browser/printing/print_job.cc | 2 +- .../chrome/browser/printing/print_job.h | 1 - .../printing/print_preview_message_handler.cc | 2 +- .../printing/print_preview_message_handler.h | 2 +- .../printing/print_view_manager_base.cc | 10 +-- .../printing/printing_message_filter.cc | 2 +- .../printing/printing_message_filter.h | 2 +- .../printing_ui_web_contents_observer.h | 1 - .../chrome/browser/process_singleton.h | 1 - .../chrome/browser/process_singleton_posix.cc | 10 +-- .../pepper/pepper_flash_browser_host.h | 1 - .../pepper_flash_clipboard_message_filter.cc | 4 +- .../pepper_flash_clipboard_message_filter.h | 2 - .../browser/ui/cocoa/color_chooser_mac.mm | 6 +- .../browser/ui/views/color_chooser_aura.h | 2 - .../frame/global_menu_bar_registrar_x11.h | 1 - chromium_src/chrome/common/print_messages.cc | 1 - chromium_src/chrome/common/print_messages.h | 4 +- .../chrome/common/tts_utterance_request.h | 4 +- .../chrome/common/widevine_cdm_constants.cc | 4 +- .../chrome/common/widevine_cdm_constants.h | 4 +- .../chrome_renderer_pepper_host_factory.h | 2 - .../pepper/pepper_flash_font_file_host.h | 2 - .../pepper/pepper_flash_fullscreen_host.h | 2 - .../pepper/pepper_flash_renderer_host.h | 1 - .../pepper_shared_memory_message_filter.cc | 5 +- .../pepper_shared_memory_message_filter.h | 2 - .../printing/print_web_view_helper.cc | 24 +++---- .../printing/print_web_view_helper_linux.cc | 2 +- .../printing/print_web_view_helper_mac.mm | 4 +- .../printing/print_web_view_helper_pdf_win.cc | 4 +- .../spellchecker/spellcheck_worditerator.cc | 3 +- .../spellchecker/spellcheck_worditerator.h | 2 +- .../chrome/renderer/tts_dispatcher.cc | 3 +- chromium_src/chrome/renderer/tts_dispatcher.h | 4 +- .../chrome/utility/printing_handler_win.cc | 2 +- .../stream_listen_socket.cc | 4 +- .../stream_listen_socket.h | 2 +- .../embedded_test_server/tcp_listen_socket.cc | 11 +-- .../embedded_test_server/tcp_listen_socket.h | 8 +-- vendor/brightray | 2 +- 93 files changed, 242 insertions(+), 317 deletions(-) diff --git a/atom/app/atom_library_main.h b/atom/app/atom_library_main.h index b45e27a4a99..e1603fa5942 100644 --- a/atom/app/atom_library_main.h +++ b/atom/app/atom_library_main.h @@ -5,7 +5,7 @@ #ifndef ATOM_APP_ATOM_LIBRARY_MAIN_H_ #define ATOM_APP_ATOM_LIBRARY_MAIN_H_ -#include "base/macros.h" +#include "build/build_config.h" #if defined(OS_MACOSX) extern "C" { diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index 698da4f4def..221d59c1619 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -135,7 +135,7 @@ content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() { } scoped_ptr AtomMainDelegate::CreateContentClient() { - return scoped_ptr(new AtomContentClient).Pass(); + return scoped_ptr(new AtomContentClient); } } // namespace atom diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 0c235a56cb4..d728d9dd546 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -230,8 +230,7 @@ void App::OnLogin(LoginHandler* login_handler) { } void App::AllowCertificateError( - int pid, - int fid, + content::WebContents* web_contents, int cert_error, const net::SSLInfo& ssl_info, const GURL& request_url, @@ -241,9 +240,6 @@ void App::AllowCertificateError( bool expired_previous_decision, const base::Callback& callback, content::CertificateRequestResultType* request) { - auto rfh = content::RenderFrameHost::FromID(pid, fid); - auto web_contents = content::WebContents::FromRenderFrameHost(rfh); - v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); bool prevent_default = Emit("certificate-error", diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 3d4ac17adf7..5faf8ebb10e 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -52,8 +52,7 @@ class App : public AtomBrowserClient::Delegate, // content::ContentBrowserClient: void AllowCertificateError( - int render_process_id, - int render_frame_id, + content::WebContents* web_contents, int cert_error, const net::SSLInfo& ssl_info, const GURL& request_url, diff --git a/atom/browser/api/atom_api_content_tracing.cc b/atom/browser/api/atom_api_content_tracing.cc index f29946d1f46..937a87ea213 100644 --- a/atom/browser/api/atom_api_content_tracing.cc +++ b/atom/browser/api/atom_api_content_tracing.cc @@ -53,13 +53,7 @@ scoped_refptr GetTraceDataSink( void StopRecording(const base::FilePath& path, const CompletionCallback& callback) { - TracingController::GetInstance()->DisableRecording( - GetTraceDataSink(path, callback)); -} - -void CaptureMonitoringSnapshot(const base::FilePath& path, - const CompletionCallback& callback) { - TracingController::GetInstance()->CaptureMonitoringSnapshot( + TracingController::GetInstance()->StopTracing( GetTraceDataSink(path, callback)); } @@ -70,13 +64,8 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("getCategories", base::Bind( &TracingController::GetCategories, controller)); dict.SetMethod("startRecording", base::Bind( - &TracingController::EnableRecording, controller)); + &TracingController::StartTracing, controller)); dict.SetMethod("stopRecording", &StopRecording); - dict.SetMethod("startMonitoring", base::Bind( - &TracingController::EnableMonitoring, controller)); - dict.SetMethod("stopMonitoring", base::Bind( - &TracingController::DisableMonitoring, controller)); - dict.SetMethod("captureMonitoringSnapshot", &CaptureMonitoringSnapshot); dict.SetMethod("getTraceBufferUsage", base::Bind( &TracingController::GetTraceBufferUsage, controller)); dict.SetMethod("setWatchEvent", base::Bind( diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index 6323e5110c1..e49a2ee2f67 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -180,7 +180,8 @@ void SetCookieOnIO(scoped_refptr getter, GetCookieStore(getter)->GetCookieMonster()->SetCookieWithDetailsAsync( GURL(url), name, value, domain, path, expiration_time, secure, http_only, - false, net::COOKIE_PRIORITY_DEFAULT, base::Bind(OnSetCookie, callback)); + false, false, false, net::COOKIE_PRIORITY_DEFAULT, + base::Bind(OnSetCookie, callback)); } } // namespace diff --git a/atom/browser/api/atom_api_desktop_capturer.cc b/atom/browser/api/atom_api_desktop_capturer.cc index ceb69deca45..cdae6f0c44c 100644 --- a/atom/browser/api/atom_api_desktop_capturer.cc +++ b/atom/browser/api/atom_api_desktop_capturer.cc @@ -5,7 +5,6 @@ #include "atom/browser/api/atom_api_desktop_capturer.h" #include "atom/common/api/atom_api_native_image.h" -#include "atom/common/node_includes.h" #include "atom/common/native_mate_converters/gfx_converter.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/media/desktop_media_list.h" @@ -14,6 +13,8 @@ #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" #include "third_party/webrtc/modules/desktop_capture/window_capturer.h" +#include "atom/common/node_includes.h" + namespace mate { template<> @@ -63,8 +64,8 @@ void DesktopCapturer::StartHandling(bool capture_window, capture_screen ? webrtc::ScreenCapturer::Create(options) : nullptr); scoped_ptr window_capturer( capture_window ? webrtc::WindowCapturer::Create(options) : nullptr); - media_list_.reset(new NativeDesktopMediaList(screen_capturer.Pass(), - window_capturer.Pass())); + media_list_.reset(new NativeDesktopMediaList( + std::move(screen_capturer), std::move(window_capturer))); media_list_->SetThumbnailSize(thumbnail_size); media_list_->StartUpdating(this); diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index de3a5b348ee..3edd5f9c254 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -106,11 +106,11 @@ void DownloadItem::Cancel() { download_item_->Remove(); } -int64 DownloadItem::GetReceivedBytes() const { +int64_t DownloadItem::GetReceivedBytes() const { return download_item_->GetReceivedBytes(); } -int64 DownloadItem::GetTotalBytes() const { +int64_t DownloadItem::GetTotalBytes() const { return download_item_->GetTotalBytes(); } diff --git a/atom/browser/api/atom_api_download_item.h b/atom/browser/api/atom_api_download_item.h index 5806c018176..64469b9b34d 100644 --- a/atom/browser/api/atom_api_download_item.h +++ b/atom/browser/api/atom_api_download_item.h @@ -30,8 +30,8 @@ class DownloadItem : public mate::TrackableObject, void Pause(); void Resume(); void Cancel(); - int64 GetReceivedBytes() const; - int64 GetTotalBytes() const; + int64_t GetReceivedBytes() const; + int64_t GetTotalBytes() const; std::string GetMimeType() const; bool HasUserGesture() const; std::string GetFilename() const; diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index 8aef406fbc3..107fbf1ce71 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -117,7 +117,7 @@ class Protocol : public mate::Wrappable { scoped_ptr> protocol_handler( new CustomProtocolHandler( isolate(), request_context_getter_, handler)); - if (job_factory_->SetProtocolHandler(scheme, protocol_handler.Pass())) + if (job_factory_->SetProtocolHandler(scheme, std::move(protocol_handler))) return PROTOCOL_OK; else return PROTOCOL_FAIL; @@ -161,7 +161,7 @@ class Protocol : public mate::Wrappable { isolate(), request_context_getter_, handler)); original_protocols_.set( scheme, - job_factory_->ReplaceProtocol(scheme, protocol_handler.Pass())); + job_factory_->ReplaceProtocol(scheme, std::move(protocol_handler))); return PROTOCOL_OK; } diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 1f4c9f92b35..c8b597704cd 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -44,6 +44,7 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/resource_request_details.h" #include "content/public/browser/service_worker_context.h" @@ -150,7 +151,7 @@ struct Converter { } else { scoped_ptr values(new base::ListValue()); values->AppendString(value); - response_headers.Set(key, values.Pass()); + response_headers.Set(key, std::move(values)); } } } @@ -317,8 +318,9 @@ bool WebContents::AddMessageToConsole(content::WebContents* source, bool WebContents::ShouldCreateWebContents( content::WebContents* web_contents, - int route_id, - int main_frame_route_id, + int32_t route_id, + int32_t main_frame_route_id, + int32_t main_frame_widget_route_id, WindowContainerType window_container_type, const std::string& frame_name, const GURL& target_url, @@ -509,11 +511,11 @@ void WebContents::PluginCrashed(const base::FilePath& plugin_path, Emit("plugin-crashed", info.name, info.version); } -void WebContents::MediaStartedPlaying() { +void WebContents::MediaStartedPlaying(const MediaPlayerId& id) { Emit("media-started-playing"); } -void WebContents::MediaPaused() { +void WebContents::MediaStoppedPlaying(const MediaPlayerId& id) { Emit("media-paused"); } @@ -1070,7 +1072,7 @@ void WebContents::BeginFrameSubscription( if (view) { scoped_ptr frame_subscriber(new FrameSubscriber( isolate(), view, callback)); - view->BeginFrameSubscription(frame_subscriber.Pass()); + view->BeginFrameSubscription(std::move(frame_subscriber)); } } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index a008a84913b..d98b838fb46 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -168,8 +168,9 @@ class WebContents : public mate::TrackableObject, const base::string16& source_id) override; bool ShouldCreateWebContents( content::WebContents* web_contents, - int route_id, - int main_frame_route_id, + int32_t route_id, + int32_t main_frame_route_id, + int32_t main_frame_widget_route_id, WindowContainerType window_container_type, const std::string& frame_name, const GURL& target_url, @@ -252,8 +253,8 @@ class WebContents : public mate::TrackableObject, const std::vector& urls) override; void PluginCrashed(const base::FilePath& plugin_path, base::ProcessId plugin_pid) override; - void MediaStartedPlaying() override; - void MediaPaused() override; + void MediaStartedPlaying(const MediaPlayerId& id) override; + void MediaStoppedPlaying(const MediaPlayerId& id) override; void DidChangeThemeColor(SkColor theme_color) override; // brightray::InspectableWebContentsViewDelegate: diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index c76d5ffc87d..f81a8bea8b1 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -54,7 +54,7 @@ void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback, return; bitmap.copyPixelsTo( - reinterpret_cast(node::Buffer::Data(buffer.ToLocalChecked())), + reinterpret_cast(node::Buffer::Data(buffer.ToLocalChecked())), rgb_arr_size); callback_.Run(buffer.ToLocalChecked()); diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 1fe435673db..876be2b1d00 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -230,8 +230,7 @@ content::QuotaPermissionContext* } void AtomBrowserClient::AllowCertificateError( - int render_process_id, - int render_frame_id, + content::WebContents* web_contents, int cert_error, const net::SSLInfo& ssl_info, const GURL& request_url, @@ -243,7 +242,7 @@ void AtomBrowserClient::AllowCertificateError( content::CertificateRequestResultType* request) { if (delegate_) { delegate_->AllowCertificateError( - render_process_id, render_frame_id, cert_error, ssl_info, request_url, + web_contents, cert_error, ssl_info, request_url, resource_type, overridable, strict_enforcement, expired_previous_decision, callback, request); } @@ -265,7 +264,7 @@ void AtomBrowserClient::SelectClientCertificate( if (!cert_request_info->client_certs.empty() && delegate_) { delegate_->SelectClientCertificate( - web_contents, cert_request_info, delegate.Pass()); + web_contents, cert_request_info, std::move(delegate)); } } diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index 4af66cc041a..8f62887ff68 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -61,8 +61,7 @@ class AtomBrowserClient : public brightray::BrowserClient, void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override; content::QuotaPermissionContext* CreateQuotaPermissionContext() override; void AllowCertificateError( - int render_process_id, - int render_frame_id, + content::WebContents* web_contents, int cert_error, const net::SSLInfo& ssl_info, const GURL& request_url, diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index be004c8f6db..2ff9a510db4 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -134,14 +134,15 @@ AtomBrowserContext::CreateURLRequestJobFactory( new net::FtpNetworkLayer(host_resolver)))); // Set up interceptors in the reverse order. - scoped_ptr top_job_factory = job_factory.Pass(); + scoped_ptr top_job_factory = + std::move(job_factory); content::URLRequestInterceptorScopedVector::reverse_iterator it; for (it = interceptors->rbegin(); it != interceptors->rend(); ++it) top_job_factory.reset(new net::URLRequestInterceptingJobFactory( - top_job_factory.Pass(), make_scoped_ptr(*it))); + std::move(top_job_factory), make_scoped_ptr(*it))); interceptors->weak_clear(); - return top_job_factory.Pass(); + return top_job_factory; } net::HttpCache::BackendFactory* diff --git a/atom/browser/atom_permission_manager.cc b/atom/browser/atom_permission_manager.cc index e7fdaaffea7..bd005869aa2 100644 --- a/atom/browser/atom_permission_manager.cc +++ b/atom/browser/atom_permission_manager.cc @@ -80,6 +80,26 @@ int AtomPermissionManager::RequestPermission( return kNoPendingOperation; } +int AtomPermissionManager::RequestPermissions( + const std::vector& permissions, + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + bool user_gesture, + const base::Callback&)>& callback) { + // FIXME(zcbenz): Just ignore multiple permissions request for now. + std::vector permissionStatuses; + for (auto permission : permissions) { + if (permission == content::PermissionType::MIDI_SYSEX) { + content::ChildProcessSecurityPolicy::GetInstance()-> + GrantSendMidiSysExMessage(render_frame_host->GetProcess()->GetID()); + } + permissionStatuses.push_back(content::PERMISSION_STATUS_GRANTED); + } + callback.Run(permissionStatuses); + return kNoPendingOperation; +} + void AtomPermissionManager::OnPermissionResponse( int request_id, const GURL& origin, diff --git a/atom/browser/atom_permission_manager.h b/atom/browser/atom_permission_manager.h index 4bebbbc84f2..58c23723bfb 100644 --- a/atom/browser/atom_permission_manager.h +++ b/atom/browser/atom_permission_manager.h @@ -38,6 +38,13 @@ class AtomPermissionManager : public content::PermissionManager { const GURL& requesting_origin, bool user_gesture, const ResponseCallback& callback) override; + int RequestPermissions( + const std::vector& permissions, + content::RenderFrameHost* render_frame_host, + const GURL& requesting_origin, + bool user_gesture, + const base::Callback&)>& callback) override; protected: void OnPermissionResponse(int request_id, diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index 4d969786c19..68576a52f24 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -19,8 +19,8 @@ AtomResourceDispatcherHostDelegate::AtomResourceDispatcherHostDelegate() { bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( const GURL& url, - int render_process_id, - int render_view_id, + int child_id, + const content::ResourceRequestInfo::WebContentsGetter&, bool is_main_frame, ui::PageTransition transition, bool has_user_gesture) { diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.h b/atom/browser/atom_resource_dispatcher_host_delegate.h index a90b366bc75..408b83c92d9 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.h +++ b/atom/browser/atom_resource_dispatcher_host_delegate.h @@ -15,12 +15,13 @@ class AtomResourceDispatcherHostDelegate AtomResourceDispatcherHostDelegate(); // content::ResourceDispatcherHostDelegate: - bool HandleExternalProtocol(const GURL& url, - int render_process_id, - int render_view_id, - bool is_main_frame, - ui::PageTransition transition, - bool has_user_gesture) override; + bool HandleExternalProtocol( + const GURL& url, + int child_id, + const content::ResourceRequestInfo::WebContentsGetter&, + bool is_main_frame, + ui::PageTransition transition, + bool has_user_gesture) override; content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( net::AuthChallengeInfo* auth_info, net::URLRequest* request) override; diff --git a/atom/browser/atom_speech_recognition_manager_delegate.h b/atom/browser/atom_speech_recognition_manager_delegate.h index ec31e227baf..4c78e0eead1 100644 --- a/atom/browser/atom_speech_recognition_manager_delegate.h +++ b/atom/browser/atom_speech_recognition_manager_delegate.h @@ -7,6 +7,7 @@ #include +#include "base/macros.h" #include "content/public/browser/speech_recognition_event_listener.h" #include "content/public/browser/speech_recognition_manager_delegate.h" diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index 1fd6f782de5..07cc20c7d10 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -19,6 +19,7 @@ #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host.h" #include "storage/browser/fileapi/isolated_context.h" #if defined(TOOLKIT_VIEWS) @@ -173,8 +174,6 @@ content::WebContents* CommonWebContentsDelegate::OpenURLFromTab( load_url_params.should_replace_current_entry = params.should_replace_current_entry; load_url_params.is_renderer_initiated = params.is_renderer_initiated; - load_url_params.transferred_global_request_id = - params.transferred_global_request_id; load_url_params.should_clear_history_list = true; source->GetController().LoadURLWithParams(load_url_params); @@ -223,7 +222,7 @@ void CommonWebContentsDelegate::EnterFullscreenModeForTab( return; SetHtmlApiFullscreen(true); owner_window_->NotifyWindowEnterHtmlFullScreen(); - source->GetRenderViewHost()->WasResized(); + source->GetRenderViewHost()->GetWidget()->WasResized(); } void CommonWebContentsDelegate::ExitFullscreenModeForTab( @@ -232,7 +231,7 @@ void CommonWebContentsDelegate::ExitFullscreenModeForTab( return; SetHtmlApiFullscreen(false); owner_window_->NotifyWindowLeaveHtmlFullScreen(); - source->GetRenderViewHost()->WasResized(); + source->GetRenderViewHost()->GetWidget()->WasResized(); } bool CommonWebContentsDelegate::IsFullscreenForTabOrPending( diff --git a/atom/browser/javascript_environment.cc b/atom/browser/javascript_environment.cc index dc27cedee56..970132b47c1 100644 --- a/atom/browser/javascript_environment.cc +++ b/atom/browser/javascript_environment.cc @@ -37,6 +37,7 @@ bool JavascriptEnvironment::Initialize() { v8::V8::SetFlagsFromString(js_flags.c_str(), js_flags.size()); gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode, + gin::IsolateHolder::kStableV8Extras, gin::ArrayBufferAllocator::SharedInstance()); return true; } diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 98b3d725a9a..d66b6ebf3fe 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -27,6 +27,7 @@ #include "content/public/browser/plugin_service.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/common/content_switches.h" #include "ipc/ipc_message_macros.h" @@ -275,15 +276,15 @@ bool NativeWindow::HasModalDialog() { } void NativeWindow::FocusOnWebView() { - web_contents()->GetRenderViewHost()->Focus(); + web_contents()->GetRenderViewHost()->GetWidget()->Focus(); } void NativeWindow::BlurWebView() { - web_contents()->GetRenderViewHost()->Blur(); + web_contents()->GetRenderViewHost()->GetWidget()->Blur(); } bool NativeWindow::IsWebViewFocused() { - auto host_view = web_contents()->GetRenderViewHost()->GetView(); + auto host_view = web_contents()->GetRenderViewHost()->GetWidget()->GetView(); return host_view && host_view->HasFocus(); } @@ -511,7 +512,7 @@ scoped_ptr NativeWindow::DraggableRegionsToSkRegion( region.bounds.bottom(), region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); } - return sk_region.Pass(); + return sk_region; } void NativeWindow::RenderViewCreated( diff --git a/atom/browser/net/asar/url_request_asar_job.cc b/atom/browser/net/asar/url_request_asar_job.cc index d926d111172..39e55a35cbc 100644 --- a/atom/browser/net/asar/url_request_asar_job.cc +++ b/atom/browser/net/asar/url_request_asar_job.cc @@ -44,6 +44,7 @@ URLRequestAsarJob::URLRequestAsarJob( : net::URLRequestJob(request, network_delegate), type_(TYPE_ERROR), remaining_bytes_(0), + range_parse_result_(net::OK), weak_ptr_factory_(this) {} URLRequestAsarJob::~URLRequestAsarJob() {} @@ -99,7 +100,7 @@ void URLRequestAsarJob::InitializeFileJob( void URLRequestAsarJob::Start() { if (type_ == TYPE_ASAR) { - remaining_bytes_ = static_cast(file_info_.size); + remaining_bytes_ = static_cast(file_info_.size); int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | @@ -131,18 +132,14 @@ void URLRequestAsarJob::Kill() { URLRequestJob::Kill(); } -bool URLRequestAsarJob::ReadRawData(net::IOBuffer* dest, - int dest_size, - int* bytes_read) { +int URLRequestAsarJob::ReadRawData(net::IOBuffer* dest, int dest_size) { if (remaining_bytes_ < dest_size) dest_size = static_cast(remaining_bytes_); // If we should copy zero bytes because |remaining_bytes_| is zero, short // circuit here. - if (!dest_size) { - *bytes_read = 0; - return true; - } + if (!dest_size) + return 0; int rv = stream_->Read(dest, dest_size, @@ -150,20 +147,11 @@ bool URLRequestAsarJob::ReadRawData(net::IOBuffer* dest, weak_ptr_factory_.GetWeakPtr(), make_scoped_refptr(dest))); if (rv >= 0) { - // Data is immediately available. - *bytes_read = rv; remaining_bytes_ -= rv; DCHECK_GE(remaining_bytes_, 0); - return true; } - // Otherwise, a read error occured. We may just need to wait... - if (rv == net::ERR_IO_PENDING) { - SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); - } else { - NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, rv)); - } - return false; + return rv; } bool URLRequestAsarJob::IsRedirectResponse(GURL* location, @@ -214,15 +202,16 @@ void URLRequestAsarJob::SetExtraRequestHeaders( const net::HttpRequestHeaders& headers) { std::string range_header; if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) { - // We only care about "Range" header here. + // This job only cares about the Range header. This method stashes the value + // for later use in DidOpen(), which is responsible for some of the range + // validation as well. NotifyStartError is not legal to call here since + // the job has not started. std::vector ranges; if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { if (ranges.size() == 1) { byte_range_ = ranges[0]; } else { - NotifyDone(net::URLRequestStatus( - net::URLRequestStatus::FAILED, - net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); + range_parse_result_ = net::ERR_REQUEST_RANGE_NOT_SATISFIABLE; } } } @@ -274,7 +263,14 @@ void URLRequestAsarJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) { void URLRequestAsarJob::DidOpen(int result) { if (result != net::OK) { - NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); + NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, + result)); + return; + } + + if (range_parse_result_ != net::OK) { + NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, + range_parse_result_)); return; } @@ -289,8 +285,9 @@ void URLRequestAsarJob::DidOpen(int result) { } } else { if (!byte_range_.ComputeBounds(meta_info_.file_size)) { - NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, - net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); + NotifyStartError( + net::URLRequestStatus(net::URLRequestStatus::FAILED, + net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); return; } @@ -315,17 +312,19 @@ void URLRequestAsarJob::DidOpen(int result) { } } -void URLRequestAsarJob::DidSeek(int64 result) { +void URLRequestAsarJob::DidSeek(int64_t result) { if (type_ == TYPE_ASAR) { - if (result != static_cast(file_info_.offset)) { - NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, - net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); + if (result != static_cast(file_info_.offset)) { + NotifyStartError( + net::URLRequestStatus(net::URLRequestStatus::FAILED, + net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); return; } } else { if (result != byte_range_.first_byte_position()) { - NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, - net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); + NotifyStartError( + net::URLRequestStatus(net::URLRequestStatus::FAILED, + net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); return; } } @@ -334,21 +333,14 @@ void URLRequestAsarJob::DidSeek(int64 result) { } void URLRequestAsarJob::DidRead(scoped_refptr buf, int result) { - if (result > 0) { - SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status + if (result >= 0) { remaining_bytes_ -= result; DCHECK_GE(remaining_bytes_, 0); } buf = NULL; - if (result == 0) { - NotifyDone(net::URLRequestStatus()); - } else if (result < 0) { - NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); - } - - NotifyReadComplete(result); + ReadRawDataComplete(result); } } // namespace asar diff --git a/atom/browser/net/asar/url_request_asar_job.h b/atom/browser/net/asar/url_request_asar_job.h index 29d1afc521d..7103abc4139 100644 --- a/atom/browser/net/asar/url_request_asar_job.h +++ b/atom/browser/net/asar/url_request_asar_job.h @@ -54,9 +54,7 @@ class URLRequestAsarJob : public net::URLRequestJob { // net::URLRequestJob: void Start() override; void Kill() override; - bool ReadRawData(net::IOBuffer* buf, - int buf_size, - int* bytes_read) override; + int ReadRawData(net::IOBuffer* buf, int buf_size) override; bool IsRedirectResponse(GURL* location, int* http_status_code) override; net::Filter* SetupFilter() const override; bool GetMimeType(std::string* mime_type) const override; @@ -72,7 +70,7 @@ class URLRequestAsarJob : public net::URLRequestJob { FileMetaInfo(); // Size of the file. - int64 file_size; + int64_t file_size; // Mime type associated with the file. std::string mime_type; // Result returned from GetMimeTypeFromFile(), i.e. flag showing whether @@ -97,7 +95,7 @@ class URLRequestAsarJob : public net::URLRequestJob { // Callback after seeking to the beginning of |byte_range_| in the file // on a background thread. - void DidSeek(int64 result); + void DidSeek(int64_t result); // Callback after data is asynchronously read from the file into |buf|. void DidRead(scoped_refptr buf, int result); @@ -119,7 +117,9 @@ class URLRequestAsarJob : public net::URLRequestJob { scoped_refptr file_task_runner_; net::HttpByteRange byte_range_; - int64 remaining_bytes_; + int64_t remaining_bytes_; + + net::Error range_parse_result_; base::WeakPtrFactory weak_ptr_factory_; diff --git a/atom/browser/net/atom_network_delegate.cc b/atom/browser/net/atom_network_delegate.cc index f993138ccc5..91b63fada35 100644 --- a/atom/browser/net/atom_network_delegate.cc +++ b/atom/browser/net/atom_network_delegate.cc @@ -78,7 +78,7 @@ void ToDictionary(base::DictionaryValue* details, net::URLRequest* request) { scoped_ptr list(new base::ListValue); GetUploadData(list.get(), request); if (!list->empty()) - details->Set("uploadData", list.Pass()); + details->Set("uploadData", std::move(list)); } void ToDictionary(base::DictionaryValue* details, @@ -87,7 +87,7 @@ void ToDictionary(base::DictionaryValue* details, net::HttpRequestHeaders::Iterator it(headers); while (it.GetNext()) dict->SetString(it.name(), it.value()); - details->Set("requestHeaders", dict.Pass()); + details->Set("requestHeaders", std::move(dict)); } void ToDictionary(base::DictionaryValue* details, @@ -107,10 +107,10 @@ void ToDictionary(base::DictionaryValue* details, } else { scoped_ptr values(new base::ListValue); values->AppendString(value); - dict->Set(key, values.Pass()); + dict->Set(key, std::move(values)); } } - details->Set("responseHeaders", dict.Pass()); + details->Set("responseHeaders", std::move(dict)); details->SetString("statusLine", headers->GetStatusLine()); details->SetInteger("statusCode", headers->response_code()); } diff --git a/atom/browser/net/js_asker.h b/atom/browser/net/js_asker.h index 8ec245ee8c4..061a9cb859e 100644 --- a/atom/browser/net/js_asker.h +++ b/atom/browser/net/js_asker.h @@ -81,7 +81,7 @@ class JsAsker : public RequestJob { void OnResponse(bool success, scoped_ptr value) { int error = net::ERR_NOT_IMPLEMENTED; if (success && value && !internal::IsErrorOptions(value.get(), &error)) { - StartAsync(value.Pass()); + StartAsync(std::move(value)); } else { RequestJob::NotifyStartError( net::URLRequestStatus(net::URLRequestStatus::FAILED, error)); diff --git a/atom/browser/net/url_request_fetch_job.cc b/atom/browser/net/url_request_fetch_job.cc index 6f418290175..b176aef378a 100644 --- a/atom/browser/net/url_request_fetch_job.cc +++ b/atom/browser/net/url_request_fetch_job.cc @@ -181,7 +181,7 @@ int URLRequestFetchJob::DataAvailable(net::IOBuffer* buffer, int num_bytes) { pending_buffer_ = nullptr; pending_buffer_size_ = 0; - NotifyReadComplete(bytes_read); + ReadRawDataComplete(bytes_read); return bytes_read; } @@ -190,18 +190,15 @@ void URLRequestFetchJob::Kill() { fetcher_.reset(); } -bool URLRequestFetchJob::ReadRawData(net::IOBuffer* dest, - int dest_size, - int* bytes_read) { +int URLRequestFetchJob::ReadRawData(net::IOBuffer* dest, int dest_size) { if (GetResponseCode() == 204) { - *bytes_read = 0; request()->set_received_response_content_length(prefilter_bytes_read()); - return true; + return 0; } pending_buffer_ = dest; pending_buffer_size_ = dest_size; SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); - return false; + return dest_size; } bool URLRequestFetchJob::GetMimeType(std::string* mime_type) const { @@ -234,9 +231,10 @@ void URLRequestFetchJob::OnURLFetchComplete(const net::URLFetcher* source) { pending_buffer_ = nullptr; pending_buffer_size_ = 0; - NotifyDone(fetcher_->GetStatus()); if (fetcher_->GetStatus().is_success()) - NotifyReadComplete(0); + ReadRawDataComplete(0); + else + NotifyStartError(fetcher_->GetStatus()); } } // namespace atom diff --git a/atom/browser/net/url_request_fetch_job.h b/atom/browser/net/url_request_fetch_job.h index 399f78ae396..d9a247c5db8 100644 --- a/atom/browser/net/url_request_fetch_job.h +++ b/atom/browser/net/url_request_fetch_job.h @@ -31,9 +31,7 @@ class URLRequestFetchJob : public JsAsker, // net::URLRequestJob: void Kill() override; - bool ReadRawData(net::IOBuffer* buf, - int buf_size, - int* bytes_read) override; + int ReadRawData(net::IOBuffer* buf, int buf_size) override; bool GetMimeType(std::string* mime_type) const override; void GetResponseInfo(net::HttpResponseInfo* info) override; int GetResponseCode() const override; diff --git a/atom/browser/node_debugger.cc b/atom/browser/node_debugger.cc index 2cfcdb222ae..50aa454fe75 100644 --- a/atom/browser/node_debugger.cc +++ b/atom/browser/node_debugger.cc @@ -152,7 +152,7 @@ void NodeDebugger::DidAccept( return; } - accepted_socket_ = socket.Pass(); + accepted_socket_ = std::move(socket); SendConnectMessage(); } diff --git a/atom/browser/ui/accelerator_util_mac.mm b/atom/browser/ui/accelerator_util_mac.mm index 2075b1041f6..be631b02124 100644 --- a/atom/browser/ui/accelerator_util_mac.mm +++ b/atom/browser/ui/accelerator_util_mac.mm @@ -28,7 +28,7 @@ void SetPlatformAccelerator(ui::Accelerator* accelerator) { scoped_ptr platform_accelerator( new ui::PlatformAcceleratorCocoa(characters, modifiers)); - accelerator->set_platform_accelerator(platform_accelerator.Pass()); + accelerator->set_platform_accelerator(std::move(platform_accelerator)); } } // namespace accelerator_util diff --git a/atom/browser/ui/message_box_mac.mm b/atom/browser/ui/message_box_mac.mm index 9380f01e384..d553a6a7dfb 100644 --- a/atom/browser/ui/message_box_mac.mm +++ b/atom/browser/ui/message_box_mac.mm @@ -96,7 +96,7 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window, } if (!icon.isNull()) { - NSImage* image = gfx::SkBitmapToNSImageWithColorSpace( + NSImage* image = skia::SkBitmapToNSImageWithColorSpace( *icon.bitmap(), base::mac::GetGenericRGBColorSpace()); [alert setIcon:image]; } diff --git a/atom/browser/web_view_guest_delegate.cc b/atom/browser/web_view_guest_delegate.cc index 8e1810c4a39..38f0fb1783f 100644 --- a/atom/browser/web_view_guest_delegate.cc +++ b/atom/browser/web_view_guest_delegate.cc @@ -9,6 +9,7 @@ #include "content/public/browser/guest_host.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" namespace atom { @@ -101,13 +102,14 @@ void WebViewGuestDelegate::SetAllowTransparency(bool allow) { auto render_view_host = web_contents()->GetRenderViewHost(); guest_opaque_ = !allow; - if (!render_view_host->GetView()) + if (!render_view_host->GetWidget()->GetView()) return; if (guest_opaque_) { - render_view_host->GetView()->SetBackgroundColorToDefault(); + render_view_host->GetWidget()->GetView()->SetBackgroundColorToDefault(); } else { - render_view_host->GetView()->SetBackgroundColor(SK_ColorTRANSPARENT); + render_view_host->GetWidget()->GetView()->SetBackgroundColor( + SK_ColorTRANSPARENT); } } @@ -123,7 +125,8 @@ void WebViewGuestDelegate::RenderViewReady() { // WebContents::GetRenderWidgetHostView will return the RWHV of an // interstitial page if one is showing at this time. We only want opacity // to apply to web pages. - auto render_view_host_view = web_contents()->GetRenderViewHost()->GetView(); + auto render_view_host_view = + web_contents()->GetRenderViewHost()->GetWidget()->GetView(); if (guest_opaque_) render_view_host_view->SetBackgroundColorToDefault(); else diff --git a/atom/common/api/atom_api_asar.cc b/atom/common/api/atom_api_asar.cc index 7aee71fc329..8f5190fecaa 100644 --- a/atom/common/api/atom_api_asar.cc +++ b/atom/common/api/atom_api_asar.cc @@ -27,12 +27,12 @@ class Archive : public mate::Wrappable { scoped_ptr archive(new asar::Archive(path)); if (!archive->Init()) return v8::False(isolate); - return (new Archive(archive.Pass()))->GetWrapper(isolate); + return (new Archive(std::move(archive)))->GetWrapper(isolate); } protected: explicit Archive(scoped_ptr archive) - : archive_(archive.Pass()) {} + : archive_(std::move(archive)) {} // Reads the offset and size of file. v8::Local GetFileInfo(v8::Isolate* isolate, diff --git a/atom/common/api/atom_bindings.h b/atom/common/api/atom_bindings.h index b3536c23403..9460145d239 100644 --- a/atom/common/api/atom_bindings.h +++ b/atom/common/api/atom_bindings.h @@ -7,6 +7,7 @@ #include +#include "base/macros.h" #include "base/strings/string16.h" #include "v8/include/v8.h" #include "vendor/node/deps/uv/include/uv.h" diff --git a/atom/common/asar/archive.cc b/atom/common/asar/archive.cc index b5a9603acb1..01fe23a8892 100644 --- a/atom/common/asar/archive.cc +++ b/atom/common/asar/archive.cc @@ -158,7 +158,7 @@ bool Archive::Init() { } uint32_t size; - if (!base::PickleIterator(base::Pickle(buf.data(), buf.size())).ReadUint32_t( + if (!base::PickleIterator(base::Pickle(buf.data(), buf.size())).ReadUInt32( &size)) { LOG(ERROR) << "Failed to parse header size from " << path_.value(); return false; @@ -296,7 +296,7 @@ bool Archive::CopyFileOut(const base::FilePath& path, base::FilePath* out) { #endif *out = temp_file->path(); - external_files_.set(path, temp_file.Pass()); + external_files_.set(path, std::move(temp_file)); return true; } diff --git a/atom/common/asar/archive.h b/atom/common/asar/archive.h index 6bde7bd1ff2..79b848623c9 100644 --- a/atom/common/asar/archive.h +++ b/atom/common/asar/archive.h @@ -29,7 +29,7 @@ class Archive { bool unpacked; bool executable; uint32_t size; - uint64 offset; + uint64_t offset; }; struct Stats : public FileInfo { diff --git a/atom/common/asar/scoped_temporary_file.cc b/atom/common/asar/scoped_temporary_file.cc index 6dd12782d8e..8578d90d907 100644 --- a/atom/common/asar/scoped_temporary_file.cc +++ b/atom/common/asar/scoped_temporary_file.cc @@ -51,7 +51,7 @@ bool ScopedTemporaryFile::Init(const base::FilePath::StringType& ext) { bool ScopedTemporaryFile::InitFromFile(base::File* src, const base::FilePath::StringType& ext, - uint64 offset, uint64 size) { + uint64_t offset, uint64_t size) { if (!src->IsValid()) return false; diff --git a/atom/common/asar/scoped_temporary_file.h b/atom/common/asar/scoped_temporary_file.h index 23660a23901..5931d9b87af 100644 --- a/atom/common/asar/scoped_temporary_file.h +++ b/atom/common/asar/scoped_temporary_file.h @@ -28,7 +28,7 @@ class ScopedTemporaryFile { // Init an temporary file and fill it with content of |path|. bool InitFromFile(base::File* src, const base::FilePath::StringType& ext, - uint64 offset, uint64 size); + uint64_t offset, uint64_t size); base::FilePath path() const { return path_; } diff --git a/atom/common/crash_reporter/crash_reporter_mac.mm b/atom/common/crash_reporter/crash_reporter_mac.mm index 74ac70125b7..130a421665f 100644 --- a/atom/common/crash_reporter/crash_reporter_mac.mm +++ b/atom/common/crash_reporter/crash_reporter_mac.mm @@ -48,7 +48,8 @@ void CrashReporterMac::InitBreakpad(const std::string& product_name, if (crashpad_client.StartHandler(handler_path, database_path, submit_url, StringMap(), - std::vector())) { + std::vector(), + true)) { crashpad_client.UseHandler(); } } // @autoreleasepool diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 184f1c3fecf..5223709ae58 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -34,7 +34,7 @@ v8::Local Converter::ToV8( scoped_ptr list(new base::ListValue); atom::GetUploadData(list.get(), val); if (!list->empty()) - dict->Set("uploadData", list.Pass()); + dict->Set("uploadData", std::move(list)); return mate::ConvertToV8(isolate, *(dict.get())); } @@ -74,7 +74,7 @@ void GetUploadData(base::ListValue* upload_data_list, const net::UploadDataStream* upload_data = request->get_upload(); if (!upload_data) return; - const ScopedVector* readers = + const std::vector>* readers = upload_data->GetElementReaders(); for (const auto& reader : *readers) { scoped_ptr upload_data_dict( @@ -85,14 +85,14 @@ void GetUploadData(base::ListValue* upload_data_list, scoped_ptr bytes( base::BinaryValue::CreateWithCopiedBuffer(bytes_reader->bytes(), bytes_reader->length())); - upload_data_dict->Set("bytes", bytes.Pass()); + upload_data_dict->Set("bytes", std::move(bytes)); } else if (reader->AsFileReader()) { const net::UploadFileElementReader* file_reader = reader->AsFileReader(); auto file_path = file_reader->path().AsUTF8Unsafe(); upload_data_dict->SetStringWithoutPathExpansion("file", file_path); } - upload_data_list->Append(upload_data_dict.Pass()); + upload_data_list->Append(std::move(upload_data_dict)); } } diff --git a/atom/common/native_mate_converters/v8_value_converter.cc b/atom/common/native_mate_converters/v8_value_converter.cc index b35f1eb6a0b..99873cd1c4f 100644 --- a/atom/common/native_mate_converters/v8_value_converter.cc +++ b/atom/common/native_mate_converters/v8_value_converter.cc @@ -222,8 +222,8 @@ base::Value* V8ValueConverter::FromV8ValueImpl( if (val->IsBoolean()) return new base::FundamentalValue(val->ToBoolean()->Value()); - if (val->Isint32_t()) - return new base::FundamentalValue(val->Toint32_t()->Value()); + if (val->IsInt32()) + return new base::FundamentalValue(val->ToInt32()->Value()); if (val->IsNumber()) return new base::FundamentalValue(val->ToNumber()->Value()); diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 608cc94b09a..950a2cd786a 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -85,7 +85,7 @@ scoped_ptr StringVectorToArgArray( for (size_t i = 0; i < vector.size(); ++i) { array[i] = vector[i].c_str(); } - return array.Pass(); + return array; } base::FilePath GetResourcesPath(bool is_browser) { diff --git a/atom/renderer/api/atom_api_spell_check_client.cc b/atom/renderer/api/atom_api_spell_check_client.cc index 51c5f721f02..08f36efce58 100644 --- a/atom/renderer/api/atom_api_spell_check_client.cc +++ b/atom/renderer/api/atom_api_spell_check_client.cc @@ -21,8 +21,6 @@ namespace api { namespace { -const int kMaxAutoCorrectWordSize = 8; - bool HasWordCharacters(const base::string16& text, int index) { const base::char16* data = text.data(); int length = text.length(); @@ -42,8 +40,7 @@ SpellCheckClient::SpellCheckClient(const std::string& language, bool auto_spell_correct_turned_on, v8::Isolate* isolate, v8::Local provider) - : auto_spell_correct_turned_on_(auto_spell_correct_turned_on), - isolate_(isolate), + : isolate_(isolate), provider_(isolate, provider) { character_attributes_.SetDefaultLanguage(language); @@ -96,14 +93,6 @@ void SpellCheckClient::requestCheckingOfText( completionCallback->didFinishCheckingText(results); } -blink::WebString SpellCheckClient::autoCorrectWord( - const blink::WebString& misspelledWord) { - if (auto_spell_correct_turned_on_) - return GetAutoCorrectionWord(base::string16(misspelledWord)); - else - return blink::WebString(); -} - void SpellCheckClient::showSpellingUI(bool show) { } @@ -170,53 +159,6 @@ bool SpellCheckClient::SpellCheckWord(const base::string16& word_to_check) { return true; } -base::string16 SpellCheckClient::GetAutoCorrectionWord( - const base::string16& word) { - base::string16 autocorrect_word; - - int word_length = static_cast(word.size()); - if (word_length < 2 || word_length > kMaxAutoCorrectWordSize) - return autocorrect_word; - - base::char16 misspelled_word[kMaxAutoCorrectWordSize + 1]; - const base::char16* word_char = word.c_str(); - for (int i = 0; i <= kMaxAutoCorrectWordSize; ++i) { - if (i >= word_length) - misspelled_word[i] = 0; - else - misspelled_word[i] = word_char[i]; - } - - // Swap adjacent characters and spellcheck. - int misspelling_start, misspelling_len; - for (int i = 0; i < word_length - 1; i++) { - // Swap. - std::swap(misspelled_word[i], misspelled_word[i + 1]); - - // Check spelling. - misspelling_start = misspelling_len = 0; - spellCheck(blink::WebString(misspelled_word, word_length), - misspelling_start, - misspelling_len, - NULL); - - // Make decision: if only one swap produced a valid word, then we want to - // return it. If we found two or more, we don't do autocorrection. - if (misspelling_len == 0) { - if (autocorrect_word.empty()) { - autocorrect_word.assign(misspelled_word); - } else { - autocorrect_word.clear(); - break; - } - } - - // Restore the swapped characters. - std::swap(misspelled_word[i], misspelled_word[i + 1]); - } - return autocorrect_word; -} - // Returns whether or not the given string is a valid contraction. // This function is a fall-back when the SpellcheckWordIterator class // returns a concatenated word which is not in the selected dictionary diff --git a/atom/renderer/api/atom_api_spell_check_client.h b/atom/renderer/api/atom_api_spell_check_client.h index 345cad186ac..af72756e2ec 100644 --- a/atom/renderer/api/atom_api_spell_check_client.h +++ b/atom/renderer/api/atom_api_spell_check_client.h @@ -41,8 +41,6 @@ class SpellCheckClient : public blink::WebSpellCheckClient { const blink::WebVector& markersInText, const blink::WebVector& markerOffsets, blink::WebTextCheckingCompletion* completionCallback) override; - blink::WebString autoCorrectWord( - const blink::WebString& misspelledWord) override; void showSpellingUI(bool show) override; bool isShowingSpellingUI() override; void updateSpellingUIWithMisspelledWord( diff --git a/chromium_src/chrome/browser/browser_process.h b/chromium_src/chrome/browser/browser_process.h index f971320f821..8baa899f7ad 100644 --- a/chromium_src/chrome/browser/browser_process.h +++ b/chromium_src/chrome/browser/browser_process.h @@ -12,7 +12,7 @@ #include -#include "base/basictypes.h" +#include "base/macros.h" #include "base/memory/scoped_ptr.h" namespace printing { diff --git a/chromium_src/chrome/browser/extensions/global_shortcut_listener.h b/chromium_src/chrome/browser/extensions/global_shortcut_listener.h index 1f07df2b6e1..9aec54a3263 100644 --- a/chromium_src/chrome/browser/extensions/global_shortcut_listener.h +++ b/chromium_src/chrome/browser/extensions/global_shortcut_listener.h @@ -7,7 +7,7 @@ #include -#include "base/basictypes.h" +#include "base/macros.h" #include "ui/events/keycodes/keyboard_codes.h" namespace ui { diff --git a/chromium_src/chrome/browser/media/desktop_media_list.h b/chromium_src/chrome/browser/media/desktop_media_list.h index 7ef703e8b7b..6572e792a12 100644 --- a/chromium_src/chrome/browser/media/desktop_media_list.h +++ b/chromium_src/chrome/browser/media/desktop_media_list.h @@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_ #define CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_ -#include "base/basictypes.h" #include "base/strings/string16.h" #include "base/time/time.h" #include "content/public/browser/desktop_media_id.h" diff --git a/chromium_src/chrome/browser/media/native_desktop_media_list.cc b/chromium_src/chrome/browser/media/native_desktop_media_list.cc index 4a7fb58962c..3c1848df3ef 100644 --- a/chromium_src/chrome/browser/media/native_desktop_media_list.cc +++ b/chromium_src/chrome/browser/media/native_desktop_media_list.cc @@ -34,7 +34,7 @@ const int kDefaultUpdatePeriod = 1000; // Returns a hash of a DesktopFrame content to detect when image for a desktop // media source has changed. -uint32 GetFrameHash(webrtc::DesktopFrame* frame) { +uint32_t GetFrameHash(webrtc::DesktopFrame* frame) { int data_size = frame->stride() * frame->size().height(); return base::SuperFastHash(reinterpret_cast(frame->data()), data_size); } @@ -117,8 +117,8 @@ NativeDesktopMediaList::Worker::Worker( scoped_ptr screen_capturer, scoped_ptr window_capturer) : media_list_(media_list), - screen_capturer_(screen_capturer.Pass()), - window_capturer_(window_capturer.Pass()) { + screen_capturer_(std::move(screen_capturer)), + window_capturer_(std::move(window_capturer)) { if (screen_capturer_) screen_capturer_->Start(this); if (window_capturer_) @@ -195,14 +195,14 @@ void NativeDesktopMediaList::Worker::Refresh( // |current_frame_| may be NULL if capture failed (e.g. because window has // been closed). if (current_frame_) { - uint32 frame_hash = GetFrameHash(current_frame_.get()); + uint32_t frame_hash = GetFrameHash(current_frame_.get()); new_image_hashes[source.id] = frame_hash; // Scale the image only if it has changed. ImageHashesMap::iterator it = image_hashes_.find(source.id); if (it == image_hashes_.end() || it->second != frame_hash) { gfx::ImageSkia thumbnail = - ScaleDesktopFrame(current_frame_.Pass(), thumbnail_size); + ScaleDesktopFrame(std::move(current_frame_), thumbnail_size); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&NativeDesktopMediaList::OnSourceThumbnail, @@ -231,8 +231,8 @@ void NativeDesktopMediaList::Worker::OnCaptureCompleted( NativeDesktopMediaList::NativeDesktopMediaList( scoped_ptr screen_capturer, scoped_ptr window_capturer) - : screen_capturer_(screen_capturer.Pass()), - window_capturer_(window_capturer.Pass()), + : screen_capturer_(std::move(screen_capturer)), + window_capturer_(std::move(window_capturer)), update_period_(base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)), thumbnail_size_(100, 100), view_dialog_id_(-1), @@ -269,7 +269,8 @@ void NativeDesktopMediaList::StartUpdating(DesktopMediaListObserver* observer) { observer_ = observer; worker_.reset(new Worker(weak_factory_.GetWeakPtr(), - screen_capturer_.Pass(), window_capturer_.Pass())); + std::move(screen_capturer_), + std::move(window_capturer_))); Refresh(); } diff --git a/chromium_src/chrome/browser/media/native_desktop_media_list.h b/chromium_src/chrome/browser/media/native_desktop_media_list.h index 943d3dd3256..f789a368be9 100644 --- a/chromium_src/chrome/browser/media/native_desktop_media_list.h +++ b/chromium_src/chrome/browser/media/native_desktop_media_list.h @@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_ #define CHROME_BROWSER_MEDIA_NATIVE_DESKTOP_MEDIA_LIST_H_ -#include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" diff --git a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc index 9064cd961bd..2231ed8b0dc 100644 --- a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc +++ b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc @@ -256,7 +256,7 @@ void LazyEmf::Close() const { bool LazyEmf::LoadEmf(Emf* emf) const { file_->Seek(base::File::FROM_BEGIN, 0); - int64 size = file_->GetLength(); + int64_t size = file_->GetLength(); if (size <= 0) return false; std::vector data(size); diff --git a/chromium_src/chrome/browser/printing/print_job.cc b/chromium_src/chrome/browser/printing/print_job.cc index 65449ef121e..60dcebe0803 100644 --- a/chromium_src/chrome/browser/printing/print_job.cc +++ b/chromium_src/chrome/browser/printing/print_job.cc @@ -441,7 +441,7 @@ void PrintJob::HoldUntilStopIsCalled() { } void PrintJob::Quit() { - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); } // Takes settings_ ownership and will be deleted in the receiving thread. diff --git a/chromium_src/chrome/browser/printing/print_job.h b/chromium_src/chrome/browser/printing/print_job.h index 48daaa6cb97..4963a94f14f 100644 --- a/chromium_src/chrome/browser/printing/print_job.h +++ b/chromium_src/chrome/browser/printing/print_job.h @@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_PRINTING_PRINT_JOB_H_ #define CHROME_BROWSER_PRINTING_PRINT_JOB_H_ -#include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" diff --git a/chromium_src/chrome/browser/printing/print_preview_message_handler.cc b/chromium_src/chrome/browser/printing/print_preview_message_handler.cc index 613f3f2343c..a195ad4c6ad 100644 --- a/chromium_src/chrome/browser/printing/print_preview_message_handler.cc +++ b/chromium_src/chrome/browser/printing/print_preview_message_handler.cc @@ -118,7 +118,7 @@ void PrintPreviewMessageHandler::PrintToPDF( } void PrintPreviewMessageHandler::RunPrintToPDFCallback( - int request_id, uint32 data_size, char* data) { + int request_id, uint32_t data_size, char* data) { DCHECK_CURRENTLY_ON(BrowserThread::UI); v8::Isolate* isolate = v8::Isolate::GetCurrent(); diff --git a/chromium_src/chrome/browser/printing/print_preview_message_handler.h b/chromium_src/chrome/browser/printing/print_preview_message_handler.h index 453d78761bb..1aac74baa22 100644 --- a/chromium_src/chrome/browser/printing/print_preview_message_handler.h +++ b/chromium_src/chrome/browser/printing/print_preview_message_handler.h @@ -47,7 +47,7 @@ class PrintPreviewMessageHandler const PrintHostMsg_DidPreviewDocument_Params& params); void OnPrintPreviewFailed(int document_cookie, int request_id); - void RunPrintToPDFCallback(int request_id, uint32 data_size, char* data); + void RunPrintToPDFCallback(int request_id, uint32_t data_size, char* data); PrintToPDFCallbackMap print_to_pdf_callback_map_; diff --git a/chromium_src/chrome/browser/printing/print_view_manager_base.cc b/chromium_src/chrome/browser/printing/print_view_manager_base.cc index ede1d3b8ba8..688256e4251 100644 --- a/chromium_src/chrome/browser/printing/print_view_manager_base.cc +++ b/chromium_src/chrome/browser/printing/print_view_manager_base.cc @@ -144,7 +144,7 @@ void PrintViewManagerBase::OnDidPrintPage( #if !defined(OS_WIN) // Update the rendered document. It will send notifications to the listener. document->SetPage(params.page_number, - metafile.Pass(), + std::move(metafile), params.page_size, params.content_area); @@ -305,7 +305,7 @@ void PrintViewManagerBase::ShouldQuitFromInnerMessageLoop() { inside_inner_message_loop_) { // We are in a message loop created by RenderAllMissingPagesNow. Quit from // it. - base::MessageLoop::current()->Quit(); + base::MessageLoop::current()->QuitWhenIdle(); inside_inner_message_loop_ = false; } } @@ -411,9 +411,9 @@ bool PrintViewManagerBase::RunInnerMessageLoop() { // memory-bound. static const int kPrinterSettingsTimeout = 60000; base::OneShotTimer quit_timer; - quit_timer.Start(FROM_HERE, - TimeDelta::FromMilliseconds(kPrinterSettingsTimeout), - base::MessageLoop::current(), &base::MessageLoop::Quit); + quit_timer.Start( + FROM_HERE, TimeDelta::FromMilliseconds(kPrinterSettingsTimeout), + base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle); inside_inner_message_loop_ = true; diff --git a/chromium_src/chrome/browser/printing/printing_message_filter.cc b/chromium_src/chrome/browser/printing/printing_message_filter.cc index 6fd536ef68c..eac4405fbcf 100644 --- a/chromium_src/chrome/browser/printing/printing_message_filter.cc +++ b/chromium_src/chrome/browser/printing/printing_message_filter.cc @@ -394,7 +394,7 @@ void PrintingMessageFilter::OnUpdatePrintSettings( printer_query = queue_->CreatePrinterQuery(host_id, routing_id); } printer_query->SetSettings( - new_settings.Pass(), + std::move(new_settings), base::Bind(&PrintingMessageFilter::OnUpdatePrintSettingsReply, this, printer_query, reply_msg)); } diff --git a/chromium_src/chrome/browser/printing/printing_message_filter.h b/chromium_src/chrome/browser/printing/printing_message_filter.h index 624b28fd35d..e8536a69c5a 100644 --- a/chromium_src/chrome/browser/printing/printing_message_filter.h +++ b/chromium_src/chrome/browser/printing/printing_message_filter.h @@ -107,7 +107,7 @@ class PrintingMessageFilter : public content::BrowserMessageFilter { #if defined(ENABLE_FULL_PRINTING) // Check to see if print preview has been cancelled. - void OnCheckForCancel(int32 preview_ui_id, + void OnCheckForCancel(int32_t preview_ui_id, int preview_request_id, bool* cancel); #endif diff --git a/chromium_src/chrome/browser/printing/printing_ui_web_contents_observer.h b/chromium_src/chrome/browser/printing/printing_ui_web_contents_observer.h index 66d51e7fba2..de969f5cdb5 100644 --- a/chromium_src/chrome/browser/printing/printing_ui_web_contents_observer.h +++ b/chromium_src/chrome/browser/printing/printing_ui_web_contents_observer.h @@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_PRINTING_PRINTING_UI_WEB_CONTENTS_OBSERVER_H_ #define CHROME_BROWSER_PRINTING_PRINTING_UI_WEB_CONTENTS_OBSERVER_H_ -#include "base/basictypes.h" #include "content/public/browser/web_contents_observer.h" #include "ui/gfx/native_widget_types.h" diff --git a/chromium_src/chrome/browser/process_singleton.h b/chromium_src/chrome/browser/process_singleton.h index 3eeb53393e1..eab6c35479a 100644 --- a/chromium_src/chrome/browser/process_singleton.h +++ b/chromium_src/chrome/browser/process_singleton.h @@ -12,7 +12,6 @@ #include #include -#include "base/basictypes.h" #include "base/callback.h" #include "base/command_line.h" #include "base/files/file_path.h" diff --git a/chromium_src/chrome/browser/process_singleton_posix.cc b/chromium_src/chrome/browser/process_singleton_posix.cc index 98fb948730e..7e54d9b5d37 100644 --- a/chromium_src/chrome/browser/process_singleton_posix.cc +++ b/chromium_src/chrome/browser/process_singleton_posix.cc @@ -54,7 +54,6 @@ #include "atom/common/atom_command_line.h" #include "base/base_paths.h" -#include "base/basictypes.h" #include "base/bind.h" #include "base/command_line.h" #include "base/files/file_path.h" @@ -75,6 +74,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/thread_task_runner_handle.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" #include "base/timer/timer.h" @@ -222,7 +222,7 @@ int SetupSocketOnly() { int sock = socket(PF_UNIX, SOCK_STREAM, 0); PCHECK(sock >= 0) << "socket() failed"; - int rv = net::SetNonBlocking(sock); + int rv = base::SetNonBlocking(sock); DCHECK_EQ(0, rv) << "Failed to make non-blocking socket."; rv = SetCloseOnExec(sock); DCHECK_EQ(0, rv) << "Failed to set CLOEXEC on socket."; @@ -577,7 +577,7 @@ void ProcessSingleton::LinuxWatcher::OnFileCanReadWithoutBlocking(int fd) { PLOG(ERROR) << "accept() failed"; return; } - int rv = net::SetNonBlocking(connection_socket); + int rv = base::SetNonBlocking(connection_socket); DCHECK_EQ(0, rv) << "Failed to make non-blocking socket."; SocketReader* reader = new SocketReader(this, ui_message_loop_, @@ -990,8 +990,8 @@ bool ProcessSingleton::Create() { // In Electron the ProcessSingleton is created earlier than the IO // thread gets created, so we have to postpone the call until message // loop is up an running. - scoped_refptr task_runner( - base::ThreadTaskRunnerHandle::Get()); + scoped_refptr task_runner = + base::ThreadTaskRunnerHandle::Get(); task_runner->PostTask( FROM_HERE, base::Bind(&ProcessSingleton::StartListening, diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h index 6fb4aced181..40a03a1ff56 100644 --- a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h @@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ #define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FLASH_BROWSER_HOST_H_ -#include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "ppapi/host/host_message_context.h" diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc index fdc054f59fb..9ddb9fa56d7 100644 --- a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc @@ -240,8 +240,8 @@ int32_t PepperFlashClipboardMessageFilter::OnMsgReadData( base::string16 html; std::string url; - uint32 fragment_start; - uint32 fragment_end; + uint32_t fragment_start; + uint32_t fragment_end; clipboard->ReadHTML(type, &html, &url, &fragment_start, &fragment_end); result = PP_OK; clipboard_string = base::UTF16ToUTF8( diff --git a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h index ff07eb73750..4c146dd5daa 100644 --- a/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h +++ b/chromium_src/chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h @@ -8,8 +8,6 @@ #include #include -#include "base/basictypes.h" -#include "base/compiler_specific.h" #include "ppapi/host/resource_message_filter.h" #include "ppapi/shared_impl/flash_clipboard_format_registry.h" diff --git a/chromium_src/chrome/browser/ui/cocoa/color_chooser_mac.mm b/chromium_src/chrome/browser/ui/cocoa/color_chooser_mac.mm index cb366022d6e..6183dd5d5bd 100644 --- a/chromium_src/chrome/browser/ui/cocoa/color_chooser_mac.mm +++ b/chromium_src/chrome/browser/ui/cocoa/color_chooser_mac.mm @@ -74,7 +74,7 @@ ColorChooserMac::ColorChooserMac(content::WebContents* web_contents, SkColor initial_color) : web_contents_(web_contents) { panel_.reset([[ColorPanelCocoa alloc] initWithChooser:this]); - [panel_ setColor:gfx::SkColorToDeviceNSColor(initial_color)]; + [panel_ setColor:skia::SkColorToDeviceNSColor(initial_color)]; [[NSColorPanel sharedColorPanel] makeKeyAndOrderFront:nil]; } @@ -101,7 +101,7 @@ void ColorChooserMac::End() { } void ColorChooserMac::SetSelectedColor(SkColor color) { - [panel_ setColor:gfx::SkColorToDeviceNSColor(color)]; + [panel_ setColor:skia::SkColorToDeviceNSColor(color)]; } @implementation ColorPanelCocoa @@ -139,7 +139,7 @@ void ColorChooserMac::SetSelectedColor(SkColor color) { nonUserChange_ = NO; return; } - chooser_->DidChooseColorInColorPanel(gfx::NSDeviceColorToSkColor( + chooser_->DidChooseColorInColorPanel(skia::NSDeviceColorToSkColor( [[panel color] colorUsingColorSpaceName:NSDeviceRGBColorSpace])); nonUserChange_ = NO; } diff --git a/chromium_src/chrome/browser/ui/views/color_chooser_aura.h b/chromium_src/chrome/browser/ui/views/color_chooser_aura.h index 6394b973a3d..ba6709889e6 100644 --- a/chromium_src/chrome/browser/ui/views/color_chooser_aura.h +++ b/chromium_src/chrome/browser/ui/views/color_chooser_aura.h @@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_UI_VIEWS_COLOR_CHOOSER_AURA_H_ #define CHROME_BROWSER_UI_VIEWS_COLOR_CHOOSER_AURA_H_ -#include "base/basictypes.h" -#include "base/compiler_specific.h" #include "content/public/browser/color_chooser.h" #include "ui/views/color_chooser/color_chooser_listener.h" diff --git a/chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h b/chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h index 694f776b24e..95a08b229f4 100644 --- a/chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h +++ b/chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h @@ -9,7 +9,6 @@ #include -#include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/singleton.h" #include "ui/base/glib/glib_signal.h" diff --git a/chromium_src/chrome/common/print_messages.cc b/chromium_src/chrome/common/print_messages.cc index 5f8e30f3698..b0ec282382d 100644 --- a/chromium_src/chrome/common/print_messages.cc +++ b/chromium_src/chrome/common/print_messages.cc @@ -4,7 +4,6 @@ #include "chrome/common/print_messages.h" -#include "base/basictypes.h" #include "base/strings/string16.h" #include "ui/gfx/geometry/size.h" diff --git a/chromium_src/chrome/common/print_messages.h b/chromium_src/chrome/common/print_messages.h index cd775d0478b..034691b5b95 100644 --- a/chromium_src/chrome/common/print_messages.h +++ b/chromium_src/chrome/common/print_messages.h @@ -161,7 +161,7 @@ IPC_STRUCT_BEGIN(PrintHostMsg_DidPrintPage_Params) IPC_STRUCT_MEMBER(base::SharedMemoryHandle, metafile_data_handle) // Size of the metafile data. - IPC_STRUCT_MEMBER(uint32, data_size) + IPC_STRUCT_MEMBER(uint32_t, data_size) // Cookie for the document to ensure correctness. IPC_STRUCT_MEMBER(int, document_cookie) @@ -193,7 +193,7 @@ IPC_STRUCT_BEGIN(PrintHostMsg_DidPreviewDocument_Params) IPC_STRUCT_MEMBER(base::SharedMemoryHandle, metafile_data_handle) // Size of metafile data. - IPC_STRUCT_MEMBER(uint32, data_size) + IPC_STRUCT_MEMBER(uint32_t, data_size) // Cookie for the document to ensure correctness. IPC_STRUCT_MEMBER(int, document_cookie) diff --git a/chromium_src/chrome/common/tts_utterance_request.h b/chromium_src/chrome/common/tts_utterance_request.h index e0b7adfa4a0..a4b4cab68ca 100644 --- a/chromium_src/chrome/common/tts_utterance_request.h +++ b/chromium_src/chrome/common/tts_utterance_request.h @@ -7,7 +7,7 @@ #include -#include "base/basictypes.h" +#include "base/macros.h" #include "base/strings/string16.h" struct TtsUtteranceRequest { @@ -41,4 +41,4 @@ struct TtsUtteranceResponse { int id; }; -#endif // CHROME_COMMON_TTS_UTTERANCE_REQUEST_H_ \ No newline at end of file +#endif // CHROME_COMMON_TTS_UTTERANCE_REQUEST_H_ diff --git a/chromium_src/chrome/common/widevine_cdm_constants.cc b/chromium_src/chrome/common/widevine_cdm_constants.cc index 60f487e2ae8..587966a9c36 100644 --- a/chromium_src/chrome/common/widevine_cdm_constants.cc +++ b/chromium_src/chrome/common/widevine_cdm_constants.cc @@ -12,5 +12,5 @@ const base::FilePath::CharType kWidevineCdmBaseDirectory[] = const char kWidevineCdmPluginExtension[] = ""; -const int32 kWidevineCdmPluginPermissions = ppapi::PERMISSION_DEV | - ppapi::PERMISSION_PRIVATE; +const int32_t kWidevineCdmPluginPermissions = ppapi::PERMISSION_DEV | + ppapi::PERMISSION_PRIVATE; diff --git a/chromium_src/chrome/common/widevine_cdm_constants.h b/chromium_src/chrome/common/widevine_cdm_constants.h index b626079a11b..9597b1cb41f 100644 --- a/chromium_src/chrome/common/widevine_cdm_constants.h +++ b/chromium_src/chrome/common/widevine_cdm_constants.h @@ -5,7 +5,7 @@ #ifndef CHROME_COMMON_WIDEVINE_CDM_CONSTANTS_H_ #define CHROME_COMMON_WIDEVINE_CDM_CONSTANTS_H_ -#include "base/basictypes.h" +#include "base/macros.h" #include "base/files/file_path.h" // The Widevine CDM adapter and Widevine CDM are in this directory. @@ -14,6 +14,6 @@ extern const base::FilePath::CharType kWidevineCdmBaseDirectory[]; extern const char kWidevineCdmPluginExtension[]; // Permission bits for Widevine CDM plugin. -extern const int32 kWidevineCdmPluginPermissions; +extern const int32_t kWidevineCdmPluginPermissions; #endif // CHROME_COMMON_WIDEVINE_CDM_CONSTANTS_H_ diff --git a/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h b/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h index 13ab2853a35..dd12e9d9160 100644 --- a/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h +++ b/chromium_src/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.h @@ -5,8 +5,6 @@ #ifndef CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_ #define CHROME_RENDERER_PEPPER_CHROME_RENDERER_PEPPER_HOST_FACTORY_H_ -#include "base/basictypes.h" -#include "base/compiler_specific.h" #include "ppapi/host/host_factory.h" namespace content { diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h b/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h index 02bb30f315f..eeaa7209b5f 100644 --- a/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_font_file_host.h @@ -5,8 +5,6 @@ #ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_ #define CHROME_RENDERER_PEPPER_PEPPER_FLASH_FONT_FILE_HOST_H_ -#include "base/basictypes.h" -#include "base/compiler_specific.h" #include "ppapi/c/private/pp_private_font_charset.h" #include "ppapi/host/resource_host.h" diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h b/chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h index 3550ea13663..86d0af73aee 100644 --- a/chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_fullscreen_host.h @@ -5,8 +5,6 @@ #ifndef CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_ #define CHROME_RENDERER_PEPPER_PEPPER_FLASH_FULLSCREEN_HOST_H_ -#include "base/basictypes.h" -#include "base/compiler_specific.h" #include "ppapi/host/resource_host.h" namespace content { diff --git a/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h b/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h index de22f46045a..f37907a8655 100644 --- a/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h +++ b/chromium_src/chrome/renderer/pepper/pepper_flash_renderer_host.h @@ -8,7 +8,6 @@ #include #include -#include "base/basictypes.h" #include "base/memory/weak_ptr.h" #include "ppapi/host/host_message_context.h" #include "ppapi/host/resource_host.h" diff --git a/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc b/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc index 3ef6dff0c8b..6fbadd12116 100644 --- a/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc +++ b/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.cc @@ -43,9 +43,8 @@ void PepperSharedMemoryMessageFilter::OnHostMsgCreateSharedMemory( ppapi::proxy::SerializedHandle* plugin_handle) { plugin_handle->set_null_shmem(); *host_handle_id = -1; - scoped_ptr shm(content::RenderThread::Get() - ->HostAllocateSharedMemoryBuffer(size) - .Pass()); + scoped_ptr shm( + content::RenderThread::Get()->HostAllocateSharedMemoryBuffer(size)); if (!shm.get()) return; diff --git a/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h b/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h index d7e0934cd6e..860e1c9dbd1 100644 --- a/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h +++ b/chromium_src/chrome/renderer/pepper/pepper_shared_memory_message_filter.h @@ -5,8 +5,6 @@ #ifndef CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_ #define CHROME_RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_ -#include "base/basictypes.h" -#include "base/compiler_specific.h" #include "ppapi/c/pp_instance.h" #include "ppapi/host/instance_message_filter.h" diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper.cc index 3bfe719a0c9..924553b5cff 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper.cc @@ -415,22 +415,19 @@ class PrepareFrameAndViewForPrint : public blink::WebViewClient, return owns_web_view_ && frame() && frame()->isLoading(); } - // TODO(ojan): Remove this override and have this class use a non-null - // layerTreeView. - // blink::WebViewClient override: - virtual bool allowsBrokenNullLayerTreeView() const; - protected: // blink::WebViewClient override: - virtual void didStopLoading(); + void didStopLoading() override; + bool allowsBrokenNullLayerTreeView() const override; - // blink::WebFrameClient override: - virtual blink::WebFrame* createChildFrame( + // blink::WebFrameClient: + blink::WebFrame* createChildFrame( blink::WebLocalFrame* parent, blink::WebTreeScopeType scope, const blink::WebString& name, - blink::WebSandboxFlags sandboxFlags); - virtual void frameDetached(blink::WebFrame* frame, DetachType type); + blink::WebSandboxFlags sandboxFlags, + const blink::WebFrameOwnerProperties& frameOwnerProperties) override; + void frameDetached(blink::WebFrame* frame, DetachType type) override; private: void CallOnReady(); @@ -576,7 +573,8 @@ blink::WebFrame* PrepareFrameAndViewForPrint::createChildFrame( blink::WebLocalFrame* parent, blink::WebTreeScopeType scope, const blink::WebString& name, - blink::WebSandboxFlags sandboxFlags) { + blink::WebSandboxFlags sandboxFlags, + const blink::WebFrameOwnerProperties& frameOwnerProperties) { blink::WebFrame* frame = blink::WebLocalFrame::create(scope, this); parent->appendChild(frame); return frame; @@ -814,7 +812,7 @@ bool PrintWebViewHelper::FinalizePrintReadyDocument() { // Get the size of the resulting metafile. PdfMetafileSkia* metafile = print_preview_context_.metafile(); - uint32 buf_size = metafile->GetDataSize(); + uint32_t buf_size = metafile->GetDataSize(); DCHECK_GT(buf_size, 0u); PrintHostMsg_DidPreviewDocument_Params preview_params; @@ -1164,7 +1162,7 @@ bool PrintWebViewHelper::RenderPagesForPrint(blink::WebLocalFrame* frame, bool PrintWebViewHelper::CopyMetafileDataToSharedMem( PdfMetafileSkia* metafile, base::SharedMemoryHandle* shared_mem_handle) { - uint32 buf_size = metafile->GetDataSize(); + uint32_t buf_size = metafile->GetDataSize(); scoped_ptr shared_buf( content::RenderThread::Get()->HostAllocateSharedMemoryBuffer( buf_size).release()); diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc index 82d7779d026..62267f8f45f 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc @@ -92,7 +92,7 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame, metafile.FinishDocument(); // Get the size of the resulting metafile. - uint32 buf_size = metafile.GetDataSize(); + uint32_t buf_size = metafile.GetDataSize(); DCHECK_GT(buf_size, 0u); #if defined(OS_CHROMEOS) || defined(OS_ANDROID) diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm b/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm index 0785e30a9cf..3b1a0593d06 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm @@ -116,15 +116,13 @@ void PrintWebViewHelper::RenderPage(const PrintMsg_Print_Params& params, gfx::Rect canvas_area = content_area; { - skia::PlatformCanvas* canvas = metafile->GetVectorCanvasForNewPage( + SkCanvas* canvas = metafile->GetVectorCanvasForNewPage( *page_size, canvas_area, scale_factor); if (!canvas) return; MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile); - skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_); skia::SetIsPreviewMetafile(*canvas, is_preview); - RenderPageContent(frame, page_number, canvas_area, content_area, scale_factor, static_cast(canvas)); } diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc index 0b21de46995..243e9ab7522 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc @@ -96,7 +96,7 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame, metafile.FinishDocument(); // Get the size of the resulting metafile. - uint32 buf_size = metafile.GetDataSize(); + uint32_t buf_size = metafile.GetDataSize(); DCHECK_GT(buf_size, 0u); PrintHostMsg_DidPrintPage_Params printed_page_params; @@ -218,7 +218,7 @@ void PrintWebViewHelper::PrintPageInternal( bool PrintWebViewHelper::CopyMetafileDataToSharedMem( PdfMetafileSkia* metafile, base::SharedMemoryHandle* shared_mem_handle) { - uint32 buf_size = metafile->GetDataSize(); + uint32_t buf_size = metafile->GetDataSize(); base::SharedMemory shared_buf; // Allocate a shared memory buffer to hold the generated metafile data. if (!shared_buf.CreateAndMapAnonymous(buf_size)) { diff --git a/chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.cc b/chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.cc index 815a9c08b34..a3b51a8c46e 100644 --- a/chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.cc +++ b/chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.cc @@ -9,7 +9,6 @@ #include #include -#include "base/basictypes.h" #include "base/i18n/break_iterator.h" #include "base/logging.h" #include "base/strings/stringprintf.h" @@ -332,7 +331,7 @@ bool SpellcheckWordIterator::Initialize( NOTREACHED() << "failed to open iterator (broken rules)"; return false; } - iterator_ = iterator.Pass(); + iterator_ = std::move(iterator); // Set the character attributes so we can normalize the words extracted by // this iterator. diff --git a/chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h b/chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h index 2ac28a2e240..03fd8e666f5 100644 --- a/chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h +++ b/chromium_src/chrome/renderer/spellchecker/spellcheck_worditerator.h @@ -11,7 +11,7 @@ #include -#include "base/basictypes.h" +#include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" #include "third_party/icu/source/common/unicode/uscript.h" diff --git a/chromium_src/chrome/renderer/tts_dispatcher.cc b/chromium_src/chrome/renderer/tts_dispatcher.cc index 91b67ba1674..0d3b97c8454 100644 --- a/chromium_src/chrome/renderer/tts_dispatcher.cc +++ b/chromium_src/chrome/renderer/tts_dispatcher.cc @@ -4,7 +4,6 @@ #include "chrome/renderer/tts_dispatcher.h" -#include "base/basictypes.h" #include "base/strings/utf_string_conversions.h" #include "chrome/common/tts_messages.h" #include "chrome/common/tts_utterance_request.h" @@ -197,4 +196,4 @@ void TtsDispatcher::OnSpeakingErrorOccurred(int utterance_id, // The web speech API doesn't support an error message. synthesizer_client_->speakingErrorOccurred(utterance); utterance_id_map_.erase(utterance_id); -} \ No newline at end of file +} diff --git a/chromium_src/chrome/renderer/tts_dispatcher.h b/chromium_src/chrome/renderer/tts_dispatcher.h index fd18acba206..0a770d72183 100644 --- a/chromium_src/chrome/renderer/tts_dispatcher.h +++ b/chromium_src/chrome/renderer/tts_dispatcher.h @@ -7,8 +7,6 @@ #include -#include "base/basictypes.h" -#include "base/compiler_specific.h" #include "base/containers/hash_tables.h" #include "content/public/renderer/render_process_observer.h" #include "third_party/WebKit/public/platform/WebSpeechSynthesizer.h" @@ -75,4 +73,4 @@ class TtsDispatcher DISALLOW_COPY_AND_ASSIGN(TtsDispatcher); }; -#endif // CHROME_RENDERER_TTS_DISPATCHER_H_ \ No newline at end of file +#endif // CHROME_RENDERER_TTS_DISPATCHER_H_ diff --git a/chromium_src/chrome/utility/printing_handler_win.cc b/chromium_src/chrome/utility/printing_handler_win.cc index ec908d19fc5..805cd6e343c 100644 --- a/chromium_src/chrome/utility/printing_handler_win.cc +++ b/chromium_src/chrome/utility/printing_handler_win.cc @@ -177,7 +177,7 @@ int PrintingHandlerWin::LoadPDF(base::File pdf_file) { if (!g_pdf_lib.Get().IsValid()) return 0; - int64 length64 = pdf_file.GetLength(); + int64_t length64 = pdf_file.GetLength(); if (length64 <= 0 || length64 > std::numeric_limits::max()) return 0; int length = static_cast(length64); diff --git a/chromium_src/net/test/embedded_test_server/stream_listen_socket.cc b/chromium_src/net/test/embedded_test_server/stream_listen_socket.cc index 897b23bbd56..6495b23b840 100644 --- a/chromium_src/net/test/embedded_test_server/stream_listen_socket.cc +++ b/chromium_src/net/test/embedded_test_server/stream_listen_socket.cc @@ -17,6 +17,7 @@ #include "net/base/net_errors.h" #endif +#include "base/files/file_util.h" #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" @@ -27,6 +28,7 @@ #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" +#include "net/base/sockaddr_storage.h" #include "net/socket/socket_descriptor.h" using std::string; @@ -125,7 +127,7 @@ SocketDescriptor StreamListenSocket::AcceptSocket() { if (conn == kInvalidSocket) LOG(ERROR) << "Error accepting connection."; else - SetNonBlocking(conn); + base::SetNonBlocking(conn); return conn; } diff --git a/chromium_src/net/test/embedded_test_server/stream_listen_socket.h b/chromium_src/net/test/embedded_test_server/stream_listen_socket.h index 02a8b9827a2..9df51258306 100644 --- a/chromium_src/net/test/embedded_test_server/stream_listen_socket.h +++ b/chromium_src/net/test/embedded_test_server/stream_listen_socket.h @@ -28,7 +28,7 @@ #include "base/message_loop/message_loop.h" #endif -#include "base/basictypes.h" +#include "base/macros.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "net/base/net_export.h" diff --git a/chromium_src/net/test/embedded_test_server/tcp_listen_socket.cc b/chromium_src/net/test/embedded_test_server/tcp_listen_socket.cc index 418f3459212..fbdcc2bfc7e 100644 --- a/chromium_src/net/test/embedded_test_server/tcp_listen_socket.cc +++ b/chromium_src/net/test/embedded_test_server/tcp_listen_socket.cc @@ -34,14 +34,14 @@ namespace test_server { // static scoped_ptr TCPListenSocket::CreateAndListen( const string& ip, - uint16 port, + uint16_t port, StreamListenSocket::Delegate* del) { SocketDescriptor s = CreateAndBind(ip, port); if (s == kInvalidSocket) return scoped_ptr(); scoped_ptr sock(new TCPListenSocket(s, del)); sock->Listen(); - return sock.Pass(); + return sock; } TCPListenSocket::TCPListenSocket(SocketDescriptor s, @@ -52,7 +52,8 @@ TCPListenSocket::TCPListenSocket(SocketDescriptor s, TCPListenSocket::~TCPListenSocket() { } -SocketDescriptor TCPListenSocket::CreateAndBind(const string& ip, uint16 port) { +SocketDescriptor TCPListenSocket::CreateAndBind(const string& ip, + uint16_t port) { SocketDescriptor s = CreatePlatformSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s != kInvalidSocket) { #if defined(OS_POSIX) @@ -79,7 +80,7 @@ SocketDescriptor TCPListenSocket::CreateAndBind(const string& ip, uint16 port) { } SocketDescriptor TCPListenSocket::CreateAndBindAnyPort(const string& ip, - uint16* port) { + uint16_t* port) { SocketDescriptor s = CreateAndBind(ip, 0); if (s == kInvalidSocket) return kInvalidSocket; @@ -110,7 +111,7 @@ void TCPListenSocket::Accept() { #if defined(OS_POSIX) sock->WatchSocket(WAITING_READ); #endif - socket_delegate_->DidAccept(this, sock.Pass()); + socket_delegate_->DidAccept(this, std::move(sock)); } } // namespace test_server diff --git a/chromium_src/net/test/embedded_test_server/tcp_listen_socket.h b/chromium_src/net/test/embedded_test_server/tcp_listen_socket.h index 12b3fa40745..6990845f392 100644 --- a/chromium_src/net/test/embedded_test_server/tcp_listen_socket.h +++ b/chromium_src/net/test/embedded_test_server/tcp_listen_socket.h @@ -7,7 +7,7 @@ #include -#include "base/basictypes.h" +#include "base/macros.h" #include "net/base/net_export.h" #include "net/socket/socket_descriptor.h" #include "net/test/embedded_test_server/stream_listen_socket.h" @@ -25,7 +25,7 @@ class TCPListenSocket : public StreamListenSocket { // accept local connections. static scoped_ptr CreateAndListen( const std::string& ip, - uint16 port, + uint16_t port, StreamListenSocket::Delegate* del); protected: @@ -39,11 +39,11 @@ class TCPListenSocket : public StreamListenSocket { friend class TCPListenSocketTester; // Get raw TCP socket descriptor bound to ip:port. - static SocketDescriptor CreateAndBind(const std::string& ip, uint16 port); + static SocketDescriptor CreateAndBind(const std::string& ip, uint16_t port); // Get raw TCP socket descriptor bound to ip and return port it is bound to. static SocketDescriptor CreateAndBindAnyPort(const std::string& ip, - uint16* port); + uint16_t* port); DISALLOW_COPY_AND_ASSIGN(TCPListenSocket); }; diff --git a/vendor/brightray b/vendor/brightray index 2a29ea6c1de..70f475e34dd 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 2a29ea6c1de3accd01f1883ac94326220349bbe1 +Subproject commit 70f475e34dd5f580dc8d5184d6fa8e5c96c5f601 From f29d633563276b4bc3458d6a215d41c76f6855b4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 8 Mar 2016 23:32:59 +0900 Subject: [PATCH 412/688] Fix cpplint warnings --- atom/browser/atom_permission_manager.cc | 2 ++ atom/browser/atom_permission_manager.h | 1 + 2 files changed, 3 insertions(+) diff --git a/atom/browser/atom_permission_manager.cc b/atom/browser/atom_permission_manager.cc index bd005869aa2..720d1f93b32 100644 --- a/atom/browser/atom_permission_manager.cc +++ b/atom/browser/atom_permission_manager.cc @@ -4,6 +4,8 @@ #include "atom/browser/atom_permission_manager.h" +#include + #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/render_frame_host.h" diff --git a/atom/browser/atom_permission_manager.h b/atom/browser/atom_permission_manager.h index 58c23723bfb..e16893fd8bb 100644 --- a/atom/browser/atom_permission_manager.h +++ b/atom/browser/atom_permission_manager.h @@ -6,6 +6,7 @@ #define ATOM_BROWSER_ATOM_PERMISSION_MANAGER_H_ #include +#include #include "base/callback.h" #include "content/public/browser/permission_manager.h" From a31cbd24a1426aef466d760897c1fe31839eb47f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 8 Mar 2016 23:35:52 +0900 Subject: [PATCH 413/688] Final pieces of int16 and .Pass() --- atom/browser/net/atom_ssl_config_service.cc | 6 +++--- atom/browser/ui/views/submenu_button.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/browser/net/atom_ssl_config_service.cc b/atom/browser/net/atom_ssl_config_service.cc index 2b3143e93cb..79b10d0ca98 100644 --- a/atom/browser/net/atom_ssl_config_service.cc +++ b/atom/browser/net/atom_ssl_config_service.cc @@ -18,8 +18,8 @@ namespace atom { namespace { -uint16 GetSSLProtocolVersion(const std::string& version_string) { - uint16 version = 0; // Invalid +uint16_t GetSSLProtocolVersion(const std::string& version_string) { + uint16_t version = 0; // Invalid if (version_string == "tls1") version = net::SSL_PROTOCOL_VERSION_TLS1; else if (version_string == "tls1.1") @@ -35,7 +35,7 @@ std::vector ParseCipherSuites( cipher_suites.reserve(cipher_strings.size()); for (auto& cipher_string : cipher_strings) { - uint16 cipher_suite = 0; + uint16_t cipher_suite = 0; if (!net::ParseSSLCipherString(cipher_string, &cipher_suite)) { LOG(ERROR) << "Ignoring unrecognised cipher suite : " << cipher_string; diff --git a/atom/browser/ui/views/submenu_button.cc b/atom/browser/ui/views/submenu_button.cc index 7f413d519c2..72cab258cbe 100644 --- a/atom/browser/ui/views/submenu_button.cc +++ b/atom/browser/ui/views/submenu_button.cc @@ -37,7 +37,7 @@ SubmenuButton::SubmenuButton(views::ButtonListener* listener, underline_color_(SK_ColorBLACK) { #if defined(OS_LINUX) // Dont' use native style border. - SetBorder(CreateDefaultBorder().Pass()); + SetBorder(std::move(CreateDefaultBorder())); #endif if (GetUnderlinePosition(title, &accelerator_, &underline_start_, From dd4d3db47bea9b72e20c13f451972573de9e2634 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 9 Mar 2016 12:40:06 +0900 Subject: [PATCH 414/688] Fix node integration not working --- atom/browser/atom_browser_client.cc | 3 +-- atom/browser/net/atom_ssl_config_service.cc | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 876be2b1d00..2363e6442bf 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -49,7 +49,7 @@ namespace { // The default routing id of WebContents. // In Electron each RenderProcessHost only has one WebContents, so this ID is // same for every WebContents. -int kDefaultRoutingID = 2; +int kDefaultRoutingID = 1; // Next navigation should not restart renderer process. bool g_suppress_renderer_process_restart = false; @@ -201,7 +201,6 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( if (ContainsKey(pending_processes_, process_id)) process_id = pending_processes_[process_id]; - // Certain render process will be created with no associated render view, // for example: ServiceWorker. auto rvh = content::RenderViewHost::FromID(process_id, kDefaultRoutingID); diff --git a/atom/browser/net/atom_ssl_config_service.cc b/atom/browser/net/atom_ssl_config_service.cc index 79b10d0ca98..c306a8a3917 100644 --- a/atom/browser/net/atom_ssl_config_service.cc +++ b/atom/browser/net/atom_ssl_config_service.cc @@ -29,9 +29,9 @@ uint16_t GetSSLProtocolVersion(const std::string& version_string) { return version; } -std::vector ParseCipherSuites( +std::vector ParseCipherSuites( const std::vector& cipher_strings) { - std::vector cipher_suites; + std::vector cipher_suites; cipher_suites.reserve(cipher_strings.size()); for (auto& cipher_string : cipher_strings) { From 6de9c4332fdf85a1e7645b996be0c9534fcf0f4c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 9 Mar 2016 20:03:42 +0900 Subject: [PATCH 415/688] Fix passing Promise with remote Somehow using value.then.bind(value) would result in infinite loop, could be bug of Chromium. --- atom/browser/auto_updater.h | 1 + lib/browser/rpc-server.js | 2 +- lib/renderer/api/remote.js | 2 +- vendor/brightray | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/atom/browser/auto_updater.h b/atom/browser/auto_updater.h index 637545e877f..d13c6f0c330 100644 --- a/atom/browser/auto_updater.h +++ b/atom/browser/auto_updater.h @@ -8,6 +8,7 @@ #include #include "base/macros.h" +#include "build/build_config.h" namespace base { class Time; diff --git a/lib/browser/rpc-server.js b/lib/browser/rpc-server.js index 5399c192e82..e26843667bd 100644 --- a/lib/browser/rpc-server.js +++ b/lib/browser/rpc-server.js @@ -106,7 +106,7 @@ var valueToMeta = function(sender, value, optimizeSimpleObject) { } else if (meta.type === 'buffer') { meta.value = Array.prototype.slice.call(value, 0); } else if (meta.type === 'promise') { - meta.then = valueToMeta(sender, value.then.bind(value)); + meta.then = valueToMeta(sender, function(v) { value.then(v); }); } else if (meta.type === 'error') { meta.members = plainObjectToMeta(value); diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index 42435d8304c..d3d490d053c 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -48,7 +48,7 @@ var wrapArgs = function(args, visited) { } else if ((value != null ? value.constructor.name : void 0) === 'Promise') { return { type: 'promise', - then: valueToMeta(value.then.bind(value)) + then: valueToMeta(function(v) { value.then(v); }) }; } else if ((value != null) && typeof value === 'object' && v8Util.getHiddenValue(value, 'atomId')) { return { diff --git a/vendor/brightray b/vendor/brightray index 70f475e34dd..7f9e25b50b3 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 70f475e34dd5f580dc8d5184d6fa8e5c96c5f601 +Subproject commit 7f9e25b50b373aea5e7d0a50c33aea22c85ee876 From bfc6d77bb3d35ed1a89ac7831bd39de9a6d4dad5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 9 Mar 2016 21:34:51 +0900 Subject: [PATCH 416/688] Pending renderer process no longer has render view attached --- atom/browser/atom_browser_client.cc | 7 +------ atom/browser/web_contents_preferences.cc | 25 +++++++++++++++++++++++- atom/browser/web_contents_preferences.h | 8 ++++++++ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 2363e6442bf..ca12723bb37 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -203,13 +203,8 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( // Certain render process will be created with no associated render view, // for example: ServiceWorker. - auto rvh = content::RenderViewHost::FromID(process_id, kDefaultRoutingID); - if (!rvh) - return; - - // Get the WebContents of the render process. content::WebContents* web_contents = - content::WebContents::FromRenderViewHost(rvh); + WebContentsPreferences::GetWebContentsFromProcessID(process_id); if (!web_contents) return; diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index fb67d2516eb..3939c59b8cd 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -4,12 +4,15 @@ #include "atom/browser/web_contents_preferences.h" +#include #include +#include #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/options_switches.h" #include "base/command_line.h" #include "base/strings/string_number_conversions.h" +#include "content/public/browser/render_process_host.h" #include "content/public/common/content_switches.h" #include "content/public/common/web_preferences.h" #include "native_mate/dictionary.h" @@ -23,9 +26,13 @@ DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::WebContentsPreferences); namespace atom { +// static +std::vector WebContentsPreferences::instances_; + WebContentsPreferences::WebContentsPreferences( content::WebContents* web_contents, - const mate::Dictionary& web_preferences) { + const mate::Dictionary& web_preferences) + : web_contents_(web_contents) { v8::Isolate* isolate = web_preferences.isolate(); mate::Dictionary copied(isolate, web_preferences.GetHandle()->Clone()); // Following fields should not be stored. @@ -35,15 +42,31 @@ WebContentsPreferences::WebContentsPreferences( mate::ConvertFromV8(isolate, copied.GetHandle(), &web_preferences_); web_contents->SetUserData(UserDataKey(), this); + + instances_.push_back(this); } WebContentsPreferences::~WebContentsPreferences() { + instances_.erase( + std::remove(instances_.begin(), instances_.end(), this), + instances_.end()); } void WebContentsPreferences::Merge(const base::DictionaryValue& extend) { web_preferences_.MergeDictionary(&extend); } +// static +content::WebContents* WebContentsPreferences::GetWebContentsFromProcessID( + int process_id) { + for (WebContentsPreferences* preferences : instances_) { + content::WebContents* web_contents = preferences->web_contents_; + if (web_contents->GetRenderProcessHost()->GetID() == process_id) + return web_contents; + } + return nullptr; +} + // static void WebContentsPreferences::AppendExtraCommandLineSwitches( content::WebContents* web_contents, base::CommandLine* command_line) { diff --git a/atom/browser/web_contents_preferences.h b/atom/browser/web_contents_preferences.h index 8b04f9ee24e..dd98a9658ac 100644 --- a/atom/browser/web_contents_preferences.h +++ b/atom/browser/web_contents_preferences.h @@ -5,6 +5,8 @@ #ifndef ATOM_BROWSER_WEB_CONTENTS_PREFERENCES_H_ #define ATOM_BROWSER_WEB_CONTENTS_PREFERENCES_H_ +#include + #include "base/values.h" #include "content/public/browser/web_contents_user_data.h" @@ -26,6 +28,9 @@ namespace atom { class WebContentsPreferences : public content::WebContentsUserData { public: + // Get WebContents according to process ID. + static content::WebContents* GetWebContentsFromProcessID(int process_id); + // Append command paramters according to |web_contents|'s preferences. static void AppendExtraCommandLineSwitches( content::WebContents* web_contents, base::CommandLine* command_line); @@ -47,6 +52,9 @@ class WebContentsPreferences private: friend class content::WebContentsUserData; + static std::vector instances_; + + content::WebContents* web_contents_; base::DictionaryValue web_preferences_; DISALLOW_COPY_AND_ASSIGN(WebContentsPreferences); From 044daee086e77f1cd6bc13814e202b2945948efc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 9 Mar 2016 22:19:47 +0900 Subject: [PATCH 417/688] Update printing code to latest --- .../printing/print_web_view_helper.cc | 53 +++++++++-------- .../renderer/printing/print_web_view_helper.h | 2 +- .../printing/print_web_view_helper_linux.cc | 49 ++------------- .../printing/print_web_view_helper_mac.mm | 3 +- .../printing/print_web_view_helper_pdf_win.cc | 59 ++++++------------- 5 files changed, 55 insertions(+), 111 deletions(-) diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper.cc index 924553b5cff..eb3599198d9 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper.cc @@ -386,7 +386,7 @@ class PrepareFrameAndViewForPrint : public blink::WebViewClient, blink::WebLocalFrame* frame, const blink::WebNode& node, bool ignore_css_margins); - virtual ~PrepareFrameAndViewForPrint(); + ~PrepareFrameAndViewForPrint() override; // Optional. Replaces |frame_| with selection if needed. Will call |on_ready| // when completed. @@ -810,13 +810,19 @@ bool PrintWebViewHelper::FinalizePrintReadyDocument() { DCHECK(!is_print_ready_metafile_sent_); print_preview_context_.FinalizePrintReadyDocument(); - // Get the size of the resulting metafile. PdfMetafileSkia* metafile = print_preview_context_.metafile(); - uint32_t buf_size = metafile->GetDataSize(); - DCHECK_GT(buf_size, 0u); PrintHostMsg_DidPreviewDocument_Params preview_params; - preview_params.data_size = buf_size; + + // Ask the browser to create the shared memory for us. + if (!CopyMetafileDataToSharedMem(*metafile, + &(preview_params.metafile_data_handle))) { + LOG(ERROR) << "CopyMetafileDataToSharedMem failed"; + print_preview_context_.set_error(PREVIEW_ERROR_METAFILE_COPY_FAILED); + return false; + } + + preview_params.data_size = metafile->GetDataSize(); preview_params.document_cookie = print_pages_params_->params.document_cookie; preview_params.expected_pages_count = print_preview_context_.total_page_count(); @@ -824,13 +830,6 @@ bool PrintWebViewHelper::FinalizePrintReadyDocument() { preview_params.preview_request_id = print_pages_params_->params.preview_request_id; - // Ask the browser to create the shared memory for us. - if (!CopyMetafileDataToSharedMem(metafile, - &(preview_params.metafile_data_handle))) { - LOG(ERROR) << "CopyMetafileDataToSharedMem failed"; - print_preview_context_.set_error(PREVIEW_ERROR_METAFILE_COPY_FAILED); - return false; - } is_print_ready_metafile_sent_ = true; Send(new PrintHostMsg_MetafileReadyForPrinting(routing_id(), preview_params)); @@ -1160,21 +1159,25 @@ bool PrintWebViewHelper::RenderPagesForPrint(blink::WebLocalFrame* frame, #if defined(OS_POSIX) bool PrintWebViewHelper::CopyMetafileDataToSharedMem( - PdfMetafileSkia* metafile, + const PdfMetafileSkia& metafile, base::SharedMemoryHandle* shared_mem_handle) { - uint32_t buf_size = metafile->GetDataSize(); - scoped_ptr shared_buf( - content::RenderThread::Get()->HostAllocateSharedMemoryBuffer( - buf_size).release()); + uint32_t buf_size = metafile.GetDataSize(); + if (buf_size == 0) + return false; - if (shared_buf) { - if (shared_buf->Map(buf_size)) { - metafile->GetData(shared_buf->memory(), buf_size); - return shared_buf->GiveToProcess(base::GetCurrentProcessHandle(), - shared_mem_handle); - } - } - return false; + scoped_ptr shared_buf( + content::RenderThread::Get()->HostAllocateSharedMemoryBuffer(buf_size)); + if (!shared_buf) + return false; + + if (!shared_buf->Map(buf_size)) + return false; + + if (!metafile.GetData(shared_buf->memory(), buf_size)) + return false; + + return shared_buf->GiveToProcess(base::GetCurrentProcessHandle(), + shared_mem_handle); } #endif // defined(OS_POSIX) diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper.h b/chromium_src/chrome/renderer/printing/print_web_view_helper.h index bfe9cb612d1..05f145b5bb8 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper.h +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper.h @@ -218,7 +218,7 @@ class PrintWebViewHelper // Helper methods ----------------------------------------------------------- - bool CopyMetafileDataToSharedMem(PdfMetafileSkia* metafile, + bool CopyMetafileDataToSharedMem(const PdfMetafileSkia& metafile, base::SharedMemoryHandle* shared_mem_handle); // Helper method to get page layout in points and fit to page if needed. diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc index 62267f8f45f..d37aec628ba 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_linux.cc @@ -11,7 +11,6 @@ #include "printing/metafile_skia_wrapper.h" #include "printing/page_size_margins.h" #include "printing/pdf_metafile_skia.h" -#include "skia/ext/platform_device.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) @@ -91,49 +90,15 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame, metafile.FinishDocument(); - // Get the size of the resulting metafile. - uint32_t buf_size = metafile.GetDataSize(); - DCHECK_GT(buf_size, 0u); - -#if defined(OS_CHROMEOS) || defined(OS_ANDROID) - int sequence_number = -1; - base::FileDescriptor fd; - - // Ask the browser to open a file for us. - Send(new PrintHostMsg_AllocateTempFileForPrinting(routing_id(), - &fd, - &sequence_number)); - if (!metafile.SaveToFD(fd)) - return false; - - // Tell the browser we've finished writing the file. - Send(new PrintHostMsg_TempFileForPrintingWritten(routing_id(), - sequence_number)); - return true; -#else PrintHostMsg_DidPrintPage_Params printed_page_params; - printed_page_params.data_size = 0; - printed_page_params.document_cookie = params.params.document_cookie; - - { - scoped_ptr shared_mem( - content::RenderThread::Get()->HostAllocateSharedMemoryBuffer( - buf_size).release()); - if (!shared_mem.get()) { - NOTREACHED() << "AllocateSharedMemoryBuffer failed"; - return false; - } - - if (!shared_mem->Map(buf_size)) { - NOTREACHED() << "Map failed"; - return false; - } - metafile.GetData(shared_mem->memory(), buf_size); - printed_page_params.data_size = buf_size; - shared_mem->GiveToProcess(base::GetCurrentProcessHandle(), - &(printed_page_params.metafile_data_handle)); + if (!CopyMetafileDataToSharedMem( + metafile, &printed_page_params.metafile_data_handle)) { + return false; } + printed_page_params.data_size = metafile.GetDataSize(); + printed_page_params.document_cookie = params.params.document_cookie; + for (size_t i = 0; i < printed_pages.size(); ++i) { printed_page_params.page_number = printed_pages[i]; Send(new PrintHostMsg_DidPrintPage(routing_id(), printed_page_params)); @@ -141,7 +106,6 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame, printed_page_params.metafile_data_handle.fd = -1; } return true; -#endif // defined(OS_CHROMEOS) } void PrintWebViewHelper::PrintPageInternal( @@ -165,7 +129,6 @@ void PrintWebViewHelper::PrintPageInternal( return; MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile); - skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_); RenderPageContent(frame, params.page_number, canvas_area, content_area, scale_factor, canvas); diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm b/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm index 3b1a0593d06..b10ba616a1f 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_mac.mm @@ -42,8 +42,9 @@ void PrintWebViewHelper::PrintPageInternal( page_params.content_area = content_area_in_dpi; // Ask the browser to create the shared memory for us. - if (!CopyMetafileDataToSharedMem(&metafile, + if (!CopyMetafileDataToSharedMem(metafile, &(page_params.metafile_data_handle))) { + // TODO(thestig): Fail and return false instead. page_params.data_size = 0; } diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc index 243e9ab7522..a5896934b69 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc @@ -95,40 +95,16 @@ bool PrintWebViewHelper::PrintPagesNative(blink::WebFrame* frame, metafile.FinishDocument(); - // Get the size of the resulting metafile. - uint32_t buf_size = metafile.GetDataSize(); - DCHECK_GT(buf_size, 0u); - PrintHostMsg_DidPrintPage_Params printed_page_params; - printed_page_params.data_size = 0; + if (!CopyMetafileDataToSharedMem( + metafile, &printed_page_params.metafile_data_handle)) { + return false; + } + + printed_page_params.content_area = params.params.printable_area; + printed_page_params.data_size = metafile.GetDataSize(); printed_page_params.document_cookie = params.params.document_cookie; printed_page_params.page_size = params.params.page_size; - printed_page_params.content_area = params.params.printable_area; - - { - base::SharedMemory shared_buf; - // Allocate a shared memory buffer to hold the generated metafile data. - if (!shared_buf.CreateAndMapAnonymous(buf_size)) { - NOTREACHED() << "Buffer allocation failed"; - return false; - } - - // Copy the bits into shared memory. - if (!metafile.GetData(shared_buf.memory(), buf_size)) { - NOTREACHED() << "GetData() failed"; - shared_buf.Unmap(); - return false; - } - shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), - &printed_page_params.metafile_data_handle); - shared_buf.Unmap(); - - printed_page_params.data_size = buf_size; - Send(new PrintHostMsg_DuplicateSection( - routing_id(), - printed_page_params.metafile_data_handle, - &printed_page_params.metafile_data_handle)); - } for (size_t i = 0; i < printed_pages.size(); ++i) { printed_page_params.page_number = printed_pages[i]; @@ -216,24 +192,25 @@ void PrintWebViewHelper::PrintPageInternal( } bool PrintWebViewHelper::CopyMetafileDataToSharedMem( - PdfMetafileSkia* metafile, + const PdfMetafileSkia& metafile, base::SharedMemoryHandle* shared_mem_handle) { - uint32_t buf_size = metafile->GetDataSize(); + uint32_t buf_size = metafile.GetDataSize(); + if (buf_size == 0) + return false; + base::SharedMemory shared_buf; // Allocate a shared memory buffer to hold the generated metafile data. - if (!shared_buf.CreateAndMapAnonymous(buf_size)) { - NOTREACHED() << "Buffer allocation failed"; + if (!shared_buf.CreateAndMapAnonymous(buf_size)) return false; - } // Copy the bits into shared memory. - if (!metafile->GetData(shared_buf.memory(), buf_size)) { - NOTREACHED() << "GetData() failed"; - shared_buf.Unmap(); + if (!metafile.GetData(shared_buf.memory(), buf_size)) + return false; + + if (!shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), + shared_mem_handle)) { return false; } - shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle); - shared_buf.Unmap(); Send(new PrintHostMsg_DuplicateSection(routing_id(), *shared_mem_handle, shared_mem_handle)); From d36b8bca86fa34d1589700cc2af02c99d012cc51 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 9 Mar 2016 22:19:56 +0900 Subject: [PATCH 418/688] Fix compilation errors on Linux --- atom/common/atom_command_line.h | 1 + atom/common/crash_reporter/linux/crash_dump_handler.h | 4 ++++ chromium_src/chrome/browser/ui/views/color_chooser_aura.h | 1 + 3 files changed, 6 insertions(+) diff --git a/atom/common/atom_command_line.h b/atom/common/atom_command_line.h index 56ecb8fbd49..b5915533a41 100644 --- a/atom/common/atom_command_line.h +++ b/atom/common/atom_command_line.h @@ -9,6 +9,7 @@ #include #include "base/macros.h" +#include "build/build_config.h" namespace atom { diff --git a/atom/common/crash_reporter/linux/crash_dump_handler.h b/atom/common/crash_reporter/linux/crash_dump_handler.h index 00161f02ee5..f10c5212254 100644 --- a/atom/common/crash_reporter/linux/crash_dump_handler.h +++ b/atom/common/crash_reporter/linux/crash_dump_handler.h @@ -6,6 +6,10 @@ #ifndef ATOM_COMMON_CRASH_REPORTER_LINUX_CRASH_DUMP_HANDLER_H_ #define ATOM_COMMON_CRASH_REPORTER_LINUX_CRASH_DUMP_HANDLER_H_ +#include +#include +#include + #include "base/macros.h" #include "vendor/breakpad/src/common/simple_string_dictionary.h" diff --git a/chromium_src/chrome/browser/ui/views/color_chooser_aura.h b/chromium_src/chrome/browser/ui/views/color_chooser_aura.h index ba6709889e6..355f540b19d 100644 --- a/chromium_src/chrome/browser/ui/views/color_chooser_aura.h +++ b/chromium_src/chrome/browser/ui/views/color_chooser_aura.h @@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_VIEWS_COLOR_CHOOSER_AURA_H_ #define CHROME_BROWSER_UI_VIEWS_COLOR_CHOOSER_AURA_H_ +#include "base/macros.h" #include "content/public/browser/color_chooser.h" #include "ui/views/color_chooser/color_chooser_listener.h" From a737baafbfb38ba9109e73c3b403be19e9193f8b Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 9 Mar 2016 11:01:53 -0800 Subject: [PATCH 419/688] We don't need Metro --- chromium_src/chrome/browser/process_singleton_win.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/chromium_src/chrome/browser/process_singleton_win.cc b/chromium_src/chrome/browser/process_singleton_win.cc index 14e53bec5fa..fd4c22e7405 100644 --- a/chromium_src/chrome/browser/process_singleton_win.cc +++ b/chromium_src/chrome/browser/process_singleton_win.cc @@ -16,7 +16,6 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" -#include "base/win/metro.h" #include "base/win/registry.h" #include "base/win/scoped_handle.h" #include "base/win/windows_version.h" From 60a2495b300c7bfd051ba15291322a48134645fd Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 9 Mar 2016 11:05:17 -0800 Subject: [PATCH 420/688] Update Get() => get(), Set() => reset() --- atom/browser/ui/win/notify_icon.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 1ac29f1360c..7c8e1a189a6 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -80,7 +80,7 @@ void NotifyIcon::ResetIcon() { InitIconData(&icon_data); icon_data.uFlags |= NIF_MESSAGE; icon_data.uCallbackMessage = message_id_; - icon_data.hIcon = icon_.Get(); + icon_data.hIcon = icon_.get(); // If we have an image, then set the NIF_ICON flag, which tells // Shell_NotifyIcon() to set the image for the status icon it creates. if (icon_data.hIcon) @@ -96,8 +96,8 @@ void NotifyIcon::SetImage(const gfx::Image& image) { NOTIFYICONDATA icon_data; InitIconData(&icon_data); icon_data.uFlags |= NIF_ICON; - icon_.Set(IconUtil::CreateHICONFromSkBitmap(image.AsBitmap())); - icon_data.hIcon = icon_.Get(); + icon_.reset(IconUtil::CreateHICONFromSkBitmap(image.AsBitmap())); + icon_data.hIcon = icon_.get(); BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); if (!result) LOG(WARNING) << "Error setting status tray icon image"; @@ -132,8 +132,8 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon, base::win::Version win_version = base::win::GetVersion(); if (!icon.IsEmpty() && win_version != base::win::VERSION_PRE_XP) { - balloon_icon_.Set(IconUtil::CreateHICONFromSkBitmap(icon.AsBitmap())); - icon_data.hBalloonIcon = balloon_icon_.Get(); + balloon_icon_.reset(IconUtil::CreateHICONFromSkBitmap(icon.AsBitmap())); + icon_data.hBalloonIcon = balloon_icon_.get(); icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON; } From 12e9b7ab884ff4e423c0ba9fd057b175daf18915 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 9 Mar 2016 11:08:19 -0800 Subject: [PATCH 421/688] Use assignment operator since both sides are scoped now --- atom/browser/ui/win/notify_icon.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/ui/win/notify_icon.cc b/atom/browser/ui/win/notify_icon.cc index 7c8e1a189a6..11247301380 100644 --- a/atom/browser/ui/win/notify_icon.cc +++ b/atom/browser/ui/win/notify_icon.cc @@ -96,7 +96,7 @@ void NotifyIcon::SetImage(const gfx::Image& image) { NOTIFYICONDATA icon_data; InitIconData(&icon_data); icon_data.uFlags |= NIF_ICON; - icon_.reset(IconUtil::CreateHICONFromSkBitmap(image.AsBitmap())); + icon_ = IconUtil::CreateHICONFromSkBitmap(image.AsBitmap()); icon_data.hIcon = icon_.get(); BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); if (!result) @@ -132,7 +132,7 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon, base::win::Version win_version = base::win::GetVersion(); if (!icon.IsEmpty() && win_version != base::win::VERSION_PRE_XP) { - balloon_icon_.reset(IconUtil::CreateHICONFromSkBitmap(icon.AsBitmap())); + balloon_icon_ = IconUtil::CreateHICONFromSkBitmap(icon.AsBitmap()); icon_data.hBalloonIcon = balloon_icon_.get(); icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON; } From e835111195d50e5bd861a01d954127c1388bd839 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 9 Mar 2016 11:16:12 -0800 Subject: [PATCH 422/688] More type fixups --- chromium_src/chrome/browser/speech/tts_win.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chromium_src/chrome/browser/speech/tts_win.cc b/chromium_src/chrome/browser/speech/tts_win.cc index ac258205889..bc9411a8c15 100644 --- a/chromium_src/chrome/browser/speech/tts_win.cc +++ b/chromium_src/chrome/browser/speech/tts_win.cc @@ -87,7 +87,7 @@ bool TtsPlatformImplWin::Speak( // 0.1 -> -10 // 1.0 -> 0 // 10.0 -> 10 - speech_synthesizer_->SetRate(static_cast(10 * log10(params.rate))); + speech_synthesizer_->SetRate(static_cast(10 * log10(params.rate))); } if (params.pitch >= 0.0) { @@ -102,7 +102,7 @@ bool TtsPlatformImplWin::Speak( if (params.volume >= 0.0) { // The TTS api allows a range of 0 to 100 for speech volume. - speech_synthesizer_->SetVolume(static_cast(params.volume * 100)); + speech_synthesizer_->SetVolume(static_cast(params.volume * 100)); } // TODO(dmazzoni): convert SSML to SAPI xml. http://crbug.com/88072 From 7b60ef6261b8e2d5712257633aae9ffaf1233cf6 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 9 Mar 2016 11:16:31 -0800 Subject: [PATCH 423/688] SetIsDraftMode no longer a thing, see https://groups.google.com/a/chromium.org/forum/m/#!topic/chromium-checkins/6qohfKmEYyg --- .../chrome/renderer/printing/print_web_view_helper_pdf_win.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc index a5896934b69..ce1e962505f 100644 --- a/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc +++ b/chromium_src/chrome/renderer/printing/print_web_view_helper_pdf_win.cc @@ -164,7 +164,6 @@ void PrintWebViewHelper::PrintPageInternal( return; MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile); - skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_); #if 0 if (params.params.display_header_footer) { From 1c01e4955f1a854f339be2b67e71bd53654e8ef9 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 9 Mar 2016 11:22:54 -0800 Subject: [PATCH 424/688] Modifiers moved under UI --- atom/browser/ui/win/notify_icon_host.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/atom/browser/ui/win/notify_icon_host.cc b/atom/browser/ui/win/notify_icon_host.cc index a0d4287ff61..1f0b35b09fd 100644 --- a/atom/browser/ui/win/notify_icon_host.cc +++ b/atom/browser/ui/win/notify_icon_host.cc @@ -15,6 +15,7 @@ #include "base/win/win_util.h" #include "base/win/wrapped_window_proc.h" #include "ui/events/event_constants.h" +#include "ui/events/win/system_event_state_lookup.h" #include "ui/gfx/win/hwnd_util.h" namespace atom { @@ -35,11 +36,11 @@ bool IsWinPressed() { int GetKeyboardModifers() { int modifiers = ui::EF_NONE; - if (base::win::IsShiftPressed()) + if (ui::win::IsShiftPressed()) modifiers |= ui::EF_SHIFT_DOWN; - if (base::win::IsCtrlPressed()) + if (ui::win::IsCtrlPressed()) modifiers |= ui::EF_CONTROL_DOWN; - if (base::win::IsAltPressed()) + if (ui::win::IsAltPressed()) modifiers |= ui::EF_ALT_DOWN; if (IsWinPressed()) modifiers |= ui::EF_COMMAND_DOWN; From f4ec369873d9d22313361964c828bda41e3b32ac Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 9 Mar 2016 11:27:16 -0800 Subject: [PATCH 425/688] More boring fixups --- atom/browser/ui/message_box_win.cc | 4 ++-- atom/browser/ui/win/taskbar_host.cc | 4 ++-- atom/common/api/atom_api_native_image.cc | 4 ++-- atom/common/crash_reporter/win/crash_service.cc | 2 +- chromium_src/chrome/common/chrome_paths_win.cc | 1 - 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/atom/browser/ui/message_box_win.cc b/atom/browser/ui/message_box_win.cc index 2847ae21a16..5f49151c30f 100644 --- a/atom/browser/ui/message_box_win.cc +++ b/atom/browser/ui/message_box_win.cc @@ -102,9 +102,9 @@ int ShowMessageBoxUTF16(HWND parent, base::win::ScopedHICON hicon; if (!icon.isNull()) { - hicon.Set(IconUtil::CreateHICONFromSkBitmap(*icon.bitmap())); + hicon = IconUtil::CreateHICONFromSkBitmap(*icon.bitmap()); config.dwFlags |= TDF_USE_HICON_MAIN; - config.hMainIcon = hicon.Get(); + config.hMainIcon = hicon.get(); } else { // Show icon according to dialog's type. switch (type) { diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index 0d250829110..abfda15edf7 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -91,7 +91,7 @@ bool TaskbarHost::SetThumbarButtons( if (!button.icon.IsEmpty()) { thumb_button.dwMask |= THB_ICON; icons[i] = IconUtil::CreateHICONFromSkBitmap(button.icon.AsBitmap()); - thumb_button.hIcon = icons[i].Get(); + thumb_button.hIcon = icons[i].get(); } // Set tooltip. @@ -139,7 +139,7 @@ bool TaskbarHost::SetOverlayIcon( base::win::ScopedHICON icon( IconUtil::CreateHICONFromSkBitmap(overlay.AsBitmap())); return SUCCEEDED( - taskbar_->SetOverlayIcon(window, icon, base::UTF8ToUTF16(text).c_str())); + taskbar_->SetOverlayIcon(window, icon.get(), base::UTF8ToUTF16(text).c_str())); } bool TaskbarHost::HandleThumbarButtonEvent(int button_id) { diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 3d000b6d5d9..69ead046458 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -158,11 +158,11 @@ bool ReadImageSkiaFromICO(gfx::ImageSkia* image, const base::FilePath& path) { base::win::ScopedHICON icon(static_cast( LoadImage(NULL, image_path.value().c_str(), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE))); - if (!icon) + if (!icon.get()) return false; // Convert the icon from the Windows specific HICON to gfx::ImageSkia. - scoped_ptr bitmap(IconUtil::CreateSkBitmapFromHICON(icon)); + scoped_ptr bitmap(IconUtil:: CreateSkBitmapFromHICON(icon.get())); image->AddRepresentation(gfx::ImageSkiaRep(*bitmap, 1.0f)); return true; } diff --git a/atom/common/crash_reporter/win/crash_service.cc b/atom/common/crash_reporter/win/crash_service.cc index b8032f696fc..58c7c38632e 100644 --- a/atom/common/crash_reporter/win/crash_service.cc +++ b/atom/common/crash_reporter/win/crash_service.cc @@ -86,7 +86,7 @@ bool WriteReportIDToFile(const std::wstring& dump_path, if (!file.is_open()) return false; - int64 seconds_since_epoch = + int64_t seconds_since_epoch = (base::Time::Now() - base::Time::UnixEpoch()).InSeconds(); std::wstring line = base::Int64ToString16(seconds_since_epoch); line += L','; diff --git a/chromium_src/chrome/common/chrome_paths_win.cc b/chromium_src/chrome/common/chrome_paths_win.cc index 37f4ec2b05b..89c2ae48eaa 100644 --- a/chromium_src/chrome/common/chrome_paths_win.cc +++ b/chromium_src/chrome/common/chrome_paths_win.cc @@ -12,7 +12,6 @@ #include "base/files/file_path.h" #include "base/path_service.h" -#include "base/win/metro.h" #include "base/win/scoped_co_mem.h" #include "chrome/common/chrome_constants.h" From e3af5de7d74d7b107809705360f1107e16510bff Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 9 Mar 2016 13:59:28 -0800 Subject: [PATCH 426/688] Update pdf_to_emf_converter --- .../browser/printing/pdf_to_emf_converter.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc index 2231ed8b0dc..5d42264144a 100644 --- a/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc +++ b/chromium_src/chrome/browser/printing/pdf_to_emf_converter.cc @@ -109,21 +109,21 @@ class PdfToEmfUtilityProcessHostClient private: class GetPageCallbackData { - MOVE_ONLY_TYPE_FOR_CPP_03(GetPageCallbackData, RValue); + MOVE_ONLY_TYPE_FOR_CPP_03(GetPageCallbackData); public: GetPageCallbackData(int page_number, PdfToEmfConverter::GetPageCallback callback) : page_number_(page_number), callback_(callback) {} - // Move constructor for STL. - GetPageCallbackData(RValue other) { this->operator=(other); } + GetPageCallbackData(GetPageCallbackData&& other) { + *this = std::move(other); + } - // Move assignment for STL. - GetPageCallbackData& operator=(RValue rhs) { - page_number_ = rhs.object->page_number_; - callback_ = rhs.object->callback_; - emf_ = rhs.object->emf_.Pass(); + GetPageCallbackData& operator=(GetPageCallbackData&& rhs) { + page_number_ = rhs.page_number_; + callback_ = rhs.callback_; + emf_ = std::move(rhs.emf_); return *this; } From 89f17e0bafcd371dab2513559167fc1b370c5ea8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 10 Mar 2016 14:39:40 +0900 Subject: [PATCH 427/688] Create complete URLRequestContextGetter for URLRequestFetchJob The trivial one is causing crashes. --- atom/browser/net/js_asker.cc | 15 ++++++-- atom/browser/net/js_asker.h | 6 +++ atom/browser/net/url_request_fetch_job.cc | 46 ++++++++++++----------- atom/browser/net/url_request_fetch_job.h | 9 ++--- vendor/brightray | 2 +- 5 files changed, 47 insertions(+), 31 deletions(-) diff --git a/atom/browser/net/js_asker.cc b/atom/browser/net/js_asker.cc index 8f0d1d2b957..b11a69c9c13 100644 --- a/atom/browser/net/js_asker.cc +++ b/atom/browser/net/js_asker.cc @@ -16,7 +16,9 @@ namespace internal { namespace { // The callback which is passed to |handler|. -void HandlerCallback(const ResponseCallback& callback, mate::Arguments* args) { +void HandlerCallback(const BeforeStartCallback& before_start, + const ResponseCallback& callback, + mate::Arguments* args) { // If there is no argument passed then we failed. v8::Local value; if (!args->GetNext(&value)) { @@ -26,6 +28,9 @@ void HandlerCallback(const ResponseCallback& callback, mate::Arguments* args) { return; } + // Give the job a chance to parse V8 value. + before_start.Run(args->isolate(), value); + // Pass whatever user passed to the actaul request job. V8ValueConverter converter; v8::Local context = args->isolate()->GetCurrentContext(); @@ -40,15 +45,17 @@ void HandlerCallback(const ResponseCallback& callback, mate::Arguments* args) { void AskForOptions(v8::Isolate* isolate, const JavaScriptHandler& handler, net::URLRequest* request, + const BeforeStartCallback& before_start, const ResponseCallback& callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); v8::Locker locker(isolate); v8::HandleScope handle_scope(isolate); v8::Local context = isolate->GetCurrentContext(); v8::Context::Scope context_scope(context); - handler.Run(request, - mate::ConvertToV8(isolate, - base::Bind(&HandlerCallback, callback))); + handler.Run( + request, + mate::ConvertToV8(isolate, + base::Bind(&HandlerCallback, before_start, callback))); } bool IsErrorOptions(base::Value* value, int* error) { diff --git a/atom/browser/net/js_asker.h b/atom/browser/net/js_asker.h index 061a9cb859e..8a70794fa94 100644 --- a/atom/browser/net/js_asker.h +++ b/atom/browser/net/js_asker.h @@ -23,6 +23,8 @@ using JavaScriptHandler = namespace internal { +using BeforeStartCallback = + base::Callback)>; using ResponseCallback = base::Callback options)>; @@ -30,6 +32,7 @@ using ResponseCallback = void AskForOptions(v8::Isolate* isolate, const JavaScriptHandler& handler, net::URLRequest* request, + const BeforeStartCallback& before_start, const ResponseCallback& callback); // Test whether the |options| means an error. @@ -54,6 +57,7 @@ class JsAsker : public RequestJob { } // Subclass should do initailze work here. + virtual void BeforeStartInUI(v8::Isolate*, v8::Local) {} virtual void StartAsync(scoped_ptr options) = 0; net::URLRequestContextGetter* request_context_getter() const { @@ -69,6 +73,8 @@ class JsAsker : public RequestJob { isolate_, handler_, RequestJob::request(), + base::Bind(&JsAsker::BeforeStartInUI, + weak_factory_.GetWeakPtr()), base::Bind(&JsAsker::OnResponse, weak_factory_.GetWeakPtr()))); } diff --git a/atom/browser/net/url_request_fetch_job.cc b/atom/browser/net/url_request_fetch_job.cc index b176aef378a..d58ea3fe9fb 100644 --- a/atom/browser/net/url_request_fetch_job.cc +++ b/atom/browser/net/url_request_fetch_job.cc @@ -8,15 +8,14 @@ #include #include "base/strings/string_util.h" -#include "base/thread_task_runner_handle.h" +#include "native_mate/dictionary.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher_response_writer.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_builder.h" -#include "net/url_request/url_request_status.h" + +using content::BrowserThread; namespace atom { @@ -81,6 +80,25 @@ URLRequestFetchJob::URLRequestFetchJob( pending_buffer_size_(0) { } +void URLRequestFetchJob::BeforeStartInUI( + v8::Isolate* isolate, v8::Local value) { + mate::Dictionary options; + if (!mate::ConvertFromV8(isolate, value, &options)) + return; + + // When |session| is set to |null| we use a new request context for fetch job. + // TODO(zcbenz): Handle the case when it is not null. + v8::Local session; + if (options.Get("session", &session) && session->IsNull()) { + // We have to create the URLRequestContextGetter on UI thread. + url_request_context_getter_ = new brightray::URLRequestContextGetter( + this, nullptr, nullptr, base::FilePath(), true, + BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO), + BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE), + nullptr, content::URLRequestInterceptorScopedVector()); + } +} + void URLRequestFetchJob::StartAsync(scoped_ptr options) { if (!options->IsType(base::Value::TYPE_DICTIONARY)) { NotifyStartError(net::URLRequestStatus( @@ -89,14 +107,12 @@ void URLRequestFetchJob::StartAsync(scoped_ptr options) { } std::string url, method, referrer; - base::Value* session = nullptr; base::DictionaryValue* upload_data = nullptr; base::DictionaryValue* dict = static_cast(options.get()); dict->GetString("url", &url); dict->GetString("method", &method); dict->GetString("referrer", &referrer); - dict->Get("session", &session); dict->GetDictionary("uploadData", &upload_data); // Check if URL is valid. @@ -117,9 +133,9 @@ void URLRequestFetchJob::StartAsync(scoped_ptr options) { fetcher_ = net::URLFetcher::Create(formated_url, request_type, this); fetcher_->SaveResponseWithWriter(make_scoped_ptr(new ResponsePiper(this))); - // When |session| is set to |null| we use a new request context for fetch job. - if (session && session->IsType(base::Value::TYPE_NULL)) - fetcher_->SetRequestContext(CreateRequestContext()); + // A request context getter is passed by the user. + if (url_request_context_getter_) + fetcher_->SetRequestContext(url_request_context_getter_.get()); else fetcher_->SetRequestContext(request_context_getter()); @@ -144,18 +160,6 @@ void URLRequestFetchJob::StartAsync(scoped_ptr options) { fetcher_->Start(); } -net::URLRequestContextGetter* URLRequestFetchJob::CreateRequestContext() { - if (!url_request_context_getter_.get()) { - auto task_runner = base::ThreadTaskRunnerHandle::Get(); - net::URLRequestContextBuilder builder; - builder.set_proxy_service(net::ProxyService::CreateDirect()); - request_context_ = builder.Build(); - url_request_context_getter_ = new net::TrivialURLRequestContextGetter( - request_context_.get(), task_runner); - } - return url_request_context_getter_.get(); -} - void URLRequestFetchJob::HeadersCompleted() { response_info_.reset(new net::HttpResponseInfo); response_info_->headers = fetcher_->GetResponseHeaders(); diff --git a/atom/browser/net/url_request_fetch_job.h b/atom/browser/net/url_request_fetch_job.h index d9a247c5db8..69067fdc7fd 100644 --- a/atom/browser/net/url_request_fetch_job.h +++ b/atom/browser/net/url_request_fetch_job.h @@ -8,6 +8,7 @@ #include #include "atom/browser/net/js_asker.h" +#include "browser/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_request_job.h" @@ -17,7 +18,8 @@ namespace atom { class AtomBrowserContext; class URLRequestFetchJob : public JsAsker, - public net::URLFetcherDelegate { + public net::URLFetcherDelegate, + public brightray::URLRequestContextGetter::Delegate { public: URLRequestFetchJob(net::URLRequest*, net::NetworkDelegate*); @@ -27,6 +29,7 @@ class URLRequestFetchJob : public JsAsker, protected: // JsAsker: + void BeforeStartInUI(v8::Isolate*, v8::Local) override; void StartAsync(scoped_ptr options) override; // net::URLRequestJob: @@ -40,10 +43,6 @@ class URLRequestFetchJob : public JsAsker, void OnURLFetchComplete(const net::URLFetcher* source) override; private: - // Create a independent request context. - net::URLRequestContextGetter* CreateRequestContext(); - - scoped_ptr request_context_; scoped_refptr url_request_context_getter_; scoped_ptr fetcher_; scoped_refptr pending_buffer_; diff --git a/vendor/brightray b/vendor/brightray index 7f9e25b50b3..73d5b67617e 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 7f9e25b50b373aea5e7d0a50c33aea22c85ee876 +Subproject commit 73d5b67617e22c7d5a305d86a05ea40972683b63 From 20466bad8f0434b0f978b2a4a90a6e7f761fbcda Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 10 Mar 2016 14:45:19 +0900 Subject: [PATCH 428/688] Fix cpplint warnings --- atom/browser/ui/win/taskbar_host.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index abfda15edf7..f7841cfa856 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -138,8 +138,8 @@ bool TaskbarHost::SetOverlayIcon( base::win::ScopedHICON icon( IconUtil::CreateHICONFromSkBitmap(overlay.AsBitmap())); - return SUCCEEDED( - taskbar_->SetOverlayIcon(window, icon.get(), base::UTF8ToUTF16(text).c_str())); + return SUCCEEDED(taskbar_->SetOverlayIcon( + window, icon.get(), base::UTF8ToUTF16(text).c_str())); } bool TaskbarHost::HandleThumbarButtonEvent(int button_id) { From cadd1969d9ecb6a2bf4125f80de7778cb33d64ae Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 10 Mar 2016 15:57:03 +0900 Subject: [PATCH 429/688] Fix compilation errors on Windows --- .../chrome/browser/ui/views/color_chooser_win.cc | 10 +++++++--- .../net/test/embedded_test_server/tcp_listen_socket.cc | 1 + common.gypi | 1 + script/lib/config.py | 2 +- vendor/brightray | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/chromium_src/chrome/browser/ui/views/color_chooser_win.cc b/chromium_src/chrome/browser/ui/views/color_chooser_win.cc index b62801399e8..7a4f7573333 100644 --- a/chromium_src/chrome/browser/ui/views/color_chooser_win.cc +++ b/chromium_src/chrome/browser/ui/views/color_chooser_win.cc @@ -9,8 +9,10 @@ #include "chrome/browser/ui/views/color_chooser_dialog.h" #include "content/public/browser/color_chooser.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" +#include "ui/aura/window.h" #include "ui/views/color_chooser/color_chooser_listener.h" class ColorChooserWin : public content::ColorChooser, @@ -55,9 +57,11 @@ ColorChooserWin* ColorChooserWin::Open(content::WebContents* web_contents, ColorChooserWin::ColorChooserWin(content::WebContents* web_contents, SkColor initial_color) : web_contents_(web_contents) { - gfx::NativeWindow owning_window = (gfx::NativeWindow)::GetAncestor( - (HWND)web_contents->GetRenderViewHost()->GetView()->GetNativeView(), - GA_ROOT); + gfx::NativeWindow owning_window = web_contents->GetRenderViewHost() + ->GetWidget() + ->GetView() + ->GetNativeView() + ->GetToplevelWindow(); color_chooser_dialog_ = new ColorChooserDialog(this, initial_color, owning_window); diff --git a/chromium_src/net/test/embedded_test_server/tcp_listen_socket.cc b/chromium_src/net/test/embedded_test_server/tcp_listen_socket.cc index fbdcc2bfc7e..1a72b2efe37 100644 --- a/chromium_src/net/test/embedded_test_server/tcp_listen_socket.cc +++ b/chromium_src/net/test/embedded_test_server/tcp_listen_socket.cc @@ -8,6 +8,7 @@ // winsock2.h must be included first in order to ensure it is included before // windows.h. #include +#include #elif defined(OS_POSIX) #include #include diff --git a/common.gypi b/common.gypi index d8c7ee30935..6eacdc93a02 100644 --- a/common.gypi +++ b/common.gypi @@ -43,6 +43,7 @@ 'target_conditions': [ ['_target_name in ["libuv", "http_parser", "openssl", "cares", "node", "zlib"]', { 'msvs_disabled_warnings': [ + 4003, # not enough actual parameters for macro 'V' 4013, # 'free' undefined; assuming extern returning int 4018, # signed/unsigned mismatch 4054, # diff --git a/script/lib/config.py b/script/lib/config.py index 10319a2df4e..e5fafa34720 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'a661ccb38f21859309cc97c1fc313f1360101462' +LIBCHROMIUMCONTENT_COMMIT = '497f11bcb91d9b0b5b5cbd004411b37b933c825e' PLATFORM = { 'cygwin': 'win32', diff --git a/vendor/brightray b/vendor/brightray index 73d5b67617e..4a1be58208f 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 73d5b67617e22c7d5a305d86a05ea40972683b63 +Subproject commit 4a1be58208fc89a2d56cd95aed4864158890b96b From 0794980d01454c697b22a4d277ab84fffa99476e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 10 Mar 2016 17:34:52 +0900 Subject: [PATCH 430/688] pdf.dll is not shipped any more --- script/create-dist.py | 1 - 1 file changed, 1 deletion(-) diff --git a/script/create-dist.py b/script/create-dist.py index 32d8f52aff3..f3894eb4fa2 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -40,7 +40,6 @@ TARGET_BINARIES = { 'msvcr120.dll', 'ffmpeg.dll', 'node.dll', - 'pdf.dll', 'content_resources_200_percent.pak', 'ui_resources_200_percent.pak', 'xinput1_3.dll', From 60f40a6704091706cf2cc0245d1e29a53a5980ea Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 10 Mar 2016 21:01:45 +0900 Subject: [PATCH 431/688] Fix linking error for Release build on Linux --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 4a1be58208f..5077bee89dc 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 4a1be58208fc89a2d56cd95aed4864158890b96b +Subproject commit 5077bee89dc3403982e9a5c59cc0a2218b2d4610 From e27e3d641c79cd82787d042e7abf0819ccf67113 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 4 Mar 2016 05:24:01 +0530 Subject: [PATCH 432/688] linux: optionaly allow building x64 targets with sysroot --- .gitignore | 1 + script/bootstrap.py | 29 ++++++++++++++++++++++------- script/install-sysroot.py | 21 +++++++++++++++------ script/update.py | 6 ++++++ toolchain.gypi | 5 ++++- 5 files changed, 48 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index eb9aedb4e2f..a92239801a4 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ /external_binaries/ /out/ /vendor/brightray/vendor/download/ +/vendor/debian_wheezy_amd64-sysroot/ /vendor/debian_wheezy_arm-sysroot/ /vendor/debian_wheezy_i386-sysroot/ /vendor/python_26/ diff --git a/script/bootstrap.py b/script/bootstrap.py index 6eaf635bfd8..b09bc015d70 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -43,8 +43,8 @@ def main(): args.libcc_source_path, args.libcc_shared_library_path, args.libcc_static_library_path) - if args.target_arch in ['arm', 'ia32'] and PLATFORM == 'linux': - download_sysroot(args.target_arch) + if PLATFORM == 'linux': + download_sysroot(args.target_arch, args.sysroot_url, args.sysroot_sha1sum) create_chrome_version_h() touch_config_gypi() @@ -79,6 +79,10 @@ def parse_args(): help='The shared library path of libchromiumcontent.') parser.add_argument('--libcc_static_library_path', required=False, help='The static library path of libchromiumcontent.') + parser.add_argument('--sysroot_url', required=False, + help='The URL to download sysroot image.') + parser.add_argument('--sysroot_sha1sum', required=False, + help='SHA1 hash of the sysroot image tarball.') return parser.parse_args() @@ -163,11 +167,22 @@ def update_clang(): execute_stdout([os.path.join(SOURCE_ROOT, 'script', 'update-clang.sh')]) -def download_sysroot(target_arch): - if target_arch == 'ia32': - target_arch = 'i386' - execute_stdout([os.path.join(SOURCE_ROOT, 'script', 'install-sysroot.py'), - '--arch', target_arch]) +def download_sysroot(target_arch, url, sha1sum): + if url or target_arch in ['ia32', 'arm']: + os.environ['USE_SYSROOT'] = '1' + sysroot_script = os.path.join(SOURCE_ROOT, 'script', 'install-sysroot.py') + if target_arch == 'ia32': + target_arch = 'i386' + if target_arch == 'x64': + target_arch = 'amd64' + args = [ + '--arch', target_arch + ] + if url: + args += ['--url', url] + if sha1sum: + args += ['--revision', sha1sum] + execute_stdout([sysroot_script] + args) def create_chrome_version_h(): diff --git a/script/install-sysroot.py b/script/install-sysroot.py index 69acfb13269..6c7b8adc62d 100755 --- a/script/install-sysroot.py +++ b/script/install-sysroot.py @@ -134,7 +134,11 @@ def main(): print 'Unknown architecture: %s' % target_arch assert(False) - url = '%s/%s/%s/%s' % (URL_PREFIX, URL_PATH, revision, tarball_filename) + if options.url: + url = options.url + tarball_sha1sum = options.revision + else: + url = '%s/%s/%s/%s' % (URL_PREFIX, URL_PATH, revision, tarball_filename) stamp = os.path.join(sysroot, '.stamp') if os.path.exists(stamp): @@ -153,11 +157,12 @@ def main(): sys.stdout.flush() sys.stderr.flush() subprocess.check_call(['curl', '--fail', '-L', url, '-o', tarball]) - sha1sum = GetSha1(tarball) - if sha1sum != tarball_sha1sum: - print 'Tarball sha1sum is wrong.' - print 'Expected %s, actual: %s' % (tarball_sha1sum, sha1sum) - return 1 + if tarball_sha1sum: + sha1sum = GetSha1(tarball) + if sha1sum != tarball_sha1sum: + print 'Tarball sha1sum is wrong.' + print 'Expected %s, actual: %s' % (tarball_sha1sum, sha1sum) + return 1 subprocess.check_call(['tar', 'xf', tarball, '-C', sysroot]) os.remove(tarball) @@ -173,5 +178,9 @@ if __name__ == '__main__': 'Linux builds') parser.add_option('--arch', type='choice', choices=valid_archs, help='Sysroot architecture: %s' % ', '.join(valid_archs)) + parser.add_option('--url', default=None, + help='The URL to download sysroot image.') + parser.add_option('--revision', default=None, + help='SHA1 hash of the sysroot image tarball.') options, _ = parser.parse_args() sys.exit(main()) diff --git a/script/update.py b/script/update.py index e91e8401cbf..2388f16515c 100755 --- a/script/update.py +++ b/script/update.py @@ -60,12 +60,18 @@ def run_gyp(target_arch, component): mas_build = 1 else: mas_build = 0 + # Whether to use sysroot image. + if os.environ.has_key('USE_SYSROOT'): + use_sysroot = 1 + else: + use_sysroot = 0 defines = [ '-Dlibchromiumcontent_component={0}'.format(component), '-Dtarget_arch={0}'.format(target_arch), '-Dhost_arch={0}'.format(get_host_arch()), '-Dlibrary=static_library', '-Dmas_build={0}'.format(mas_build), + '-Duse_sysroot={0}'.format(use_sysroot) ] return subprocess.call([python, gyp, '-f', 'ninja', '--depth', '.', 'atom.gyp', '-Icommon.gypi'] + defines, env=env) diff --git a/toolchain.gypi b/toolchain.gypi index 23592d0473a..7215cb8c542 100644 --- a/toolchain.gypi +++ b/toolchain.gypi @@ -113,7 +113,7 @@ }], # Setup sysroot environment. - ['OS=="linux" and target_arch in ["arm", "ia32"]', { + ['OS=="linux" and target_arch in ["arm", "ia32", "x64"] and use_sysroot', { 'variables': { 'conditions': [ ['target_arch=="arm"', { @@ -124,6 +124,9 @@ ['target_arch=="ia32"', { 'sysroot': '<(source_root)/vendor/debian_wheezy_i386-sysroot', }], + ['target_arch=="x64"', { + 'sysroot': '<(source_root)/vendor/debian_wheezy_amd64-sysroot', + }], ], }, 'target_defaults': { From 91951472bf06e82ab472d8aad62b4be17a9b3033 Mon Sep 17 00:00:00 2001 From: Robo Date: Tue, 8 Mar 2016 20:35:32 +0530 Subject: [PATCH 433/688] use sysroot by default on linux --- script/bootstrap.py | 30 ++++++++---------------------- script/install-sysroot.py | 33 ++++++++++++--------------------- script/update.py | 6 ------ toolchain.gypi | 2 +- 4 files changed, 21 insertions(+), 50 deletions(-) diff --git a/script/bootstrap.py b/script/bootstrap.py index b09bc015d70..b0a528f760a 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -44,7 +44,7 @@ def main(): args.libcc_static_library_path) if PLATFORM == 'linux': - download_sysroot(args.target_arch, args.sysroot_url, args.sysroot_sha1sum) + download_sysroot(args.target_arch) create_chrome_version_h() touch_config_gypi() @@ -79,10 +79,6 @@ def parse_args(): help='The shared library path of libchromiumcontent.') parser.add_argument('--libcc_static_library_path', required=False, help='The static library path of libchromiumcontent.') - parser.add_argument('--sysroot_url', required=False, - help='The URL to download sysroot image.') - parser.add_argument('--sysroot_sha1sum', required=False, - help='SHA1 hash of the sysroot image tarball.') return parser.parse_args() @@ -167,23 +163,13 @@ def update_clang(): execute_stdout([os.path.join(SOURCE_ROOT, 'script', 'update-clang.sh')]) -def download_sysroot(target_arch, url, sha1sum): - if url or target_arch in ['ia32', 'arm']: - os.environ['USE_SYSROOT'] = '1' - sysroot_script = os.path.join(SOURCE_ROOT, 'script', 'install-sysroot.py') - if target_arch == 'ia32': - target_arch = 'i386' - if target_arch == 'x64': - target_arch = 'amd64' - args = [ - '--arch', target_arch - ] - if url: - args += ['--url', url] - if sha1sum: - args += ['--revision', sha1sum] - execute_stdout([sysroot_script] + args) - +def download_sysroot(target_arch): + if target_arch == 'ia32': + target_arch = 'i386' + if target_arch == 'x64': + target_arch = 'amd64' + execute_stdout([os.path.join(SOURCE_ROOT, 'script', 'install-sysroot.py'), + '--arch', target_arch]) def create_chrome_version_h(): version_file = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor', diff --git a/script/install-sysroot.py b/script/install-sysroot.py index 6c7b8adc62d..16df6f7b9e5 100755 --- a/script/install-sysroot.py +++ b/script/install-sysroot.py @@ -30,15 +30,15 @@ from lib.util import get_host_arch SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) URL_PREFIX = 'https://github.com' URL_PATH = 'atom/debian-sysroot-image-creator/releases/download' -REVISION_AMD64 = 264817 -REVISION_I386 = 'v0.2.0' -REVISION_ARM = 'v0.1.0' +REVISION_AMD64 = 'v0.3.0' +REVISION_I386 = 'v0.3.0' +REVISION_ARM = 'v0.3.0' TARBALL_AMD64 = 'debian_wheezy_amd64_sysroot.tgz' TARBALL_I386 = 'debian_wheezy_i386_sysroot.tgz' TARBALL_ARM = 'debian_wheezy_arm_sysroot.tgz' -TARBALL_AMD64_SHA1SUM = '74b7231e12aaf45c5c5489d9aebb56bd6abb3653' -TARBALL_I386_SHA1SUM = 'f5b2ceaeb3f7e6bc2058733585fe877d002b5fa7' -TARBALL_ARM_SHA1SUM = '72e668c57b8591e108759584942ddb6f6cee1322' +TARBALL_AMD64_SHA1SUM = '3dc6f553c3f4e54166ac1264b7754cddc01942e4' +TARBALL_I386_SHA1SUM = '62d2490de201f73b3774868f7ab82b2a48acf3c0' +TARBALL_ARM_SHA1SUM = '1110793341e7a3c12adfe5e53138d692a22c99bc' SYSROOT_DIR_AMD64 = 'debian_wheezy_amd64-sysroot' SYSROOT_DIR_I386 = 'debian_wheezy_i386-sysroot' SYSROOT_DIR_ARM = 'debian_wheezy_arm-sysroot' @@ -134,11 +134,7 @@ def main(): print 'Unknown architecture: %s' % target_arch assert(False) - if options.url: - url = options.url - tarball_sha1sum = options.revision - else: - url = '%s/%s/%s/%s' % (URL_PREFIX, URL_PATH, revision, tarball_filename) + url = '%s/%s/%s/%s' % (URL_PREFIX, URL_PATH, revision, tarball_filename) stamp = os.path.join(sysroot, '.stamp') if os.path.exists(stamp): @@ -157,12 +153,11 @@ def main(): sys.stdout.flush() sys.stderr.flush() subprocess.check_call(['curl', '--fail', '-L', url, '-o', tarball]) - if tarball_sha1sum: - sha1sum = GetSha1(tarball) - if sha1sum != tarball_sha1sum: - print 'Tarball sha1sum is wrong.' - print 'Expected %s, actual: %s' % (tarball_sha1sum, sha1sum) - return 1 + sha1sum = GetSha1(tarball) + if sha1sum != tarball_sha1sum: + print 'Tarball sha1sum is wrong.' + print 'Expected %s, actual: %s' % (tarball_sha1sum, sha1sum) + return 1 subprocess.check_call(['tar', 'xf', tarball, '-C', sysroot]) os.remove(tarball) @@ -178,9 +173,5 @@ if __name__ == '__main__': 'Linux builds') parser.add_option('--arch', type='choice', choices=valid_archs, help='Sysroot architecture: %s' % ', '.join(valid_archs)) - parser.add_option('--url', default=None, - help='The URL to download sysroot image.') - parser.add_option('--revision', default=None, - help='SHA1 hash of the sysroot image tarball.') options, _ = parser.parse_args() sys.exit(main()) diff --git a/script/update.py b/script/update.py index 2388f16515c..e91e8401cbf 100755 --- a/script/update.py +++ b/script/update.py @@ -60,18 +60,12 @@ def run_gyp(target_arch, component): mas_build = 1 else: mas_build = 0 - # Whether to use sysroot image. - if os.environ.has_key('USE_SYSROOT'): - use_sysroot = 1 - else: - use_sysroot = 0 defines = [ '-Dlibchromiumcontent_component={0}'.format(component), '-Dtarget_arch={0}'.format(target_arch), '-Dhost_arch={0}'.format(get_host_arch()), '-Dlibrary=static_library', '-Dmas_build={0}'.format(mas_build), - '-Duse_sysroot={0}'.format(use_sysroot) ] return subprocess.call([python, gyp, '-f', 'ninja', '--depth', '.', 'atom.gyp', '-Icommon.gypi'] + defines, env=env) diff --git a/toolchain.gypi b/toolchain.gypi index 7215cb8c542..42c2987dc68 100644 --- a/toolchain.gypi +++ b/toolchain.gypi @@ -113,7 +113,7 @@ }], # Setup sysroot environment. - ['OS=="linux" and target_arch in ["arm", "ia32", "x64"] and use_sysroot', { + ['OS=="linux" and target_arch in ["arm", "ia32", "x64"]', { 'variables': { 'conditions': [ ['target_arch=="arm"', { From dfe1641d1e8a6ec77f3cc8f14346b3f3ab75c9b1 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 9 Mar 2016 19:41:17 +0530 Subject: [PATCH 434/688] set path for pkg-config when using sysroot --- common.gypi | 6 +++ toolchain.gypi | 51 +++++++++++++----------- tools/linux/pkg-config-wrapper | 49 +++++++++++++++++++++++ tools/linux/rewrite_dirs.py | 71 ++++++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 23 deletions(-) create mode 100755 tools/linux/pkg-config-wrapper create mode 100755 tools/linux/rewrite_dirs.py diff --git a/common.gypi b/common.gypi index 6eacdc93a02..285baa84c29 100644 --- a/common.gypi +++ b/common.gypi @@ -260,5 +260,11 @@ }, }, }], # OS=="mac" + + ['OS=="linux"', { + 'variables': { + 'pkg-config': '<(source_root)/tools/linux/pkg-config-wrapper "<(sysroot)" "<(target_arch)" "<(system_libdir)"', + }, + }], # OS=="linux" ], } diff --git a/toolchain.gypi b/toolchain.gypi index 42c2987dc68..8e07ecc497b 100644 --- a/toolchain.gypi +++ b/toolchain.gypi @@ -5,8 +5,7 @@ # Set this to true when building with Clang. 'clang%': 1, - # Path to sysroot dir. - 'sysroot%': '', + 'system_libdir%': 'lib', 'variables': { # The minimum OS X SDK version to use. @@ -17,12 +16,20 @@ # Set NEON compilation flags. 'arm_neon%': 1, + + 'conditions': [ + # Define the abosulte version of <(DEPTH). + ['OS!="win"', { + 'source_root%': '&2 + exit 1 +fi + +rewrite=`dirname $0`/rewrite_dirs.py +package=${!#} + +libdir=$root/usr/$libpath/pkgconfig:$root/usr/share/pkgconfig + +set -e +# Some sysroots, like the Chromium OS ones, may generate paths that are not +# relative to the sysroot. For example, +# /path/to/chroot/build/x86-generic/usr/lib/pkgconfig/pkg.pc may have all paths +# relative to /path/to/chroot (i.e. prefix=/build/x86-generic/usr) instead of +# relative to /path/to/chroot/build/x86-generic (i.e prefix=/usr). +# To support this correctly, it's necessary to extract the prefix to strip from +# pkg-config's |prefix| variable. +prefix=`PKG_CONFIG_LIBDIR=$libdir pkg-config --variable=prefix "$package" | sed -e 's|/usr$||'` +result=`PKG_CONFIG_LIBDIR=$libdir pkg-config "$@"` +echo "$result"| $rewrite --sysroot "$root" --strip-prefix "$prefix" diff --git a/tools/linux/rewrite_dirs.py b/tools/linux/rewrite_dirs.py new file mode 100755 index 00000000000..30f22f0cd61 --- /dev/null +++ b/tools/linux/rewrite_dirs.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python +# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Rewrites paths in -I, -L and other option to be relative to a sysroot.""" + +import sys +import os +import optparse + +REWRITE_PREFIX = ['-I', + '-idirafter', + '-imacros', + '-imultilib', + '-include', + '-iprefix', + '-iquote', + '-isystem', + '-L'] + +def RewritePath(path, opts): + """Rewrites a path by stripping the prefix and prepending the sysroot.""" + sysroot = opts.sysroot + prefix = opts.strip_prefix + if os.path.isabs(path) and not path.startswith(sysroot): + if path.startswith(prefix): + path = path[len(prefix):] + path = path.lstrip('/') + return os.path.join(sysroot, path) + else: + return path + + +def RewriteLine(line, opts): + """Rewrites all the paths in recognized options.""" + args = line.split() + count = len(args) + i = 0 + while i < count: + for prefix in REWRITE_PREFIX: + # The option can be either in the form "-I /path/to/dir" or + # "-I/path/to/dir" so handle both. + if args[i] == prefix: + i += 1 + try: + args[i] = RewritePath(args[i], opts) + except IndexError: + sys.stderr.write('Missing argument following %s\n' % prefix) + break + elif args[i].startswith(prefix): + args[i] = prefix + RewritePath(args[i][len(prefix):], opts) + i += 1 + + return ' '.join(args) + + +def main(argv): + parser = optparse.OptionParser() + parser.add_option('-s', '--sysroot', default='/', help='sysroot to prepend') + parser.add_option('-p', '--strip-prefix', default='', help='prefix to strip') + opts, args = parser.parse_args(argv[1:]) + + for line in sys.stdin.readlines(): + line = RewriteLine(line.strip(), opts) + print line + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) From ed2103a49fdafad683fd81eb071c48e6b79c846d Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 10 Mar 2016 17:24:45 +0530 Subject: [PATCH 435/688] update sysroot image revisions --- script/bootstrap.py | 2 +- script/install-sysroot.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/script/bootstrap.py b/script/bootstrap.py index b0a528f760a..1efea3c2897 100755 --- a/script/bootstrap.py +++ b/script/bootstrap.py @@ -165,7 +165,7 @@ def update_clang(): def download_sysroot(target_arch): if target_arch == 'ia32': - target_arch = 'i386' + target_arch = 'i386' if target_arch == 'x64': target_arch = 'amd64' execute_stdout([os.path.join(SOURCE_ROOT, 'script', 'install-sysroot.py'), diff --git a/script/install-sysroot.py b/script/install-sysroot.py index 16df6f7b9e5..be68fbad0ad 100755 --- a/script/install-sysroot.py +++ b/script/install-sysroot.py @@ -30,15 +30,15 @@ from lib.util import get_host_arch SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) URL_PREFIX = 'https://github.com' URL_PATH = 'atom/debian-sysroot-image-creator/releases/download' -REVISION_AMD64 = 'v0.3.0' -REVISION_I386 = 'v0.3.0' -REVISION_ARM = 'v0.3.0' +REVISION_AMD64 = 'v0.4.0' +REVISION_I386 = 'v0.4.0' +REVISION_ARM = 'v0.4.0' TARBALL_AMD64 = 'debian_wheezy_amd64_sysroot.tgz' TARBALL_I386 = 'debian_wheezy_i386_sysroot.tgz' TARBALL_ARM = 'debian_wheezy_arm_sysroot.tgz' -TARBALL_AMD64_SHA1SUM = '3dc6f553c3f4e54166ac1264b7754cddc01942e4' -TARBALL_I386_SHA1SUM = '62d2490de201f73b3774868f7ab82b2a48acf3c0' -TARBALL_ARM_SHA1SUM = '1110793341e7a3c12adfe5e53138d692a22c99bc' +TARBALL_AMD64_SHA1SUM = 'a7e8faa99b681317969ac450a27233925bdeed62' +TARBALL_I386_SHA1SUM = '9fc827eddc26e562c0a0b2586be5dc075e570e10' +TARBALL_ARM_SHA1SUM = 'bfa4233708ab937d682a14e8d87ddba3cadb6eae' SYSROOT_DIR_AMD64 = 'debian_wheezy_amd64-sysroot' SYSROOT_DIR_I386 = 'debian_wheezy_i386-sysroot' SYSROOT_DIR_ARM = 'debian_wheezy_arm-sysroot' From 8e19edd1b519fec7420f3245397c660e13e955a5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 10 Mar 2016 21:58:09 +0900 Subject: [PATCH 436/688] Move toolchain related configures into one place --- common.gypi | 6 ------ toolchain.gypi | 50 +++++++++++++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/common.gypi b/common.gypi index 285baa84c29..6eacdc93a02 100644 --- a/common.gypi +++ b/common.gypi @@ -260,11 +260,5 @@ }, }, }], # OS=="mac" - - ['OS=="linux"', { - 'variables': { - 'pkg-config': '<(source_root)/tools/linux/pkg-config-wrapper "<(sysroot)" "<(target_arch)" "<(system_libdir)"', - }, - }], # OS=="linux" ], } diff --git a/toolchain.gypi b/toolchain.gypi index 8e07ecc497b..7c3cd0d0583 100644 --- a/toolchain.gypi +++ b/toolchain.gypi @@ -5,8 +5,6 @@ # Set this to true when building with Clang. 'clang%': 1, - 'system_libdir%': 'lib', - 'variables': { # The minimum OS X SDK version to use. 'mac_sdk_min%': '10.10', @@ -17,12 +15,8 @@ # Set NEON compilation flags. 'arm_neon%': 1, - 'conditions': [ - # Define the abosulte version of <(DEPTH). - ['OS!="win"', { - 'source_root%': ' Date: Thu, 10 Mar 2016 23:12:57 +0800 Subject: [PATCH 437/688] finish browser-window first --- docs-translations/zh-CN/api/browser-window.md | 767 ++++++++++++++++++ 1 file changed, 767 insertions(+) create mode 100644 docs-translations/zh-CN/api/browser-window.md diff --git a/docs-translations/zh-CN/api/browser-window.md b/docs-translations/zh-CN/api/browser-window.md new file mode 100644 index 00000000000..66ae76cff91 --- /dev/null +++ b/docs-translations/zh-CN/api/browser-window.md @@ -0,0 +1,767 @@ +# BrowserWindow + + `BrowserWindow` 类让你有创建一个浏览器窗口的权力。例如: + +```javascript +// In the main process. +const BrowserWindow = require('electron').BrowserWindow; + +// Or in the renderer process. +const BrowserWindow = require('electron').remote.BrowserWindow; + +var win = new BrowserWindow({ width: 800, height: 600, show: false }); +win.on('closed', function() { + win = null; +}); + +win.loadURL('https://github.com'); +win.show(); +``` + +你也可以不通过chrome创建窗口,使用 +[Frameless Window](frameless-window.md) API. + +## Class: BrowserWindow + +`BrowserWindow` 是一个 +[EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter). + +通过 `options` 可以创建一个具有本质属性的 `BrowserWindow` . + +### `new BrowserWindow([options])` + +* `options` Object + * `width` Integer - 窗口宽度,单位像素. 默认是 `800`. + * `height` Integer - 窗口高度,单位像素. 默认是 `600`. + * `x` Integer - 窗口相对于屏幕的左偏移位置.默认居中. + * `y` Integer - 窗口相对于屏幕的顶部偏移位置.默认居中. + * `useContentSize` Boolean - `width` 和 `height` 使用web网页size, 这意味着实际窗口的size应该包括窗口框架的size,稍微会大一点,默认为 `false`. + * `center` Boolean - 窗口屏幕居中. + * `minWidth` Integer - 窗口最小宽度,默认为 `0`. + * `minHeight` Integer - 窗口最小高度,默认为 `0`. + * `maxWidth` Integer - 窗口最大宽度,默认无限制. + * `maxHeight` Integer - 窗口最大高度,默认无限制. + * `resizable` Boolean - 是否可以改变窗口size,默认为 `true`. + * `movable` Boolean - 窗口是否可以拖动. 在 Linux 上无效. 默认为 `true`. + * `minimizable` Boolean - 窗口是否可以最小化. 在 Linux 上无效. 默认为 `true`. + * `maximizable` Boolean - 窗口是否可以最大化. 在 Linux 上无效. 默认为 `true`. + * `closable` Boolean - 窗口是否可以关闭. 在 Linux 上无效. 默认为 `true`. + * `alwaysOnTop` Boolean - 窗口是否总是显示在其他窗口之前. 在 Linux 上无效. 默认为 `false`. + * `fullscreen` Boolean - 窗口是否可以全屏幕. 当明确设置值为When `false` ,全屏化按钮将会隐藏,在 OS X 将禁用. 默认 `false`. + * `fullscreenable` Boolean - 在 OS X 上,全屏化按钮是否可用,默认为 `true`. + * `skipTaskbar` Boolean - 是否在人物栏中显示窗口. 默认是`false`. + * `kiosk` Boolean - kiosk 方式. 默认为 `false`. + * `title` String - 窗口默认title. 默认 `"Electron"`. + * `icon` [NativeImage](native-image.md) - 窗口图标, 如果不设置,窗口将使用可用的默认图标. + * `show` Boolean - 窗口创建的时候是否显示. 默认为 `true`. + * `frame` Boolean - 指定 `false` 来创建一个 + [Frameless Window](frameless-window.md). 默认为 `true`. + * `acceptFirstMouse` Boolean - 是否允许单击web view来激活窗口 . 默认为 `false`. + * `disableAutoHideCursor` Boolean - 当 typing 时是否隐藏鼠标.默认 `false`. + * `autoHideMenuBar` Boolean - 除非点击 `Alt`,否则隐藏菜单栏.默认为 `false`. + * `enableLargerThanScreen` Boolean - 是否允许允许改变窗口大小大于屏幕. 默认是 `false`. + * `backgroundColor` String -窗口的 background color 值为十六进制,如 `#66CD00` 或 `#FFF` 或 `#80FFFFFF` (支持透明度). 默认为在 Linux 和 Windows 上为 + `#000` (黑色) , Mac上为 `#FFF`(或透明). + * `hasShadow` Boolean - 窗口是否有阴影. 只在 OS X 上有效. 默认为 `true`. + * `darkTheme` Boolean - 为窗口使用 dark 主题, 只在一些拥有 GTK+3 桌面环境上有效. 默认为 `false`. + * `transparent` Boolean - 窗口 [透明](frameless-window.md). + 默认为 `false`. + * `type` String - 窗口type, 默认普通窗口. 下面查看更多. + * `titleBarStyle` String - 窗口标题栏样式. 下面查看更多. + * `webPreferences` Object - 设置界面特性. 下面查看更多. + +`type` 的值和效果不同平台展示效果不同,具体: + +* Linux, 可用值为 `desktop`, `dock`, `toolbar`, `splash`, + `notification`. +* OS X, 可用值为 `desktop`, `textured`. + * `textured` type 添加金属梯度效果 + (`NSTexturedBackgroundWindowMask`). + * `desktop` 设置窗口在桌面背景窗口水平 + (`kCGDesktopWindowLevel - 1`). 注意桌面窗口不可聚焦, 不可不支持键盘和鼠标事件, 但是可以使用 `globalShortcut` 来解决输入问题. + +`titleBarStyle` 只在 OS X 10.10 Yosemite 或更新版本上支持. +可用值: + +* `default` 以及无值, 显示在 Mac 标题栏上为不透明的标准灰色. +* `hidden` 隐藏标题栏,内容充满整个窗口, 然后它依然在左上角,仍然受标准窗口控制. +* `hidden-inset`主体隐藏,显示小的控制按钮在窗口边缘. + +`webPreferences` 参数是个对象,它的属性: + +* `nodeIntegration` Boolean - 是否完整支持node. 默认为 `true`. +* `preload` String - 界面的其它脚本运行之前预先加载一个指定脚本. 这个脚本将一直可以使用 node APIs 无论 node integration 是否开启. 脚本路径为绝对路径. + 当 node integration 关闭, 预加载的脚本将从全局范围重新引入node的全局引用标志. 查看例子 + [here](process.md#event-loaded). +* `session` [Session](session.md#class-session) - 设置界面session. 而不是直接忽略session对象 , 也可用 `partition` 来代替, 它接受一个 partition 字符串. 当同时使用 `session` 和 `partition`, `session` 优先级更高. + 默认使用默认 session. +* `partition` String - 通过session的partition字符串来设置界面session. 如果 `partition` 以 `persist:` 开头, 这个界面将会为所有界面使用相同的 `partition`. 如果没有 `persist:` 前缀, 界面使用历史session. 通过分享同一个 `partition`, 所有界面使用相同的session. 默认使用默认 session. +* `zoomFactor` Number - 界面默认缩放值, `3.0` 表示 + `300%`. 默认 `1.0`. +* `javascript` Boolean - 开启javascript支持. 默认为`true`. +* `webSecurity` Boolean - 当设置为 `false`, 它将禁用相同地方的规则 (通常测试服), 并且如果有2个非用户设置的参数,就设置 + `allowDisplayingInsecureContent` 和 `allowRunningInsecureContent` 的值为 + `true`. 默认为 `true`. +* `allowDisplayingInsecureContent` Boolean -允许一个使用 https的界面来展示由 http URLs 传过来的资源. 默认`false`. +* `allowRunningInsecureContent` Boolean - Boolean -允许一个使用 https的界面来渲染由 http URLs 提交的html,css,javascript. 默认为 `false`. +* `images` Boolean - 开启图片使用支持. 默认 `true`. +* `textAreasAreResizable` Boolean - textArea 可以编辑. 默认为 `true`. +* `webgl` Boolean - 开启 WebGL 支持. 默认为 `true`. +* `webaudio` Boolean - 开启 WebAudio 支持. 默认为 `true`. +* `plugins` Boolean - 是否开启插件支持. 默认为 `false`. +* `experimentalFeatures` Boolean - 开启 Chromium 的 可测试 特性. + 默认为 `false`. +* `experimentalCanvasFeatures` Boolean - 开启 Chromium 的 canvas 可测试特性. 默认为 `false`. +* `directWrite` Boolean - 开启窗口的 DirectWrite font 渲染系统. 默认为 `true`. +* `blinkFeatures` String - 以 `,` 分隔的特性列表, 如 + `CSSVariables,KeyboardEventKey`. 被支持的所有特性可在 [setFeatureEnabledFromString][blink-feature-string] + 中找到. +* `defaultFontFamily` Object - 设置 font-family 默认字体. + * `standard` String - 默认为 `Times New Roman`. + * `serif` String - 默认为 `Times New Roman`. + * `sansSerif` String - 默认为 `Arial`. + * `monospace` String - 默认为 `Courier New`. +* `defaultFontSize` Integer - 默认为 `16`. +* `defaultMonospaceFontSize` Integer - 默认为 `13`. +* `minimumFontSize` Integer - 默认为 `0`. +* `defaultEncoding` String - 默认为 `ISO-8859-1`. + +## 事件 + + `BrowserWindow` 对象可触发下列事件: + +**注意:** 一些事件只能在特定os环境中触发,已经尽可能地标出. + +### Event: 'page-title-updated' + +返回: + +* `event` Event + +当文档改变标题时触发,使用 `event.preventDefault()` 可以阻止原窗口的标题改变. + +### Event: 'close' + +返回: + +* `event` Event + +在窗口要关闭的时候触发. 它在DOM的 `beforeunload` and `unload` 事件之前触发.使用 `event.preventDefault()` 可以取消这个操作 + +通常你想通过 `beforeunload` 处理器来决定是否关闭窗口,但是它也会在窗口重载的时候被触发. 在 Electron 中,返回一个空的字符串或 `false` 可以取消关闭.例如: + +```javascript +window.onbeforeunload = function(e) { + console.log('I do not want to be closed'); + + // Unlike usual browsers, in which a string should be returned and the user is + // prompted to confirm the page unload, Electron gives developers more options. + // Returning empty string or false would prevent the unloading now. + // You can also use the dialog API to let the user confirm closing the application. + e.returnValue = false; +}; +``` + +### Event: 'closed' + +当窗口已经关闭的时候触发.当你接收到这个事件的时候,你应当删除对已经关闭的窗口的引用对象和避免再次使用它. + +### Event: 'unresponsive' + +在界面卡死的时候触发事件. + +### Event: 'responsive' + +在界面恢复卡死的时候触发. + +### Event: 'blur' + +在窗口失去焦点的时候触发. + +### Event: 'focus' + +在窗口获得焦点的时候触发. + +### Event: 'maximize' + +在窗口最大化的时候触发. + +### Event: 'unmaximize' + +在窗口退出最大化的时候触发. + +### Event: 'minimize' + +在窗口最小化的时候触发. + +### Event: 'restore' + +在窗口从最小化恢复的时候触发. +Emitted when the window is restored from minimized state. + +### Event: 'resize' + +在窗口size改变的时候触发. +Emitted when the window is getting resized. + +### Event: 'move' + +在窗口移动的时候触发. + +注意:在 OS X 中别名为 `moved`. + +### Event: 'moved' _OS X_ + +在窗口移动的时候触发. + +### Event: 'enter-full-screen' + +在的窗口进入全屏状态时候触发. + +### Event: 'leave-full-screen' + +在的窗口退出全屏状态时候触发. + +### Event: 'enter-html-full-screen' + +在的窗口通过 html api 进入全屏状态时候触发. + +### Event: 'leave-html-full-screen' + +在的窗口通过 html api 退出全屏状态时候触发. + +### Event: 'app-command' _Windows_ + +在请求一个[App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx)的时候触发. +典型的是键盘媒体或浏览器命令, Windows上的 "Back" 按钮用作鼠标也会触发. + +```js +someWindow.on('app-command', function(e, cmd) { + // Navigate the window back when the user hits their mouse back button + if (cmd === 'browser-backward' && someWindow.webContents.canGoBack()) { + someWindow.webContents.goBack(); + } +}); +``` + +### Event: 'scroll-touch-begin' _OS X_ + +在滚动条事件开始的时候触发. + +### Event: 'scroll-touch-end' _OS X_ + +在滚动条事件结束的时候触发. + +## 方法 + +`BrowserWindow` 对象有如下方法: + +### `BrowserWindow.getAllWindows()` + +返回一个所有已经打开了的窗口的对象数组. + +### `BrowserWindow.getFocusedWindow()` + +返回应用当前聚焦窗口,如果没有就返回 `null`. + +### `BrowserWindow.fromWebContents(webContents)` + +* `webContents` [WebContents](web-contents.md) + +根据 `webContents` 查找窗口. + +### `BrowserWindow.fromId(id)` + +* `id` Integer + +根据 id 查找窗口. + +### `BrowserWindow.addDevToolsExtension(path)` + +* `path` String + +添加位于 `path` 的开发者工具栏扩展,并且返回扩展项的名字. + +这个扩展会被添加到历史,所以只需要使用这个API一次,这个api不可用作编程使用. + +### `BrowserWindow.removeDevToolsExtension(name)` + +* `name` String + +删除开发者工具栏名为 `name` 的扩展. + +## 实例属性 + +使用 `new BrowserWindow` 创建的实例对象,有如下属性: + +```javascript +// In this example `win` is our instance +var win = new BrowserWindow({ width: 800, height: 600 }); +``` + +### `win.webContents` + +这个窗口的 `WebContents` 对象,所有与界面相关的事件和方法都通过它完成的. + +查看 [`webContents` documentation](web-contents.md) 的方法和事件. + +### `win.id` + +窗口的唯一id. + +## 实例方法 + +使用 `new BrowserWindow` 创建的实例对象,有如下方法: + +**注意:** 一些方法只能在特定os环境中调用,已经尽可能地标出. + +### `win.destroy()` + +强制关闭窗口, `unload` and `beforeunload` 不会触发,并且 `close` 也不会触发, 但是它保证了 `closed` 触发. + +### `win.close()` + +尝试关闭窗口,这与用户点击关闭按钮的效果一样. 虽然网页可能会取消关闭,查看 [close event](#event-close). + +### `win.focus()` + +聚焦窗口. + +### `win.isFocused()` + +返回 boolean, 窗口是否聚焦. + +### `win.show()` + +展示并且聚焦窗口. + +### `win.showInactive()` + +展示窗口但是不聚焦. + +### `win.hide()` + +隐藏窗口. + +### `win.isVisible()` + +返回 boolean, 窗口是否可见. + +### `win.maximize()` + +窗口最大化. + +### `win.unmaximize()` + +取消窗口最大化. + +### `win.isMaximized()` + +返回 boolean, 窗口是否最大化. + +### `win.minimize()` + +窗口最小化. 在一些os中,它将在dock中显示. + +### `win.restore()` + +将最小化的窗口恢复为之前的状态. + +### `win.isMinimized()` + +返回 boolean, 窗口是否最小化. + +### `win.setFullScreen(flag)` + +* `flag` Boolean + +设置是否全屏. + +### `win.isFullScreen()` + +返回 boolean, 窗口是否全屏化. + +### `win.setAspectRatio(aspectRatio[, extraSize])` _OS X_ + +* `aspectRatio` 维持部分视图内容窗口的高宽比值. +* `extraSize` Object (可选) - 维持高宽比值时不包含的额外size. + * `width` Integer + * `height` Integer + +由一个窗口来维持高宽比值. `extraSize` 允许开发者使用它,它的单位为像素,不包含在 `aspectRatio` 中.这个 API 可用来区分窗口的size和内容的size . + +想象一个普通可控的HD video 播放器窗口. 假如左边缘有15控制像素,右边缘有25控制像素,在播放器下面有50控制像素.为了在播放器内保持一个 16:9 的高宽比例,我们可以调用这个api传入参数16/9 and +[ 40, 50 ].第二个参数不管网页中的额外的宽度和高度在什么位置,只要它们存在就行.只需要把网页中的所有额外的高度和宽度加起来就行. + +### `win.setBounds(options[, animate])` + +* `options` Object + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer +* `animate` Boolean (可选) _OS X_ + +重新设置窗口的宽高值,并且移动到指定的 `x`, `y` 位置. + +### `win.getBounds()` + +返回一个对象,它包含了窗口的宽,高,x坐标,y坐标. + +### `win.setSize(width, height[, animate])` + +* `width` Integer +* `height` Integer +* `animate` Boolean (可选) _OS X_ + +重新设置窗口的宽高值. + +### `win.getSize()` + +返回一个数组,它包含了窗口的宽,高. + +### `win.setContentSize(width, height[, animate])` + +* `width` Integer +* `height` Integer +* `animate` Boolean (可选) _OS X_ + +重新设置窗口客户端的宽高值(例如网页界面). + +### `win.getContentSize()` + +返回一个数组,它包含了窗口客户端的宽,高. + +### `win.setMinimumSize(width, height)` + +* `width` Integer +* `height` Integer + +设置窗口最小化的宽高值. + +### `win.getMinimumSize()` + +返回一个数组,它包含了窗口最小化的宽,高. + +### `win.setMaximumSize(width, height)` + +* `width` Integer +* `height` Integer + +设置窗口最大化的宽高值. + +### `win.getMaximumSize()` + +返回一个数组,它包含了窗口最大化的宽,高. + +### `win.setResizable(resizable)` + +* `resizable` Boolean + +设置窗口是否可以被用户改变size. + +### `win.isResizable()` + +返回窗口是否可以被用户改变size的状态. + +### `win.setMovable(movable)` _OS X_ _Windows_ + +* `movable` Boolean + +设置窗口是否可以被用户拖动. Linux 无效. + +### `win.isMovable()` _OS X_ _Windows_ + +返回窗口是否可以被用户拖动的状态. Linux 总是返回 `true`. + +### `win.setMinimizable(minimizable)` _OS X_ _Windows_ + +* `minimizable` Boolean + +设置窗口是否可以最小化. Linux 无效. + +### `win.isMinimizable()` _OS X_ _Windows_ + +返回窗口是否可以最小化的状态. Linux 总是返回 `true`. + +### `win.setMaximizable(maximizable)` _OS X_ _Windows_ + +* `maximizable` Boolean + +设置窗口是否可以最大化. Linux 无效. + +### `win.isMaximizable()` _OS X_ _Windows_ + +返回窗口是否可以最大化的状态. Linux 总是返回 `true`. + +### `win.setFullScreenable(fullscreenable)` + +* `fullscreenable` Boolean + +设置点击最大化按钮是否可以全屏或最大化窗口. + +### `win.isFullScreenable()` + +返回点击最大化按钮是否可以全屏或最大化窗口的状态. + +### `win.setClosable(closable)` _OS X_ _Windows_ + +* `closable` Boolean + +设置窗口是否可以人为关闭. Linux 无效. + +### `win.isClosable()` _OS X_ _Windows_ + +返回窗口是否可以人为关闭的状态. Linux 总是返回 `true`. + +### `win.setAlwaysOnTop(flag)` + +* `flag` Boolean + +是否设置这个窗口始终在其他窗口之上.设置之后,这个窗口仍然是一个普通的窗口,不是一个不可以聚焦的工具箱窗口. + +### `win.isAlwaysOnTop()` + +返回当前窗口是否始终在其它窗口之前的状态. + +### `win.center()` + +窗口居中. + +### `win.setPosition(x, y[, animate])` + +* `x` Integer +* `y` Integer +* `animate` Boolean (可选) _OS X_ + +移动窗口到对应的 `x` and `y` 坐标. + +### `win.getPosition()` + +返回一个包含当前窗口位置的数组. + +### `win.setTitle(title)` + +* `title` String + +改变原窗口的title. + +### `win.getTitle()` + +返回原窗口的title. + +**注意:** 界面title可能和窗口title不相同. + +### `win.flashFrame(flag)` + +* `flag` Boolean + +开始或停止显示窗口来获得用户的关注. + +### `win.setSkipTaskbar(skip)` + +* `skip` Boolean + +让窗口不在任务栏中显示. + +### `win.setKiosk(flag)` + +* `flag` Boolean + +进入或离开 kiosk 模式. + +### `win.isKiosk()` + +返回是否进入或离开 kiosk 模式的状态. + +### `win.getNativeWindowHandle()` + +以 `Buffer` 形式返回这个具体平台的窗口的句柄. + +windows上句柄类型为 `HWND` ,OS X `NSView*` , Linux `Window`. + +### `win.hookWindowMessage(message, callback)` _Windows_ + +* `message` Integer +* `callback` Function + +拦截windows 消息,在 WndProc 接收到消息时触发 `callback`函数. + +### `win.isWindowMessageHooked(message)` _Windows_ + +* `message` Integer + +返回 `true` or `false` 来代表是否拦截到消息. + +### `win.unhookWindowMessage(message)` _Windows_ + +* `message` Integer + +不拦截窗口消息. + +### `win.unhookAllWindowMessages()` _Windows_ + +窗口消息全部不拦截. + +### `win.setRepresentedFilename(filename)` _OS X_ + +* `filename` String + +设置窗口当前文件路径,并且将这个文件的图标放在窗口标题栏上. + +### `win.getRepresentedFilename()` _OS X_ + +获取窗口当前文件路径. + +### `win.setDocumentEdited(edited)` _OS X_ + +* `edited` Boolean + +明确指出窗口文档是否可以编辑,如果可以编辑则将标题栏的图标变成灰色. + +### `win.isDocumentEdited()` _OS X_ + +返回当前窗口文档是否可编辑状态. + +### `win.focusOnWebView()` + +### `win.blurWebView()` + +### `win.capturePage([rect, ]callback)` + +* `rect` Object (可选) - 捕获Page位置 + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer +* `callback` Function + +捕获 `rect` 中的page 的快照.完成后将调用回调函数 `callback` 并返回 `image` . `image` 是存储了快照信息的[NativeImage](native-image.md)实例.如果不设置 `rect` 则将捕获所有可见page. + +### `win.print([options])` + +类似 `webContents.print([options])` + +### `win.printToPDF(options, callback)` + +类似 `webContents.printToPDF(options, callback)` + +### `win.loadURL(url[, options])` + +类似 `webContents.loadURL(url[, options])`. + +### `win.reload()` + +类似 `webContents.reload`. + +### `win.setMenu(menu)` _Linux_ _Windows_ + +* `menu` Menu + +设置菜单栏的 `menu` ,设置它为 `null` 则表示不设置菜单栏. + +### `win.setProgressBar(progress)` + +* `progress` Double + +在进度条中设置进度值,有效范围 [0, 1.0]. + +当进度小于0时则不显示进度; +当进度大于0时显示结果不确定. + +在libux上,只支持Unity桌面环境,需要指明 `*.desktop` 文件并且在 `package.json` 中添加文件名字.默认它为 `app.getName().desktop`. + +### `win.setOverlayIcon(overlay, description)` _Windows 7+_ + +* `overlay` [NativeImage](native-image.md) - the icon to display on the bottom +right corner of the taskbar icon. If this parameter is `null`, the overlay is +cleared +* `description` String - a description that will be provided to Accessibility +screen readers + +Sets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to convey some +sort of application status or to passively notify the user. + +### `win.setHasShadow(hasShadow)` _OS X_ + +* `hasShadow` (Boolean) + +设置窗口是否应该有阴影.在Windows和Linux系统无效. + +### `win.hasShadow()` _OS X_ + +返回设置窗口是否有阴影的状态.在Windows和Linux系统始终返回 +`true`. + +### `win.setThumbarButtons(buttons)` _Windows 7+_ + +* `buttons` Array + +在窗口的任务栏button布局出为缩略图添加一个有特殊button的缩略图工具栏. 返回一个 `Boolean` 对象来指示是否成功添加这个缩略图工具栏. + +因为空间有限,缩略图工具栏上的 button 数量不应该超过7个.一旦设置了,由于平台限制,就不能移动它了.但是你可使用一个空数组来调用api来清除 buttons . + +所有 `buttons` 是一个 `Button` 对象数组: + +* `Button` Object + * `icon` [NativeImage](native-image.md) - 在工具栏上显示的图标. + * `click` Function + * `tooltip` String (可选) - tooltip 文字. + * `flags` Array (可选) - 控制button的状态和行为. 默认它是 `['enabled']`. + +`flags` 是一个数组,它包含下面这些 `String`s: + +* `enabled` - button 为激活状态并且开放给用户. +* `disabled` -button 不可用. 目前它有一个可见的状态来表示它不会响应你的行为. +* `dismissonclick` - 点击button,这个缩略窗口直接关闭. +* `nobackground` - 不绘制边框,仅仅使用图像. +* `hidden` - button 对用户不可见. +* `noninteractive` - button 可用但是不可响应; 也不显示按下的状态. 它的值意味着这是一个在通知单使用 button 的实例. + +### `win.showDefinitionForSelection()` _OS X_ + +在界面查找选中文字时显示弹出字典. + +### `win.setAutoHideMenuBar(hide)` + +* `hide` Boolean + +设置窗口的菜单栏是否可以自动隐藏. 一旦设置了,只有当用户按下 `Alt` 键时则显示. + +如果菜单栏已经可见,调用 `setAutoHideMenuBar(true)` 则不会立刻隐藏. + +### `win.isMenuBarAutoHide()` + +返回窗口的菜单栏是否可以自动隐藏的状态. + +### `win.setMenuBarVisibility(visible)` + +* `visible` Boolean + +设置菜单栏是否可见.如果菜单栏自动隐藏,用户仍然可以按下 `Alt` 键来显示. + +### `win.isMenuBarVisible()` + +返回菜单栏是否可见的状态. + +### `win.setVisibleOnAllWorkspaces(visible)` + +* `visible` Boolean + +设置窗口是否在所有地方都可见. + +**注意:** 这个api 在windows无效. + +### `win.isVisibleOnAllWorkspaces()` + +返回窗口是否在所有地方都可见的状态. + +**注意:** 在 windows上始终返回 false. + +### `win.setIgnoreMouseEvents(ignore)` _OS X_ + +* `ignore` Boolean + +忽略窗口的所有鼠标事件. + +[blink-feature-string]: https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/platform/RuntimeEnabledFeatures.cpp&sq=package:chromium&type=cs&l=527 \ No newline at end of file From ee61ab2d260f84775698dcb7cdbf5308bc520dbb Mon Sep 17 00:00:00 2001 From: Arek Sredzki Date: Mon, 7 Mar 2016 01:26:36 -0800 Subject: [PATCH 438/688] Cache browser visibility state & emit visibilitychange event on change Fixes #3788 --- lib/browser/api/browser-window.js | 12 ++++++++++++ lib/renderer/api/ipc-renderer.js | 2 +- lib/renderer/inspector.js | 2 +- lib/renderer/override.js | 31 +++++++++++++++++++++---------- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index a9649f853d7..b3e27c58056 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -88,6 +88,18 @@ BrowserWindow.prototype._init = function() { }; })(this)); + // Evented visibilityState changes + this.on('minimize', (function(_this) { + return function() { + return _this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', false); + }; + })(this)); + this.on('restore', (function(_this) { + return function() { + return _this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', true); + }; + })(this)); + // Notify the creation of the window. app.emit('browser-window-created', {}, this); diff --git a/lib/renderer/api/ipc-renderer.js b/lib/renderer/api/ipc-renderer.js index dd614103cfa..e946dc7a4c0 100644 --- a/lib/renderer/api/ipc-renderer.js +++ b/lib/renderer/api/ipc-renderer.js @@ -3,7 +3,7 @@ const v8Util = process.atomBinding('v8_util'); var slice = [].slice; -// Created by init.coffee. +// Created by init.js. const ipcRenderer = v8Util.getHiddenValue(global, 'ipc'); ipcRenderer.send = function() { diff --git a/lib/renderer/inspector.js b/lib/renderer/inspector.js index edec3074b95..d1473c7d1be 100644 --- a/lib/renderer/inspector.js +++ b/lib/renderer/inspector.js @@ -3,7 +3,7 @@ window.onload = function() { InspectorFrontendHost.showContextMenuAtPoint = createMenu; // Use dialog API to override file chooser dialog. - return WebInspector.createFileSelectorElement = createFileSelectorElement; + return (WebInspector.createFileSelectorElement = createFileSelectorElement); }; var convertToMenuTemplate = function(items) { diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 6ff1e80785d..6a025af4ed1 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -3,6 +3,13 @@ const remote = require('electron').remote; var slice = [].slice; +// Cache browser window visibility +var _isVisible = (function() { + var currentWindow; + currentWindow = remote.getCurrentWindow(); + return currentWindow.isMinimized() || !currentWindow.isVisible(); +})(); + // Helper function to resolve relative url. var a = window.top.document.createElement('a'); @@ -30,7 +37,7 @@ var BrowserWindowProxy = (function() { ipcRenderer.once("ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_" + this.guestId, (function(_this) { return function() { BrowserWindowProxy.remove(_this.guestId); - return _this.closed = true; + return (_this.closed = true); }; })(this)); } @@ -87,7 +94,9 @@ window.open = function(url, frameName, features) { ref1 = features.split(/,\s*/); for (i = 0, len = ref1.length; i < len; i++) { feature = ref1[i]; - ref2 = feature.split(/\s*=/), name = ref2[0], value = ref2[1]; + ref2 = feature.split(/\s*=/); + name = ref2[0]; + value = ref2[1]; options[name] = value === 'yes' || value === '1' ? true : value === 'no' || value === '0' ? false : value; } if (options.left) { @@ -168,6 +177,12 @@ if (process.openerId != null) { window.opener = BrowserWindowProxy.getOrCreate(process.openerId); } +ipcRenderer.on('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', function (event, isVisible) { + _isVisible = isVisible; + + document.dispatchEvent(new Event('visibilitychange')); +}); + ipcRenderer.on('ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', function(event, sourceId, message, sourceOrigin) { // Manually dispatch event instead of using postMessage because we also need to // set event.source. @@ -212,19 +227,15 @@ Object.defineProperty(window.history, 'length', { // Make document.hidden and document.visibilityState return the correct value. Object.defineProperty(document, 'hidden', { - get: function() { - var currentWindow; - currentWindow = remote.getCurrentWindow(); - return currentWindow.isMinimized() || !currentWindow.isVisible(); - } + get: !_isVisible }); Object.defineProperty(document, 'visibilityState', { get: function() { - if (document.hidden) { - return "hidden"; - } else { + if (_isVisible) { return "visible"; + } else { + return "hidden"; } } }); From c1267b232072c48b21b55908d5bd699be954b4fa Mon Sep 17 00:00:00 2001 From: Arek Sredzki Date: Tue, 8 Mar 2016 09:36:41 -0800 Subject: [PATCH 439/688] Added 'show' & 'hide' events to browser-window, fixed visibilitychange event in renderer --- atom/browser/api/atom_api_window.cc | 8 +++ atom/browser/api/atom_api_window.h | 2 + atom/browser/native_window.h | 2 + atom/browser/native_window_observer.h | 6 ++ atom/browser/native_window_views.cc | 6 ++ docs/api/browser-window.md | 8 +++ lib/browser/api/browser-window.js | 92 ++++++++++++--------------- lib/renderer/override.js | 24 +++++-- 8 files changed, 88 insertions(+), 60 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index ea1d95b79ca..2975980cabe 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -191,6 +191,14 @@ void Window::OnWindowFocus() { Emit("focus"); } +void Window::OnWindowShow() { + Emit("show"); +} + +void Window::OnWindowHide() { + Emit("hide"); +} + void Window::OnWindowMaximize() { Emit("maximize"); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 641124f4dfd..d814a48c983 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -58,6 +58,8 @@ class Window : public mate::TrackableObject, void OnWindowClosed() override; void OnWindowBlur() override; void OnWindowFocus() override; + void OnWindowShow() override; + void OnWindowHide() override; void OnWindowMaximize() override; void OnWindowUnmaximize() override; void OnWindowMinimize() override; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 09fae6c6bcf..a215b9eb4c1 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -210,6 +210,8 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowClosed(); void NotifyWindowBlur(); void NotifyWindowFocus(); + void NotifyWindowShow(); + void NotifyWindowHide(); void NotifyWindowMaximize(); void NotifyWindowUnmaximize(); void NotifyWindowMinimize(); diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 4af181085a0..e9dbff4292e 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -42,6 +42,12 @@ class NativeWindowObserver { // Called when window gains focus. virtual void OnWindowFocus() {} + // Called when window is shown. + virtual void OnWindowShow() {} + + // Called when window is hidden. + virtual void OnWindowHide() {} + // Called when window state changed. virtual void OnWindowMaximize() {} virtual void OnWindowUnmaximize() {} diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 93eb7b88d89..15f2046364b 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -302,6 +302,8 @@ bool NativeWindowViews::IsFocused() { void NativeWindowViews::Show() { window_->native_widget_private()->ShowWithWindowState(GetRestoredState()); + NotifyWindowShow(); + #if defined(USE_X11) if (global_menu_bar_) global_menu_bar_->OnWindowMapped(); @@ -311,6 +313,8 @@ void NativeWindowViews::Show() { void NativeWindowViews::ShowInactive() { window_->ShowInactive(); + NotifyWindowShow(); + #if defined(USE_X11) if (global_menu_bar_) global_menu_bar_->OnWindowMapped(); @@ -320,6 +324,8 @@ void NativeWindowViews::ShowInactive() { void NativeWindowViews::Hide() { window_->Hide(); + NotifyWindowHide(); + #if defined(USE_X11) if (global_menu_bar_) global_menu_bar_->OnWindowUnmapped(); diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 6e1bc992539..0595fbc7056 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -245,6 +245,14 @@ Emitted when the window loses focus. Emitted when the window gains focus. +### Event: 'show' + +Emitted when the window is shown. + +### Event: 'hide' + +Emitted when the window is hidden. + ### Event: 'maximize' Emitted when window is maximized. diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index b3e27c58056..139659c2ea2 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -20,7 +20,7 @@ BrowserWindow.prototype._init = function() { } // Make new windows requested by links behave like "window.open" - this.webContents.on('-new-window', function(event, url, frameName) { + this.webContents.on('-new-window', (event, url, frameName) => { var options; options = { show: true, @@ -32,27 +32,21 @@ BrowserWindow.prototype._init = function() { // window.resizeTo(...) // window.moveTo(...) - this.webContents.on('move', (function(_this) { - return function(event, size) { - return _this.setBounds(size); - }; - })(this)); + this.webContents.on('move', (event, title) => { + return this.setBounds(size); + }); // Hide the auto-hide menu when webContents is focused. - this.webContents.on('activate', (function(_this) { - return function() { - if (process.platform !== 'darwin' && _this.isMenuBarAutoHide() && _this.isMenuBarVisible()) { - return _this.setMenuBarVisibility(false); - } - }; - })(this)); + this.webContents.on('activate', () => { + if (process.platform !== 'darwin' && this.isMenuBarAutoHide() && this.isMenuBarVisible()) { + return this.setMenuBarVisibility(false); + } + }); // Forward the crashed event. - this.webContents.on('crashed', (function(_this) { - return function() { - return _this.emit('crashed'); - }; - })(this)); + this.webContents.on('crashed', () => { + return this.emit('crashed'); + }); // Change window title to page title. this.webContents.on('page-title-updated', (event, title) => { @@ -77,48 +71,40 @@ BrowserWindow.prototype._init = function() { }); // Redirect focus/blur event to app instance too. - this.on('blur', (function(_this) { - return function(event) { - return app.emit('browser-window-blur', event, _this); - }; - })(this)); - this.on('focus', (function(_this) { - return function(event) { - return app.emit('browser-window-focus', event, _this); - }; - })(this)); + this.on('blur', (event) => { + return app.emit('browser-window-blur', event, this); + }); + this.on('focus', (event) => { + return app.emit('browser-window-focus', event, this); + }); // Evented visibilityState changes - this.on('minimize', (function(_this) { - return function() { - return _this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', false); - }; - })(this)); - this.on('restore', (function(_this) { - return function() { - return _this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', true); - }; - })(this)); + this.on('show', () => { + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', true, this.isMinimized()); + }); + this.on('hide', () => { + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', false, this.isMinimized()); + }); + this.on('minimize', () => { + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), true); + }); + this.on('restore', () => { + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), false); + }); // Notify the creation of the window. app.emit('browser-window-created', {}, this); // Be compatible with old APIs. - this.webContents.on('devtools-focused', (function(_this) { - return function() { - return _this.emit('devtools-focused'); - }; - })(this)); - this.webContents.on('devtools-opened', (function(_this) { - return function() { - return _this.emit('devtools-opened'); - }; - })(this)); - this.webContents.on('devtools-closed', (function(_this) { - return function() { - return _this.emit('devtools-closed'); - }; - })(this)); + this.webContents.on('devtools-focused', () => { + return this.emit('devtools-focused'); + }); + this.webContents.on('devtools-opened', () => { + return this.emit('devtools-opened'); + }); + this.webContents.on('devtools-closed', () => { + return this.emit('devtools-closed'); + }); return Object.defineProperty(this, 'devToolsWebContents', { enumerable: true, configurable: false, diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 6a025af4ed1..2b0e48b3dd3 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -4,10 +4,13 @@ const remote = require('electron').remote; var slice = [].slice; // Cache browser window visibility -var _isVisible = (function() { +var _isVisible = true; +var _isMinimized = false; +(function() { var currentWindow; currentWindow = remote.getCurrentWindow(); - return currentWindow.isMinimized() || !currentWindow.isVisible(); + _isVisible = currentWindow.isVisible(); + _isMinimized = currentWindow.isMinimized(); })(); // Helper function to resolve relative url. @@ -177,10 +180,15 @@ if (process.openerId != null) { window.opener = BrowserWindowProxy.getOrCreate(process.openerId); } -ipcRenderer.on('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', function (event, isVisible) { - _isVisible = isVisible; +ipcRenderer.on('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', function (event, isVisible, isMinimized) { + var hasChanged = _isVisible != isVisible || _isMinimized != isMinimized; + + if (hasChanged) { + _isVisible = isVisible; + _isMinimized = isMinimized; - document.dispatchEvent(new Event('visibilitychange')); + document.dispatchEvent(new Event('visibilitychange')); + } }); ipcRenderer.on('ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', function(event, sourceId, message, sourceOrigin) { @@ -227,12 +235,14 @@ Object.defineProperty(window.history, 'length', { // Make document.hidden and document.visibilityState return the correct value. Object.defineProperty(document, 'hidden', { - get: !_isVisible + get: function () { + return _isMinimized || !_isVisible; + } }); Object.defineProperty(document, 'visibilityState', { get: function() { - if (_isVisible) { + if (_isVisible && !_isMinimized) { return "visible"; } else { return "hidden"; From fcc1f4d7ed1fd0978e68f72c405c8ee5f179e519 Mon Sep 17 00:00:00 2001 From: Arek Sredzki Date: Tue, 8 Mar 2016 11:11:17 -0800 Subject: [PATCH 440/688] Finalized browser-window show & hide events, added tests & fixed os x implementation --- atom/browser/native_window.cc | 8 +++++ atom/browser/native_window_mac.mm | 15 ++++++++++ lib/browser/api/browser-window.js | 10 +++---- spec/api-browser-window-spec.js | 49 ++++++++++++++++++++++++++++--- 4 files changed, 73 insertions(+), 9 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 98b3d725a9a..56cfdea54c5 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -428,6 +428,14 @@ void NativeWindow::NotifyWindowFocus() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowFocus()); } +void NativeWindow::NotifyWindowShow() { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowShow()); +} + +void NativeWindow::NotifyWindowHide() { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowHide()); +} + void NativeWindow::NotifyWindowMaximize() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowMaximize()); } diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 6bbd9fd5001..a8f7bc5c168 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -79,6 +79,21 @@ bool ScopedDisableResize::disable_resize_ = false; return self; } +- (void)windowDidChangeOcclusionState:(NSNotification *)notification { + // notification.object is the window that changed its state. + // It's safe to use self.window instead if you don't assign one delegate to many windows + NSWindow *window = notification.object; + + // check occlusion binary flag + if (window.occlusionState & NSWindowOcclusionStateVisible) { + // The app is visible + shell_->NotifyWindowShow(); + } else { + // The app is not visible + shell_->NotifyWindowHide(); + } +} + - (void)windowDidBecomeMain:(NSNotification*)notification { content::WebContents* web_contents = shell_->web_contents(); if (!web_contents) diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 139659c2ea2..1d2f665e5d0 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -32,7 +32,7 @@ BrowserWindow.prototype._init = function() { // window.resizeTo(...) // window.moveTo(...) - this.webContents.on('move', (event, title) => { + this.webContents.on('move', (event, size) => { return this.setBounds(size); }); @@ -80,16 +80,16 @@ BrowserWindow.prototype._init = function() { // Evented visibilityState changes this.on('show', () => { - return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', true, this.isMinimized()); + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); }); this.on('hide', () => { - return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', false, this.isMinimized()); + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); }); this.on('minimize', () => { - return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), true); + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); }); this.on('restore', () => { - return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), false); + return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); }); // Notify the creation of the window. diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 731ae1cb86f..9a6be6865da 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -120,14 +120,55 @@ describe('browser-window module', function() { }); describe('BrowserWindow.show()', function() { - it('should focus on window', function() { - if (isCI) { - return; - } + if (isCI) { + return; + } + it('should focus on window', function() { w.show(); assert(w.isFocused()); }); + + it('should make the window visible', function() { + w.show(); + assert(w.isVisible()); + }); + + it('emits when window is shown', function(done) { + this.timeout(10000); + w.once('show', function() { + assert.equal(w.isVisible(), true); + done(); + }); + w.show(); + }); + }); + + describe('BrowserWindow.hide()', function() { + if (isCI) { + return; + } + + it('should defocus on window', function() { + w.hide(); + assert(!w.isFocused()); + }); + + it('should make the window not visible', function() { + w.show(); + w.hide(); + assert(!w.isVisible()); + }); + + it('emits when window is hidden', function(done) { + this.timeout(10000); + w.show(); + w.once('hide', function() { + assert.equal(w.isVisible(), false); + done(); + }); + w.hide(); + }); }); describe('BrowserWindow.showInactive()', function() { From 256c2684ee13cea01b064dae3b3d8aeb80a2d4dc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Mar 2016 10:25:12 +0900 Subject: [PATCH 441/688] spec: Do not enter fullscreen in travis on OS X It is too flaky --- spec/webview-spec.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index cd2be69d737..3579415a0b4 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -548,11 +548,10 @@ describe(' tag', function() { }); describe('executeJavaScript', function() { - if (process.env.TRAVIS !== 'true') { - return; - } - it('should support user gesture', function(done) { + if (process.env.TRAVIS !== 'true' || process.platform == 'darwin') + return done(); + var listener = function() { webview.removeEventListener('enter-html-full-screen', listener); done(); From 83809cef0944d0a9590d921c70f38c974b41a551 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Mar 2016 10:47:15 +0900 Subject: [PATCH 442/688] Update to master branch of brightray and libchromiumcontent --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 5077bee89dc..c1f3bb4ecf4 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 5077bee89dc3403982e9a5c59cc0a2218b2d4610 +Subproject commit c1f3bb4ecf4cacb33bf56b9ebd3656a4defbeb64 From d564727583b405fdeec53a320ffdc41bc7ed5c28 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Mar 2016 11:17:02 +0900 Subject: [PATCH 443/688] spec: Increase timeout for executeJavaScript --- spec/webview-spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 3579415a0b4..ba3913e2e47 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -568,6 +568,7 @@ describe(' tag', function() { }); it('can return the result of the executed script', function(done) { + this.timeout(50000); var listener = function() { var jsScript = "'4'+2"; webview.executeJavaScript(jsScript, false, function(result) { From d25d1f3f8b06f081e30f4ed3ce2cfd418e7e97e2 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Fri, 11 Mar 2016 11:53:04 +0800 Subject: [PATCH 444/688] add content-tracing && update browser-window --- docs-translations/zh-CN/api/browser-window.md | 50 ++++--- .../zh-CN/api/content-tracing.md | 129 ++++++++++++++++++ 2 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 docs-translations/zh-CN/api/content-tracing.md diff --git a/docs-translations/zh-CN/api/browser-window.md b/docs-translations/zh-CN/api/browser-window.md index 66ae76cff91..5ed0069caf4 100644 --- a/docs-translations/zh-CN/api/browser-window.md +++ b/docs-translations/zh-CN/api/browser-window.md @@ -258,11 +258,11 @@ someWindow.on('app-command', function(e, cmd) { ### `BrowserWindow.getAllWindows()` -返回一个所有已经打开了的窗口的对象数组. +返回一个所有已经打开了窗口的对象数组. ### `BrowserWindow.getFocusedWindow()` -返回应用当前聚焦窗口,如果没有就返回 `null`. +返回应用当前获得焦点窗口,如果没有就返回 `null`. ### `BrowserWindow.fromWebContents(webContents)` @@ -325,19 +325,19 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.focus()` -聚焦窗口. +窗口获得焦点. ### `win.isFocused()` -返回 boolean, 窗口是否聚焦. +返回 boolean, 窗口是否获得焦点. ### `win.show()` -展示并且聚焦窗口. +展示并且使窗口获得焦点. ### `win.showInactive()` -展示窗口但是不聚焦. +展示窗口但是不获得焦点. ### `win.hide()` @@ -462,7 +462,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.isResizable()` -返回窗口是否可以被用户改变size的状态. +返回 boolean,窗口是否可以被用户改变size. ### `win.setMovable(movable)` _OS X_ _Windows_ @@ -472,7 +472,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.isMovable()` _OS X_ _Windows_ -返回窗口是否可以被用户拖动的状态. Linux 总是返回 `true`. +返回 boolean,窗口是否可以被用户拖动. Linux 总是返回 `true`. ### `win.setMinimizable(minimizable)` _OS X_ _Windows_ @@ -482,7 +482,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.isMinimizable()` _OS X_ _Windows_ -返回窗口是否可以最小化的状态. Linux 总是返回 `true`. +返回 boolean,窗口是否可以最小化. Linux 总是返回 `true`. ### `win.setMaximizable(maximizable)` _OS X_ _Windows_ @@ -492,7 +492,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.isMaximizable()` _OS X_ _Windows_ -返回窗口是否可以最大化的状态. Linux 总是返回 `true`. +返回 boolean,窗口是否可以最大化. Linux 总是返回 `true`. ### `win.setFullScreenable(fullscreenable)` @@ -502,7 +502,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.isFullScreenable()` -返回点击最大化按钮是否可以全屏或最大化窗口的状态. +返回 boolean,点击最大化按钮是否可以全屏或最大化窗口. ### `win.setClosable(closable)` _OS X_ _Windows_ @@ -512,17 +512,17 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.isClosable()` _OS X_ _Windows_ -返回窗口是否可以人为关闭的状态. Linux 总是返回 `true`. +返回 boolean,窗口是否可以人为关闭. Linux 总是返回 `true`. ### `win.setAlwaysOnTop(flag)` * `flag` Boolean -是否设置这个窗口始终在其他窗口之上.设置之后,这个窗口仍然是一个普通的窗口,不是一个不可以聚焦的工具箱窗口. +是否设置这个窗口始终在其他窗口之上.设置之后,这个窗口仍然是一个普通的窗口,不是一个不可以获得焦点的工具箱窗口. ### `win.isAlwaysOnTop()` -返回当前窗口是否始终在其它窗口之前的状态. +返回 boolean,当前窗口是否始终在其它窗口之前. ### `win.center()` @@ -572,7 +572,7 @@ var win = new BrowserWindow({ width: 800, height: 600 }); ### `win.isKiosk()` -返回是否进入或离开 kiosk 模式的状态. +返回 boolean,是否进入或离开 kiosk 模式. ### `win.getNativeWindowHandle()` @@ -621,7 +621,7 @@ windows上句柄类型为 `HWND` ,OS X `NSView*` , Linux `Window`. ### `win.isDocumentEdited()` _OS X_ -返回当前窗口文档是否可编辑状态. +返回 boolean,当前窗口文档是否可编辑. ### `win.focusOnWebView()` @@ -673,14 +673,10 @@ windows上句柄类型为 `HWND` ,OS X `NSView*` , Linux `Window`. ### `win.setOverlayIcon(overlay, description)` _Windows 7+_ -* `overlay` [NativeImage](native-image.md) - the icon to display on the bottom -right corner of the taskbar icon. If this parameter is `null`, the overlay is -cleared -* `description` String - a description that will be provided to Accessibility -screen readers +* `overlay` [NativeImage](native-image.md) - 在底部任务栏右边显示图标. +* `description` String - 描述. -Sets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to convey some -sort of application status or to passively notify the user. +向当前任务栏添加一个 16 x 16 像素的图标,通常用来覆盖一些应用的状态,或者直接来提示用户. ### `win.setHasShadow(hasShadow)` _OS X_ @@ -690,7 +686,7 @@ sort of application status or to passively notify the user. ### `win.hasShadow()` _OS X_ -返回设置窗口是否有阴影的状态.在Windows和Linux系统始终返回 +返回 boolean,设置窗口是否有阴影.在Windows和Linux系统始终返回 `true`. ### `win.setThumbarButtons(buttons)` _Windows 7+_ @@ -732,7 +728,7 @@ sort of application status or to passively notify the user. ### `win.isMenuBarAutoHide()` -返回窗口的菜单栏是否可以自动隐藏的状态. +返回 boolean,窗口的菜单栏是否可以自动隐藏. ### `win.setMenuBarVisibility(visible)` @@ -742,7 +738,7 @@ sort of application status or to passively notify the user. ### `win.isMenuBarVisible()` -返回菜单栏是否可见的状态. +返回 boolean,菜单栏是否可见. ### `win.setVisibleOnAllWorkspaces(visible)` @@ -754,7 +750,7 @@ sort of application status or to passively notify the user. ### `win.isVisibleOnAllWorkspaces()` -返回窗口是否在所有地方都可见的状态. +返回 boolean,窗口是否在所有地方都可见. **注意:** 在 windows上始终返回 false. diff --git a/docs-translations/zh-CN/api/content-tracing.md b/docs-translations/zh-CN/api/content-tracing.md new file mode 100644 index 00000000000..fd1edc9bc2f --- /dev/null +++ b/docs-translations/zh-CN/api/content-tracing.md @@ -0,0 +1,129 @@ +# contentTracing + +`content-tracing` 模块是用来收集由底层的Chromium content 模块 产生的搜索数据. 这个模块不具备web接口,所有需要我们在chrome浏览器中添加 `chrome://tracing/` 来加载生成文件从而查看结果. + +```javascript +const contentTracing = require('electron').contentTracing; + +const options = { + categoryFilter: '*', + traceOptions: 'record-until-full,enable-sampling' +} + +contentTracing.startRecording(options, function() { + console.log('Tracing started'); + + setTimeout(function() { + contentTracing.stopRecording('', function(path) { + console.log('Tracing data recorded to ' + path); + }); + }, 5000); +}); +``` + +## 方法 + + `content-tracing` 模块的方法如下: + +### `contentTracing.getCategories(callback)` + +* `callback` Function + +获得一组分类组. 分类组可以更改为新的代码路径。 + +一旦所有的子进程都接受到了`getCategories`方法请求, 分类组将调用 `callback`. + +### `contentTracing.startRecording(options, callback)` + +* `options` Object + * `categoryFilter` String + * `traceOptions` String +* `callback` Function + +开始向所有进程进行记录.(recording) + +一旦收到可以开始记录的请求,记录将会立马启动并且在子进程是异步记录听的. 当所有的子进程都收到 `startRecording` 请求的时候,`callback` 将会被调用. + +`categoryFilter`是一个过滤器,它用来控制那些分类组应该被用来查找.过滤器应当有一个可选的 `-` 前缀来排除匹配的分类组.不允许同一个列表既是包含又是排斥. + +例子: + +* `test_MyTest*`, +* `test_MyTest*,test_OtherStuff`, +* `"-excluded_category1,-excluded_category2` + +`traceOptions` 控制着哪种查找应该被启动,这是一个用逗号分隔的列表.可用参数如下: + +* `record-until-full` +* `record-continuously` +* `trace-to-console` +* `enable-sampling` +* `enable-systrace` + +前3个参数是来查找记录模块,并且以后都互斥.如果在`traceOptions` 中超过一个跟踪 +记录模式,那最后一个的优先级最高.如果没有指明跟踪 +记录模式,那么它默认为 `record-until-full`. + +在 `traceOptions` 中的参数被解析应用之前,查找参数初始化默认为 (`record_mode` 设置为 +`record-until-full`, `enable_sampling` 和 `enable_systrace` 设置为 `false`). + +### `contentTracing.stopRecording(resultFilePath, callback)` + +* `resultFilePath` String +* `callback` Function + +停止对所有子进程的记录. + +子进程通常缓存查找数据,并且仅仅将数据截取和发送给主进程.这有利于在通过 IPC 发送查找数据之前减小查找时的运行开销,这样做很有价值.因此,发送查找数据,我们应当异步通知所有子进程来截取任何待查找的数据. + +一旦所有子进程接收到了 `stopRecording` 请求,将调用 `callback` ,并且返回一个包含查找数据的文件. + +如果 `resultFilePath` 不为空,那么将把查找数据写入其中,否则写入一个临时文件.实际文件路径如果不为空,则将调用 `callback` . + +### `contentTracing.startMonitoring(options, callback)` + +* `options` Object + * `categoryFilter` String + * `traceOptions` String +* `callback` Function + +开始向所有进程进行监听.(monitoring) + +一旦收到可以开始监听的请求,记录将会立马启动并且在子进程是异步记监听的. 当所有的子进程都收到 `startMonitoring` 请求的时候,`callback` 将会被调用. + +### `contentTracing.stopMonitoring(callback)` + +* `callback` Function + +停止对所有子进程的监听. + +一旦所有子进程接收到了 `stopMonitoring` 请求,将调用 `callback` . + +### `contentTracing.captureMonitoringSnapshot(resultFilePath, callback)` + +* `resultFilePath` String +* `callback` Function + +获取当前监听的查找数据. + +子进程通常缓存查找数据,并且仅仅将数据截取和发送给主进程.因为如果直接通过 IPC 来发送查找数据的代价昂贵,我们宁愿避免不必要的查找运行开销.因此,为了停止查找,我们应当异步通知所有子进程来截取任何待查找的数据. + +一旦所有子进程接收到了 `captureMonitoringSnapshot` 请求,将调用 `callback` ,并且返回一个包含查找数据的文件. + +### `contentTracing.getTraceBufferUsage(callback)` + +* `callback` Function + +通过查找 buffer 进程来获取百分比最大使用量.当确定了TraceBufferUsage 的值确定的时候,就调用 `callback` . + +### `contentTracing.setWatchEvent(categoryName, eventName, callback)` + +* `categoryName` String +* `eventName` String +* `callback` Function + +任意时刻在任何进程上指定事件发生时将调用 `callback` . + +### `contentTracing.cancelWatchEvent()` + +取消 watch 事件. 如果启动查找,这或许会造成 watch 事件的回调函数 出错. \ No newline at end of file From 704b8335aafad69c78d5dc75528133f3b89f36fe Mon Sep 17 00:00:00 2001 From: Max Beatty Date: Thu, 10 Mar 2016 21:45:51 -0800 Subject: [PATCH 445/688] Add blur method to window ref #4724 --- atom/browser/api/atom_api_window.cc | 5 +++++ atom/browser/api/atom_api_window.h | 1 + docs/api/browser-window.md | 4 ++++ spec/api-browser-window-spec.js | 7 +++++++ 4 files changed, 17 insertions(+) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index ea1d95b79ca..fb5f3eddc7f 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -294,6 +294,10 @@ void Window::Focus() { window_->Focus(true); } +void Window::Blur() { + window_->Focus(false); +} + bool Window::IsFocused() { return window_->IsFocused(); } @@ -688,6 +692,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .MakeDestroyable() .SetMethod("close", &Window::Close) .SetMethod("focus", &Window::Focus) + .SetMethod("blur", &Window::Blur) .SetMethod("isFocused", &Window::IsFocused) .SetMethod("show", &Window::Show) .SetMethod("showInactive", &Window::ShowInactive) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 641124f4dfd..c9840900515 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -83,6 +83,7 @@ class Window : public mate::TrackableObject, // APIs for NativeWindow. void Close(); void Focus(); + void Blur(); bool IsFocused(); void Show(); void ShowInactive(); diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 6e1bc992539..b21459659da 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -397,6 +397,10 @@ the [close event](#event-close). Focus on the window. +### `win.blur()` + +Remove focus on the window. + ### `win.isFocused()` Returns a boolean, whether the window is focused. diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 731ae1cb86f..3474a859cf0 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -145,6 +145,13 @@ describe('browser-window module', function() { }); }); + describe('BrowserWindow.blur()', function() { + it('removes focus from window', function() { + w.blur(); + assert(!w.isFocused()); + }); + }); + describe('BrowserWindow.capturePage(rect, callback)', function() { it('calls the callback with a Buffer', function(done) { w.capturePage({ From 328583575d4977dbf90db65b96d2878599f0d7c4 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Fri, 11 Mar 2016 15:09:08 +0800 Subject: [PATCH 446/688] modify again and add dialog.md --- docs-translations/zh-CN/api/browser-window.md | 2 - docs-translations/zh-CN/api/dialog.md | 94 +++++++++++++++++++ docs-translations/zh-CN/api/window-open.md | 4 +- 3 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 docs-translations/zh-CN/api/dialog.md diff --git a/docs-translations/zh-CN/api/browser-window.md b/docs-translations/zh-CN/api/browser-window.md index 5ed0069caf4..6e486406d63 100644 --- a/docs-translations/zh-CN/api/browser-window.md +++ b/docs-translations/zh-CN/api/browser-window.md @@ -197,12 +197,10 @@ window.onbeforeunload = function(e) { ### Event: 'restore' 在窗口从最小化恢复的时候触发. -Emitted when the window is restored from minimized state. ### Event: 'resize' 在窗口size改变的时候触发. -Emitted when the window is getting resized. ### Event: 'move' diff --git a/docs-translations/zh-CN/api/dialog.md b/docs-translations/zh-CN/api/dialog.md new file mode 100644 index 00000000000..3e77eeaa2a5 --- /dev/null +++ b/docs-translations/zh-CN/api/dialog.md @@ -0,0 +1,94 @@ +# dialog + +`dialog` 模块提供了api来展示原生的系统对话框,例如打开文件框,alert框,所以web应用可以给用户带来跟系统应用相同的体验. + +对话框例子,展示了选择文件和目录: + +```javascript +var win = ...; // BrowserWindow in which to show the dialog +const dialog = require('electron').dialog; +console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]})); +``` + +**OS X 上的注意事项**: 如果你想像sheets一样展示对话框,只需要在`browserWindow` 参数中提供一个 `BrowserWindow` 的引用对象. + +## 方法 + +`dialog` 模块有以下方法: + +### `dialog.showOpenDialog([browserWindow, ]options[, callback])` + +* `browserWindow` BrowserWindow (可选) +* `options` Object + * `title` String + * `defaultPath` String + * `filters` Array + * `properties` Array - 包含了对话框的特性值, 可以包含 `openFile`, `openDirectory`, `multiSelections` and + `createDirectory` +* `callback` Function (可选) + +成功使用这个方法的话,就返回一个可供用户选择的文件路径数组,失败返回 `undefined`. + +`filters` 当需要限定用户的行为的时候,指定一个文件数组给用户展示或选择. 例如: + +```javascript +{ + filters: [ + { name: 'Images', extensions: ['jpg', 'png', 'gif'] }, + { name: 'Movies', extensions: ['mkv', 'avi', 'mp4'] }, + { name: 'Custom File Type', extensions: ['as'] }, + { name: 'All Files', extensions: ['*'] } + ] +} +``` + +`extensions` 数组应当只包含扩展名,不应该包含通配符或'.'号 (例如 +`'png'` 正确,但是 `'.png'` 和 `'*.png'` 不正确). 展示全部文件的话, 使用 +`'*'` 通配符 (不支持其他通配符). + +如果 `callback` 被调用, 将异步调用 API ,并且结果将用过 `callback(filenames)` 展示. + +**注意:** 在 Windows 和 Linux ,一个打开的 dialog 不能既是文件选择框又是目录选择框, 所以如果在这些平台上设置 `properties` 的值为 +`['openFile', 'openDirectory']` , 将展示一个目录选择框. + +### `dialog.showSaveDialog([browserWindow, ]options[, callback])` + +* `browserWindow` BrowserWindow (可选) +* `options` Object + * `title` String + * `defaultPath` String + * `filters` Array +* `callback` Function (可选) + +成功使用这个方法的话,就返回一个可供用户选择的文件路径数组,失败返回 `undefined`. + +`filters` 指定展示一个文件类型数组, 例子 +`dialog.showOpenDialog` . + +如果 `callback` 被调用, 将异步调用 API ,并且结果将用过 `callback(filenames)` 展示. + +### `dialog.showMessageBox([browserWindow, ]options[, callback])` + +* `browserWindow` BrowserWindow (可选) +* `options` Object + * `type` String - 可以是 `"none"`, `"info"`, `"error"`, `"question"` 或 + `"warning"`. 在 Windows, "question" 与 "info" 展示图标相同, 除非你使用 "icon" 参数. + * `buttons` Array - buttons 内容,数组. + * `defaultId` Integer - 在message box 对话框打开的时候,设置默认button选中,值为在 buttons 数组中的button索引. + * `title` String - message box 的标题,一些平台不显示. + * `message` String - message box 内容. + * `detail` String - 额外信息. + * `icon` [NativeImage](native-image.md) + * `cancelId` Integer - 当用户关闭对话框的时候,不是通过点击对话框的button,就返回值.默认值为对应 "cancel" 或 "no" 标签button 的索引值, 或者如果没有这种button,就返回0. 在 OS X 和 Windows 上, "Cancel" button 的索引值将一直是 `cancelId`, 不管之前是不是特别指出的. + * `noLink` Boolean - 在 Windows ,Electron 将尝试识别哪个button 是普通 button (如 "Cancel" 或 "Yes"), 然后再对话框中以链接命令(command links)方式展现其它的 button . 这能让对话框展示得很炫酷.如果你不喜欢这种效果,你可以设置 `noLink` 为 `true`. +* `callback` Function + +展示 message box, 它会阻塞进程,直到 message box 关闭为止.返回点击按钮的索引值. + +如果 `callback` 被调用, 将异步调用 API ,并且结果将用过 `callback(response)` 展示. + +### `dialog.showErrorBox(title, content)` + +展示一个传统的包含错误信息的对话框. + +在 `app` 模块触发 `ready` 事件之前,这个 api 可以被安全调用,通常它被用来在启动的早期阶段报告错误. 在 Linux 上,如果在 `app` 模块触发 `ready` 事件之前调用,message 将会被触发显示stderr,并且没有实际GUI 框显示. \ No newline at end of file diff --git a/docs-translations/zh-CN/api/window-open.md b/docs-translations/zh-CN/api/window-open.md index a8ef042b0e3..069e2c35226 100644 --- a/docs-translations/zh-CN/api/window-open.md +++ b/docs-translations/zh-CN/api/window-open.md @@ -30,7 +30,7 @@ ### `BrowserWindowProxy.blur()` -取消对子窗口的聚焦. +子窗口的失去焦点. ### `BrowserWindowProxy.close()` 强行关闭子窗口,忽略卸载事件. @@ -47,7 +47,7 @@ ### `BrowserWindowProxy.focus()` -聚焦子窗口(让其现实在最前). +子窗口获得焦点(让其显示在最前). ### `BrowserWindowProxy.postMessage(message, targetOrigin)` From fe248ac03f796fbc84be3abbef14de3b3b3de931 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Fri, 11 Mar 2016 16:05:02 +0800 Subject: [PATCH 447/688] add ipc-main first --- docs-translations/zh-CN/api/ipc-main.md | 85 +++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 docs-translations/zh-CN/api/ipc-main.md diff --git a/docs-translations/zh-CN/api/ipc-main.md b/docs-translations/zh-CN/api/ipc-main.md new file mode 100644 index 00000000000..aef9c454a06 --- /dev/null +++ b/docs-translations/zh-CN/api/ipc-main.md @@ -0,0 +1,85 @@ +# ipcMain + +`ipcMain` 模块是类 +[EventEmitter](https://nodejs.org/api/events.html) 的实例.当在主进程中使用它的时候,它控制着由渲染进程(web page)发送过来的异步或同步消息.从渲染进程发送过来的消息将触发事件. + +## 发送消息 + +同样也可以从主进程向渲染进程发送消息,查看更多 [webContents.send][web-contents-send] . + +* 发送消息,事件名为 `channel`. +* 回应同步消息, 你可以设置 `event.returnValue`. +* 回应异步消息, 你可以使用 + `event.sender.send(...)`. + +一个例子,在主进程和渲染进程之间发送和处理消息: + +```javascript +// In main process. +const ipcMain = require('electron').ipcMain; +ipcMain.on('asynchronous-message', function(event, arg) { + console.log(arg); // prints "ping" + event.sender.send('asynchronous-reply', 'pong'); +}); + +ipcMain.on('synchronous-message', function(event, arg) { + console.log(arg); // prints "ping" + event.returnValue = 'pong'; +}); +``` + +```javascript +// In renderer process (web page). +const ipcRenderer = require('electron').ipcRenderer; +console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong" + +ipcRenderer.on('asynchronous-reply', function(event, arg) { + console.log(arg); // prints "pong" +}); +ipcRenderer.send('asynchronous-message', 'ping'); +``` + +## 监听消息 + +`ipcMain` 模块有如下监听事件方法: + +### `ipcMain.on(channel, listener)` + +* `channel` String +* `listener` Function + +监听 `channel`, 当新消息到达,将通过 `listener(event, args...)` 调用 `listener`. + +### `ipcMain.once(channel, listener)` + +* `channel` String +* `listener` Function + +为事件添加一个一次性用的`listener` 函数.这个 `listener` 只有在下次的消息到达 `channel` 时被请求调用,之后就被删除了. + +### `ipcMain.removeListener(channel, listener)` + +* `channel` String +* `listener` Function + +为特定的 `channel` 从监听队列中删除特定的 `listener` 监听者. + +### `ipcMain.removeAllListeners([channel])` + +* `channel` String (可选) + +删除所有监听者,或特指的 `channel` 的所有监听者. + +## 事件对象 + +传递给 `callback` 的 `event` 对象有如下方法: + +### `event.returnValue` + +将此设置为在一个同步消息中返回的值. + +### `event.sender` + +返回发送消息的 `webContents` ,你可以调用 `event.sender.send` 来回复异步消息,更多信息 [webContents.send][web-contents-send]. + +[web-contents-send]: web-contents.md#webcontentssendchannel-arg1-arg2- \ No newline at end of file From 3e04884a578bbc62a1c25b4ebdfbcd76552d7f08 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Fri, 11 Mar 2016 17:25:38 +0800 Subject: [PATCH 448/688] add menu.md first --- docs-translations/zh-CN/api/menu.md | 351 ++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) create mode 100644 docs-translations/zh-CN/api/menu.md diff --git a/docs-translations/zh-CN/api/menu.md b/docs-translations/zh-CN/api/menu.md new file mode 100644 index 00000000000..3a4e7e5c24e --- /dev/null +++ b/docs-translations/zh-CN/api/menu.md @@ -0,0 +1,351 @@ +# 菜单 + +`menu` 类可以用来创建原生菜单,它可用作应用菜单和 +[context 菜单](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/PopupGuide/ContextMenus). + +这个模块是一个主进程的模块,并且可以通过 `remote` 模块给渲染进程调用. + +每个菜单有一个或几个菜单项 [menu items](menu-item.md),并且每个菜单项可以有子菜单. + +下面这个例子是在网页(渲染进程)中通过 [remote](remote.md) 模块动态创建的菜单,并且右键显示: + +```html + + +``` + +例子,在渲染进程中使用模板api创建应用菜单: + +```javascript +var template = [ + { + label: 'Edit', + submenu: [ + { + label: 'Undo', + accelerator: 'CmdOrCtrl+Z', + role: 'undo' + }, + { + label: 'Redo', + accelerator: 'Shift+CmdOrCtrl+Z', + role: 'redo' + }, + { + type: 'separator' + }, + { + label: 'Cut', + accelerator: 'CmdOrCtrl+X', + role: 'cut' + }, + { + label: 'Copy', + accelerator: 'CmdOrCtrl+C', + role: 'copy' + }, + { + label: 'Paste', + accelerator: 'CmdOrCtrl+V', + role: 'paste' + }, + { + label: 'Select All', + accelerator: 'CmdOrCtrl+A', + role: 'selectall' + }, + ] + }, + { + label: 'View', + submenu: [ + { + label: 'Reload', + accelerator: 'CmdOrCtrl+R', + click: function(item, focusedWindow) { + if (focusedWindow) + focusedWindow.reload(); + } + }, + { + label: 'Toggle Full Screen', + accelerator: (function() { + if (process.platform == 'darwin') + return 'Ctrl+Command+F'; + else + return 'F11'; + })(), + click: function(item, focusedWindow) { + if (focusedWindow) + focusedWindow.setFullScreen(!focusedWindow.isFullScreen()); + } + }, + { + label: 'Toggle Developer Tools', + accelerator: (function() { + if (process.platform == 'darwin') + return 'Alt+Command+I'; + else + return 'Ctrl+Shift+I'; + })(), + click: function(item, focusedWindow) { + if (focusedWindow) + focusedWindow.toggleDevTools(); + } + }, + ] + }, + { + label: 'Window', + role: 'window', + submenu: [ + { + label: 'Minimize', + accelerator: 'CmdOrCtrl+M', + role: 'minimize' + }, + { + label: 'Close', + accelerator: 'CmdOrCtrl+W', + role: 'close' + }, + ] + }, + { + label: 'Help', + role: 'help', + submenu: [ + { + label: 'Learn More', + click: function() { require('electron').shell.openExternal('http://electron.atom.io') } + }, + ] + }, +]; + +if (process.platform == 'darwin') { + var name = require('electron').remote.app.getName(); + template.unshift({ + label: name, + submenu: [ + { + label: 'About ' + name, + role: 'about' + }, + { + type: 'separator' + }, + { + label: 'Services', + role: 'services', + submenu: [] + }, + { + type: 'separator' + }, + { + label: 'Hide ' + name, + accelerator: 'Command+H', + role: 'hide' + }, + { + label: 'Hide Others', + accelerator: 'Command+Alt+H', + role: 'hideothers' + }, + { + label: 'Show All', + role: 'unhide' + }, + { + type: 'separator' + }, + { + label: 'Quit', + accelerator: 'Command+Q', + click: function() { app.quit(); } + }, + ] + }); + // Window menu. + template[3].submenu.push( + { + type: 'separator' + }, + { + label: 'Bring All to Front', + role: 'front' + } + ); +} + +var menu = Menu.buildFromTemplate(template); +Menu.setApplicationMenu(menu); +``` + +## 类: Menu + +### `new Menu()` + +创建一个新的菜单. + +## 方法 + +`菜单` 类有如下方法: + +### `Menu.setApplicationMenu(menu)` + +* `menu` Menu + +在 OS X 上设置应用菜单 `menu` . +在windows 和 linux,是为每个窗口都在其顶部设置菜单 `menu`. + +### `Menu.sendActionToFirstResponder(action)` _OS X_ + +* `action` String + +发送 `action` 给应用的第一个响应器.这个用来模仿 Cocoa 菜单的默认行为,通常你只需要使用 `MenuItem` 的属性 `role`. + +查看更多 OS X 的原生 action [OS X Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7) . + +### `Menu.buildFromTemplate(template)` + +* `template` Array + +一般来说,`template` 只是用来创建 [MenuItem](menu-item.md) 的数组 `参数` . + +你也可以向 `template` 元素添加其它东西,并且他们会变成已经有的菜单项的属性. + +### `Menu.popup([browserWindow, x, y, positioningItem])` + +* `browserWindow` BrowserWindow (可选) - 默认为 `null`. +* `x` Number (可选) - 默认为 -1. +* `y` Number (**必须** 如果x设置了) - 默认为 -1. +* `positioningItem` Number (可选) _OS X_ - 在指定坐标鼠标位置下面的菜单项的索引. 默认为 + -1. + +在 `browserWindow` 中弹出 context menu .你可以选择性地提供指定的 `x, y` 来设置菜单应该放在哪里,否则它将默认地放在当前鼠标的位置. + +### `Menu.append(menuItem)` + +* `menuItem` MenuItem + +添加菜单项. + +### `Menu.insert(pos, menuItem)` + +* `pos` Integer +* `menuItem` MenuItem + +在制定位置添加菜单项. + +### `Menu.items()` + +获取一个菜单项数组. + +## OS X Application 上的菜单的注意事项 + +相对于windows 和 linux, OS X 上的应用菜单是完全不同的style,这里是一些注意事项,来让你的菜单项更原生化. + +### 标准菜单 + +在 OS X 上,有很多系统定义的标准菜单,例如 `Services` and +`Windows` 菜单.为了让你的应用更标准化,你可以为你的菜单的 `role` 设置值,然后 electron 将会识别他们并且让你的菜单更标准: + +* `window` +* `help` +* `services` + +### 标准菜单项行为 + +OS X 为一些菜单项提供了标准的行为方法,例如 `About xxx`, +`Hide xxx`, and `Hide Others`. 为了让你的菜单项的行为更标准化,你应该为菜单项设置 `role` 属性. + +### 主菜单名 + +在 OS X ,无论你设置的什么标签,应用菜单的第一个菜单项的标签始终未你的应用名字.想要改变它的话,你必须通过修改应用绑定的 `Info.plist` 文件来修改应用名字.更多信息参考[About Information +Property List Files][AboutInformationPropertyListFiles] . + +## 为制定浏览器窗口设置菜单 (*Linux* *Windows*) + +浏览器窗口的[`setMenu` 方法][setMenu] 能够设置菜单为特定浏览器窗口的类型. + +## 菜单项位置 + +当通过 `Menu.buildFromTemplate` 创建菜单的时候,你可以使用 `position` and `id` 来放置菜单项. + +`MenuItem` 的属性 `position` 格式为 `[placement]=[id]`,`placement` 取值为 `before`, `after`, 或 `endof` 和 `id`, `id` 是菜单已经存在的菜单项的唯一 ID: + +* `before` - 在对应引用id菜单项之前插入. 如果引用的菜单项不存在,则将其插在菜单末尾. +* `after` - 在对应引用id菜单项之后插入. 如果引用的菜单项不存在,则将其插在菜单末尾. +* `endof` - 在逻辑上包含对应引用id菜单项的集合末尾插入. 如果引用的菜单项不存在, 则将使用给定的id创建一个新的集合,并且这个菜单项将插入. + +当一个菜档项插入成功了,所有的没有插入的菜单项将一个接一个地在后面插入.所以如果你想在同一个位置插入一组菜单项,只需要为这组菜单项的第一个指定位置. + +### 例子 + +模板: + +```javascript +[ + {label: '4', id: '4'}, + {label: '5', id: '5'}, + {label: '1', id: '1', position: 'before=4'}, + {label: '2', id: '2'}, + {label: '3', id: '3'} +] +``` + +菜单: + +``` +- 1 +- 2 +- 3 +- 4 +- 5 +``` + +模板: + +```javascript +[ + {label: 'a', position: 'endof=letters'}, + {label: '1', position: 'endof=numbers'}, + {label: 'b', position: 'endof=letters'}, + {label: '2', position: 'endof=numbers'}, + {label: 'c', position: 'endof=letters'}, + {label: '3', position: 'endof=numbers'} +] +``` + +菜单: + +``` +- --- +- a +- b +- c +- --- +- 1 +- 2 +- 3 +``` + +[AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html +[setMenu]: +https://github.com/atom/electron/blob/master/docs/api/browser-window.md#winsetmenumenu-linux-windows \ No newline at end of file From 288ef13fb594673744856cee1d3d2613fcb3c69f Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 10 Mar 2016 16:57:41 +0900 Subject: [PATCH 449/688] :memo: Update Korean docs as upstream [ci skip] :memo: Update Korean docs as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 21 ++++++++++++------- docs-translations/ko-KR/api/browser-window.md | 8 +++++++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 72da6862741..7c18f181742 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -256,14 +256,6 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입 `beforeunload` 이벤트 핸들러에서 `false`를 반환했을 때 윈도우 종료가 취소 될 수 있습니다. -### `app.hide()` _OS X_ - -최소화를 하지 않고 어플리케이션의 모든 윈도우들을 숨깁니다. - -### `app.show()` _OS X_ - -숨긴 어플리케이션 윈도우들을 다시 보이게 만듭니다. 자동으로 포커스되지 않습니다. - ### `app.exit(exitCode)` * `exitCode` Integer @@ -273,6 +265,19 @@ GPU가 작동하던 중 크래시가 일어났을 때 발생하는 이벤트입 모든 윈도우는 사용자의 동의 여부에 상관없이 즉시 종료되며 `before-quit` 이벤트와 `will-quit` 이벤트가 발생하지 않습니다. +### `app.focus()` + +Linux에선, 첫 번째로 보여지는 윈도우가 포커스됩니다. OS X에선, 어플리케이션을 활성화 +앱 상태로 만듭니다. Windows에선, 어플리케이션의 첫 윈도우에 포커스 됩니다. + +### `app.hide()` _OS X_ + +최소화를 하지 않고 어플리케이션의 모든 윈도우들을 숨깁니다. + +### `app.show()` _OS X_ + +숨긴 어플리케이션 윈도우들을 다시 보이게 만듭니다. 자동으로 포커스되지 않습니다. + ### `app.getAppPath()` 현재 어플리케이션의 디렉터리를 반환합니다. diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 3517f3d500c..c5030e04d1a 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -240,6 +240,14 @@ window.onbeforeunload = function(e) { 윈도우가 포커스를 가졌을 때 발생하는 이벤트입니다. +### Event: 'show' + +윈도우가 보여진 상태일 때 발생하는 이벤트입니다. + +### Event: 'hide' + +윈도우가 숨겨진 상태일 때 발생하는 이벤트입니다. + ### Event: 'maximize' 윈도우가 최대화됐을 때 발생하는 이벤트입니다. From 5f63df248ad386ea7a4af0017156b35f1bd63bac Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Mar 2016 19:53:41 +0900 Subject: [PATCH 450/688] Fix the chrome version --- atom/common/chrome_version.h | 2 +- script/lib/config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/common/chrome_version.h b/atom/common/chrome_version.h index 604e0161c3a..8b9b7ef0c82 100644 --- a/atom/common/chrome_version.h +++ b/atom/common/chrome_version.h @@ -8,7 +8,7 @@ #ifndef ATOM_COMMON_CHROME_VERSION_H_ #define ATOM_COMMON_CHROME_VERSION_H_ -#define CHROME_VERSION_STRING "49.0.2623.64" +#define CHROME_VERSION_STRING "49.0.2623.75" #define CHROME_VERSION "v" CHROME_VERSION_STRING #endif // ATOM_COMMON_CHROME_VERSION_H_ diff --git a/script/lib/config.py b/script/lib/config.py index e5fafa34720..fb1a4b89f27 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '497f11bcb91d9b0b5b5cbd004411b37b933c825e' +LIBCHROMIUMCONTENT_COMMIT = 'b06d4c307b861cdb091f4ba26b1a185333889033' PLATFORM = { 'cygwin': 'win32', From ead94b7b1f1286e5ce06fd6cfa9b4218c3c9ab0f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Mar 2016 20:09:19 +0900 Subject: [PATCH 451/688] Bump v0.36.11 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index b7075301894..f8133b35d0b 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.36.10', + 'version%': '0.36.11', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 54b4f4d6179..267df223e2b 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.36.10 + 0.36.11 CFBundleShortVersionString - 0.36.10 + 0.36.11 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 9acd36f43a2..222c4ac4610 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,36,10,0 - PRODUCTVERSION 0,36,10,0 + FILEVERSION 0,36,11,0 + PRODUCTVERSION 0,36,11,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.36.10" + VALUE "FileVersion", "0.36.11" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.36.10" + VALUE "ProductVersion", "0.36.11" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index c4291437e5b..362e4dc7b88 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 36 -#define ATOM_PATCH_VERSION 10 +#define ATOM_PATCH_VERSION 11 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index ca232158068..343f1baa8fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.36.10", + "version": "0.36.11", "devDependencies": { "asar": "^0.10.0", "eslint": "^2.1.0", From aebfbf77825fbc6e14ee69afd688a9e3bc4627d3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Mar 2016 21:47:32 +0900 Subject: [PATCH 452/688] Bump v0.37.0 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 4 ++-- package.json | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/atom.gyp b/atom.gyp index 27b7ecd256b..969a0665f9f 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.36.11', + 'version%': '0.37.0', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 267df223e2b..6b504728ae3 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.36.11 + 0.37.0 CFBundleShortVersionString - 0.36.11 + 0.37.0 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 222c4ac4610..bdffd90effd 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,36,11,0 - PRODUCTVERSION 0,36,11,0 + FILEVERSION 0,37,0,0 + PRODUCTVERSION 0,37,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.36.11" + VALUE "FileVersion", "0.37.0" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.36.11" + VALUE "ProductVersion", "0.37.0" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 362e4dc7b88..1b1aee905ce 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -6,8 +6,8 @@ #define ATOM_VERSION_H #define ATOM_MAJOR_VERSION 0 -#define ATOM_MINOR_VERSION 36 -#define ATOM_PATCH_VERSION 11 +#define ATOM_MINOR_VERSION 37 +#define ATOM_PATCH_VERSION 0 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index 343f1baa8fc..6b6abb5bc68 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.36.11", + "version": "0.37.0", "devDependencies": { "asar": "^0.10.0", "eslint": "^2.1.0", From cd327e65cb1e4f809b0ab38a527917741af8cf27 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Mar 2016 22:20:11 +0900 Subject: [PATCH 453/688] Revert "Bump v0.37.0" This reverts commit aebfbf77825fbc6e14ee69afd688a9e3bc4627d3. We have troubles with linux-ia32 release. --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 4 ++-- package.json | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/atom.gyp b/atom.gyp index 969a0665f9f..27b7ecd256b 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.37.0', + 'version%': '0.36.11', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 6b504728ae3..267df223e2b 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.37.0 + 0.36.11 CFBundleShortVersionString - 0.37.0 + 0.36.11 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index bdffd90effd..222c4ac4610 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,37,0,0 - PRODUCTVERSION 0,37,0,0 + FILEVERSION 0,36,11,0 + PRODUCTVERSION 0,36,11,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.37.0" + VALUE "FileVersion", "0.36.11" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.37.0" + VALUE "ProductVersion", "0.36.11" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 1b1aee905ce..362e4dc7b88 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -6,8 +6,8 @@ #define ATOM_VERSION_H #define ATOM_MAJOR_VERSION 0 -#define ATOM_MINOR_VERSION 37 -#define ATOM_PATCH_VERSION 0 +#define ATOM_MINOR_VERSION 36 +#define ATOM_PATCH_VERSION 11 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index 6b6abb5bc68..343f1baa8fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.37.0", + "version": "0.36.11", "devDependencies": { "asar": "^0.10.0", "eslint": "^2.1.0", From 0f620a53930af3a479a67166afc72edea5c18705 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Mar 2016 22:22:17 +0900 Subject: [PATCH 454/688] Do not copy system libraries on Linux --- script/create-dist.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/script/create-dist.py b/script/create-dist.py index f3894eb4fa2..e25845432c7 100755 --- a/script/create-dist.py +++ b/script/create-dist.py @@ -71,17 +71,11 @@ TARGET_DIRECTORIES = { ], } -SYSTEM_LIBRARIES = [ - 'libgcrypt.so', -] - def main(): rm_rf(DIST_DIR) os.makedirs(DIST_DIR) - target_arch = get_target_arch() - force_build() create_symbols() copy_binaries() @@ -91,8 +85,6 @@ def main(): if PLATFORM == 'linux': strip_binaries() - if target_arch != 'arm': - copy_system_libraries() create_version() create_dist_zip() @@ -144,21 +136,6 @@ def strip_binaries(): execute([strip, os.path.join(DIST_DIR, binary)]) -def copy_system_libraries(): - executable_path = os.path.join(OUT_DIR, PROJECT_NAME) # our/R/electron - ldd = execute(['ldd', executable_path]) - lib_re = re.compile('\t(.*) => (.+) \(.*\)$') - for line in ldd.splitlines(): - m = lib_re.match(line) - if not m: - continue - for i, library in enumerate(SYSTEM_LIBRARIES): - real_library = m.group(1) - if real_library.startswith(library): - shutil.copyfile(m.group(2), os.path.join(DIST_DIR, real_library)) - SYSTEM_LIBRARIES[i] = real_library - - def create_version(): version_path = os.path.join(SOURCE_ROOT, 'dist', 'version') with open(version_path, 'w') as version_file: @@ -185,8 +162,6 @@ def create_dist_zip(): with scoped_cwd(DIST_DIR): files = TARGET_BINARIES[PLATFORM] + ['LICENSE', 'LICENSES.chromium.html', 'version'] - if PLATFORM == 'linux': - files += [lib for lib in SYSTEM_LIBRARIES if os.path.exists(lib)] dirs = TARGET_DIRECTORIES[PLATFORM] make_zip(zip_file, files, dirs) From 5ed6c7714b3a8e9b7b4658654e9882c560aaac0a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 10 Mar 2016 13:08:38 -0800 Subject: [PATCH 455/688] Don't return attributes from from WebViewImpl::setupWebViewAttributes --- lib/renderer/web-view/web-view-attributes.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/renderer/web-view/web-view-attributes.js b/lib/renderer/web-view/web-view-attributes.js index 4ad4bd72501..bb7847fe163 100644 --- a/lib/renderer/web-view/web-view-attributes.js +++ b/lib/renderer/web-view/web-view-attributes.js @@ -297,7 +297,6 @@ class BlinkFeaturesAttribute extends WebViewAttribute { // Sets up all of the webview attributes. WebViewImpl.prototype.setupWebViewAttributes = function() { - var attribute, autosizeAttributes, i, len, results; this.attributes = {}; this.attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] = new AllowTransparencyAttribute(this); this.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE] = new AutosizeAttribute(this); @@ -311,11 +310,9 @@ WebViewImpl.prototype.setupWebViewAttributes = function() { this.attributes[webViewConstants.ATTRIBUTE_ALLOWPOPUPS] = new BooleanAttribute(webViewConstants.ATTRIBUTE_ALLOWPOPUPS, this); this.attributes[webViewConstants.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this); this.attributes[webViewConstants.ATTRIBUTE_BLINKFEATURES] = new BlinkFeaturesAttribute(this); - autosizeAttributes = [webViewConstants.ATTRIBUTE_MAXHEIGHT, webViewConstants.ATTRIBUTE_MAXWIDTH, webViewConstants.ATTRIBUTE_MINHEIGHT, webViewConstants.ATTRIBUTE_MINWIDTH]; - results = []; - for (i = 0, len = autosizeAttributes.length; i < len; i++) { - attribute = autosizeAttributes[i]; - results.push(this.attributes[attribute] = new AutosizeDimensionAttribute(attribute, this)); - } - return results; + + const autosizeAttributes = [webViewConstants.ATTRIBUTE_MAXHEIGHT, webViewConstants.ATTRIBUTE_MAXWIDTH, webViewConstants.ATTRIBUTE_MINHEIGHT, webViewConstants.ATTRIBUTE_MINWIDTH]; + autosizeAttributes.forEach((attribute) => { + this.attributes[attribute] = new AutosizeDimensionAttribute(attribute, this); + }); }; From 3a1e837f8bbbdf129fe2af4361f6d6d8dc5d7196 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 10 Mar 2016 13:23:14 -0800 Subject: [PATCH 456/688] Don't collect results in exit event callback --- lib/common/asar.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/common/asar.js b/lib/common/asar.js index f45e62b176d..aeff18916a1 100644 --- a/lib/common/asar.js +++ b/lib/common/asar.js @@ -24,14 +24,12 @@ // Clean cache on quit. process.on('exit', function() { - var archive, p, results; - results = []; + var archive, p; for (p in cachedArchives) { if (!hasProp.call(cachedArchives, p)) continue; archive = cachedArchives[p]; - results.push(archive.destroy()); + archive.destroy(); } - return results; }); // Separate asar package's path from full path. From 93939089eca0cf01aa2ae355b52bdbe88485355b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 10 Mar 2016 13:26:14 -0800 Subject: [PATCH 457/688] Don't collect results in Menu.setApplicationMenu --- lib/browser/api/menu.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index 5af577872db..f22002e144d 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -267,7 +267,6 @@ Menu.prototype._callMenuWillShow = function() { var applicationMenu = null; Menu.setApplicationMenu = function(menu) { - var j, len, results, w, windows; if (!(menu === null || menu.constructor === Menu)) { throw new TypeError('Invalid menu'); } @@ -279,15 +278,11 @@ Menu.setApplicationMenu = function(menu) { return; } menu._callMenuWillShow(); - return bindings.setApplicationMenu(menu); + bindings.setApplicationMenu(menu); } else { - windows = BrowserWindow.getAllWindows(); - results = []; - for (j = 0, len = windows.length; j < len; j++) { - w = windows[j]; - results.push(w.setMenu(menu)); - } - return results; + BrowserWindow.getAllWindows().forEach(function(window) { + window.setMenu(menu); + }); } }; From 3a08aa37de1e7277c82934ae884197ecde5b58d2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 10 Mar 2016 13:29:57 -0800 Subject: [PATCH 458/688] Don't collect results from Menu::_callMenuWillShow --- lib/browser/api/menu.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index f22002e144d..5c19c7d421f 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -249,19 +249,14 @@ Menu.prototype.insert = function(pos, item) { // Force menuWillShow to be called Menu.prototype._callMenuWillShow = function() { - var item, j, len, ref1, ref2, results; - if ((ref1 = this.delegate) != null) { - ref1.menuWillShow(); + if (this.delegate != null) { + this.delegate.menuWillShow(); } - ref2 = this.items; - results = []; - for (j = 0, len = ref2.length; j < len; j++) { - item = ref2[j]; + this.items.forEach(function(item) { if (item.submenu != null) { - results.push(item.submenu._callMenuWillShow()); + item.submenu._callMenuWillShow(); } - } - return results; + }); }; var applicationMenu = null; From 6b1748d6d639f3849acf0e8c0d207ea2ae1e1e0e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 10 Mar 2016 14:01:57 -0800 Subject: [PATCH 459/688] Don't collect results from delegate.menuWillShow --- lib/browser/api/menu.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index 5c19c7d421f..a24f1ae0fb7 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -132,9 +132,8 @@ Menu.prototype._init = function() { return function() { // Make sure radio groups have at least one menu item seleted. - var checked, group, id, j, len, radioItem, ref1, results; + var checked, group, id, j, len, radioItem, ref1; ref1 = _this.groupsMap; - results = []; for (id in ref1) { group = ref1[id]; checked = false; @@ -147,12 +146,9 @@ Menu.prototype._init = function() { break; } if (!checked) { - results.push(v8Util.setHiddenValue(group[0], 'checked', true)); - } else { - results.push(void 0); + v8Util.setHiddenValue(group[0], 'checked', true); } } - return results; }; })(this) }; From c2b1f630f6e035cf999e4de190df34eb0da433ec Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 11 Mar 2016 09:37:56 -0800 Subject: [PATCH 460/688] Add AppVeyor badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0080585b54c..9c7d4ce815e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![Electron Logo](http://electron.atom.io/images/electron-logo.svg)](http://electron.atom.io/) -[![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron) +[![Travis Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron) +[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/qtmod45u0cc1ouov/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/electron/branch/master) [![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies) [![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/) From a95d0078b5a909e75eb57a4bafdef832f3b2c954 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 11 Mar 2016 09:39:12 -0800 Subject: [PATCH 461/688] Link to root build page --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c7d4ce815e..f7b5cb79000 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![Electron Logo](http://electron.atom.io/images/electron-logo.svg)](http://electron.atom.io/) [![Travis Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron) -[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/qtmod45u0cc1ouov/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/electron/branch/master) +[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/qtmod45u0cc1ouov/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/electron) [![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies) [![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/) From a3f08c9b514bde39067fa3c5a029a163484abdde Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 10 Mar 2016 11:54:17 -0800 Subject: [PATCH 462/688] Use arrow functions to replace old CoffeeScript => this wrappers --- lib/browser/api/app.js | 10 +- .../api/auto-updater/auto-updater-win.js | 38 +++--- lib/browser/api/browser-window.js | 8 +- lib/browser/api/menu-item.js | 41 +++--- lib/browser/api/menu.js | 122 ++++++++---------- lib/browser/api/navigation-controller.js | 61 ++++----- lib/browser/api/web-contents.js | 25 ++-- lib/common/api/crash-reporter.js | 10 +- lib/renderer/override.js | 14 +- lib/renderer/web-view/web-view.js | 59 ++++----- 10 files changed, 176 insertions(+), 212 deletions(-) diff --git a/lib/browser/api/app.js b/lib/browser/api/app.js index f7c9cd97583..8d2d203ee98 100644 --- a/lib/browser/api/app.js +++ b/lib/browser/api/app.js @@ -1,3 +1,5 @@ +'use strict'; + const deprecate = require('electron').deprecate; const session = require('electron').session; const Menu = require('electron').Menu; @@ -89,11 +91,9 @@ deprecate.rename(app, 'terminate', 'quit'); deprecate.event(app, 'finish-launching', 'ready', function() { // give default app a chance to setup default menu. - return setImmediate((function(_this) { - return function() { - return _this.emit('finish-launching'); - }; - })(this)); + setImmediate(() => { + this.emit('finish-launching'); + }); }); deprecate.event(app, 'activate-with-no-open-windows', 'activate', function(event, hasVisibleWindows) { diff --git a/lib/browser/api/auto-updater/auto-updater-win.js b/lib/browser/api/auto-updater/auto-updater-win.js index 1270f8f2bdb..8d584699419 100644 --- a/lib/browser/api/auto-updater/auto-updater-win.js +++ b/lib/browser/api/auto-updater/auto-updater-win.js @@ -28,30 +28,28 @@ AutoUpdater.prototype.checkForUpdates = function() { return this.emitError('Can not find Squirrel'); } this.emit('checking-for-update'); - return squirrelUpdate.download(this.updateURL, (function(_this) { - return function(error, update) { + squirrelUpdate.download(this.updateURL, (error, update) => { + if (error != null) { + return this.emitError(error); + } + if (update == null) { + return this.emit('update-not-available'); + } + this.emit('update-available'); + squirrelUpdate.update(this.updateURL, (error) => { + var date, releaseNotes, version; if (error != null) { - return _this.emitError(error); + return this.emitError(error); } - if (update == null) { - return _this.emit('update-not-available'); - } - _this.emit('update-available'); - return squirrelUpdate.update(_this.updateURL, function(error) { - var date, releaseNotes, version; - if (error != null) { - return _this.emitError(error); - } - releaseNotes = update.releaseNotes, version = update.version; + releaseNotes = update.releaseNotes, version = update.version; - // Following information is not available on Windows, so fake them. - date = new Date; - return _this.emit('update-downloaded', {}, releaseNotes, version, date, _this.updateURL, function() { - return _this.quitAndInstall(); - }); + // Following information is not available on Windows, so fake them. + date = new Date; + this.emit('update-downloaded', {}, releaseNotes, version, date, this.updateURL, () => { + this.quitAndInstall(); }); - }; - })(this)); + }); + }); }; // Private: Emit both error object and message, this is to keep compatibility diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 1d2f665e5d0..7d99c483944 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -1,3 +1,5 @@ +'use strict'; + const ipcMain = require('electron').ipcMain; const deprecate = require('electron').deprecate; const EventEmitter = require('events').EventEmitter; @@ -33,19 +35,19 @@ BrowserWindow.prototype._init = function() { // window.resizeTo(...) // window.moveTo(...) this.webContents.on('move', (event, size) => { - return this.setBounds(size); + this.setBounds(size); }); // Hide the auto-hide menu when webContents is focused. this.webContents.on('activate', () => { if (process.platform !== 'darwin' && this.isMenuBarAutoHide() && this.isMenuBarVisible()) { - return this.setMenuBarVisibility(false); + this.setMenuBarVisibility(false); } }); // Forward the crashed event. this.webContents.on('crashed', () => { - return this.emit('crashed'); + this.emit('crashed'); }); // Change window title to page title. diff --git a/lib/browser/api/menu-item.js b/lib/browser/api/menu-item.js index 4f449ecc015..f5f94751866 100644 --- a/lib/browser/api/menu-item.js +++ b/lib/browser/api/menu-item.js @@ -1,3 +1,5 @@ +'use strict'; + var MenuItem, methodInBrowserWindow, nextCommandId, rolesMap; nextCommandId = 0; @@ -51,28 +53,25 @@ MenuItem = (function() { throw new Error("Unknown menu type " + this.type); } this.commandId = ++nextCommandId; - this.click = (function(_this) { - return function(focusedWindow) { - - // Manually flip the checked flags when clicked. - var methodName, ref1, ref2; - if ((ref1 = _this.type) === 'checkbox' || ref1 === 'radio') { - _this.checked = !_this.checked; + this.click = (focusedWindow) => { + // Manually flip the checked flags when clicked. + var methodName, ref1, ref2; + if ((ref1 = this.type) === 'checkbox' || ref1 === 'radio') { + this.checked = !this.checked; + } + if (this.role && rolesMap[this.role] && process.platform !== 'darwin' && (focusedWindow != null)) { + methodName = rolesMap[this.role]; + if (methodInBrowserWindow[methodName]) { + return focusedWindow[methodName](); + } else { + return (ref2 = focusedWindow.webContents) != null ? ref2[methodName]() : void 0; } - if (_this.role && rolesMap[_this.role] && process.platform !== 'darwin' && (focusedWindow != null)) { - methodName = rolesMap[_this.role]; - if (methodInBrowserWindow[methodName]) { - return focusedWindow[methodName](); - } else { - return (ref2 = focusedWindow.webContents) != null ? ref2[methodName]() : void 0; - } - } else if (typeof click === 'function') { - return click(_this, focusedWindow); - } else if (typeof _this.selector === 'string' && process.platform === 'darwin') { - return Menu.sendActionToFirstResponder(_this.selector); - } - }; - })(this); + } else if (typeof click === 'function') { + return click(this, focusedWindow); + } else if (typeof this.selector === 'string' && process.platform === 'darwin') { + return Menu.sendActionToFirstResponder(this.selector); + } + }; } MenuItem.prototype.overrideProperty = function(name, defaultValue) { diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index a24f1ae0fb7..202885d826b 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -1,3 +1,5 @@ +'use strict'; + const BrowserWindow = require('electron').BrowserWindow; const MenuItem = require('electron').MenuItem; const EventEmitter = require('events').EventEmitter; @@ -92,65 +94,51 @@ Menu.prototype._init = function() { this.groupsMap = {}; this.items = []; return this.delegate = { - isCommandIdChecked: (function(_this) { - return function(commandId) { - var ref1; - return (ref1 = _this.commandsMap[commandId]) != null ? ref1.checked : void 0; - }; - })(this), - isCommandIdEnabled: (function(_this) { - return function(commandId) { - var ref1; - return (ref1 = _this.commandsMap[commandId]) != null ? ref1.enabled : void 0; - }; - })(this), - isCommandIdVisible: (function(_this) { - return function(commandId) { - var ref1; - return (ref1 = _this.commandsMap[commandId]) != null ? ref1.visible : void 0; - }; - })(this), - getAcceleratorForCommandId: (function(_this) { - return function(commandId) { - var ref1; - return (ref1 = _this.commandsMap[commandId]) != null ? ref1.accelerator : void 0; - }; - })(this), - getIconForCommandId: (function(_this) { - return function(commandId) { - var ref1; - return (ref1 = _this.commandsMap[commandId]) != null ? ref1.icon : void 0; - }; - })(this), - executeCommand: (function(_this) { - return function(commandId) { - var ref1; - return (ref1 = _this.commandsMap[commandId]) != null ? ref1.click(BrowserWindow.getFocusedWindow()) : void 0; - }; - })(this), - menuWillShow: (function(_this) { - return function() { - - // Make sure radio groups have at least one menu item seleted. - var checked, group, id, j, len, radioItem, ref1; - ref1 = _this.groupsMap; - for (id in ref1) { - group = ref1[id]; - checked = false; - for (j = 0, len = group.length; j < len; j++) { - radioItem = group[j]; - if (!radioItem.checked) { - continue; - } - checked = true; - break; - } - if (!checked) { - v8Util.setHiddenValue(group[0], 'checked', true); + isCommandIdChecked: (commandId) => { + var command = this.commandsMap[commandId]; + return command != null ? command.checked : undefined; + }, + isCommandIdEnabled: (commandId) => { + var command = this.commandsMap[commandId]; + return command != null ? command.enabled : undefined; + }, + isCommandIdVisible: (commandId) => { + var command = this.commandsMap[commandId]; + return command != null ? command.visible : undefined; + }, + getAcceleratorForCommandId: (commandId) => { + var command = this.commandsMap[commandId]; + return command != null ? command.accelerator : undefined; + }, + getIconForCommandId: (commandId) => { + var command = this.commandsMap[commandId]; + return command != null ? command.icon : void 0; + }, + executeCommand: (commandId) => { + var command = this.commandsMap[commandId]; + return command != null ? command.click(BrowserWindow.getFocusedWindow()) : undefined; + }, + menuWillShow: () => { + // Make sure radio groups have at least one menu item seleted. + var checked, group, id, j, len, radioItem, ref1; + ref1 = this.groupsMap; + results = []; + for (id in ref1) { + group = ref1[id]; + checked = false; + for (j = 0, len = group.length; j < len; j++) { + radioItem = group[j]; + if (!radioItem.checked) { + continue; } + checked = true; + break; + } + if (!checked) { + v8Util.setHiddenValue(group[0], 'checked', true); } }; - })(this) + } }; }; @@ -208,19 +196,17 @@ Menu.prototype.insert = function(pos, item) { get: function() { return v8Util.getHiddenValue(item, 'checked'); }, - set: (function(_this) { - return function() { - var j, len, otherItem, ref1; - ref1 = _this.groupsMap[item.groupId]; - for (j = 0, len = ref1.length; j < len; j++) { - otherItem = ref1[j]; - if (otherItem !== item) { - v8Util.setHiddenValue(otherItem, 'checked', false); - } + set: () => { + var j, len, otherItem, ref1; + ref1 = this.groupsMap[item.groupId]; + for (j = 0, len = ref1.length; j < len; j++) { + otherItem = ref1[j]; + if (otherItem !== item) { + v8Util.setHiddenValue(otherItem, 'checked', false); } - return v8Util.setHiddenValue(item, 'checked', true); - }; - })(this) + } + return v8Util.setHiddenValue(item, 'checked', true); + } }); this.insertRadioItem(pos, item.commandId, item.label, item.groupId); } diff --git a/lib/browser/api/navigation-controller.js b/lib/browser/api/navigation-controller.js index 80756eb13e4..8c3878a51fa 100644 --- a/lib/browser/api/navigation-controller.js +++ b/lib/browser/api/navigation-controller.js @@ -1,3 +1,5 @@ +'use strict'; + const ipcMain = require('electron').ipcMain; var slice = [].slice; @@ -30,40 +32,33 @@ var NavigationController = (function() { this.currentIndex++; this.history.push(this.webContents._getURL()); } - this.webContents.on('navigation-entry-commited', (function(_this) { - return function(event, url, inPage, replaceEntry) { - var currentEntry; - if (_this.inPageIndex > -1 && !inPage) { - - // Navigated to a new page, clear in-page mark. - _this.inPageIndex = -1; - } else if (_this.inPageIndex === -1 && inPage) { - - // Started in-page navigations. - _this.inPageIndex = _this.currentIndex; + this.webContents.on('navigation-entry-commited', (event, url, inPage, replaceEntry) => { + var currentEntry; + if (this.inPageIndex > -1 && !inPage) { + // Navigated to a new page, clear in-page mark. + this.inPageIndex = -1; + } else if (this.inPageIndex === -1 && inPage) { + // Started in-page navigations. + this.inPageIndex = this.currentIndex; + } + if (this.pendingIndex >= 0) { + // Go to index. + this.currentIndex = this.pendingIndex; + this.pendingIndex = -1; + return this.history[this.currentIndex] = url; + } else if (replaceEntry) { + // Non-user initialized navigation. + return this.history[this.currentIndex] = url; + } else { + // Normal navigation. Clear history. + this.history = this.history.slice(0, this.currentIndex + 1); + currentEntry = this.history[this.currentIndex]; + if ((currentEntry != null ? currentEntry.url : void 0) !== url) { + this.currentIndex++; + return this.history.push(url); } - if (_this.pendingIndex >= 0) { - - // Go to index. - _this.currentIndex = _this.pendingIndex; - _this.pendingIndex = -1; - return _this.history[_this.currentIndex] = url; - } else if (replaceEntry) { - - // Non-user initialized navigation. - return _this.history[_this.currentIndex] = url; - } else { - - // Normal navigation. Clear history. - _this.history = _this.history.slice(0, _this.currentIndex + 1); - currentEntry = _this.history[_this.currentIndex]; - if ((currentEntry != null ? currentEntry.url : void 0) !== url) { - _this.currentIndex++; - return _this.history.push(url); - } - } - }; - })(this)); + } + }); } NavigationController.prototype.loadURL = function(url, options) { diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index 9486378264b..c7dd3bc7475 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -153,35 +153,28 @@ let wrapWebContents = function(webContents) { // This error occurs when host could not be found. webContents.on('did-fail-provisional-load', function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + var args = 1 <= arguments.length ? slice.call(arguments, 0) : []; // Calling loadURL during this event might cause crash, so delay the event // until next tick. - return setImmediate((function(_this) { - return function() { - return _this.emit.apply(_this, ['did-fail-load'].concat(slice.call(args))); - }; - })(this)); + setImmediate(() => { + this.emit.apply(this, ['did-fail-load'].concat(slice.call(args))); + }); }); // Delays the page-title-updated event to next tick. webContents.on('-page-title-updated', function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return setImmediate((function(_this) { - return function() { - return _this.emit.apply(_this, ['page-title-updated'].concat(slice.call(args))); - }; - })(this)); + var args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + setImmediate(() => { + this.emit.apply(this, ['page-title-updated'].concat(slice.call(args))); + }); }); // Deprecated. deprecate.rename(webContents, 'loadUrl', 'loadURL'); deprecate.rename(webContents, 'getUrl', 'getURL'); deprecate.event(webContents, 'page-title-set', 'page-title-updated', function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + var args = 1 <= arguments.length ? slice.call(arguments, 0) : []; return this.emit.apply(this, ['page-title-set'].concat(slice.call(args))); }); return webContents.printToPDF = function(options, callback) { diff --git a/lib/common/api/crash-reporter.js b/lib/common/api/crash-reporter.js index e3a327118fd..f84e13ebb57 100644 --- a/lib/common/api/crash-reporter.js +++ b/lib/common/api/crash-reporter.js @@ -1,3 +1,5 @@ +'use strict'; + const os = require('os'); const path = require('path'); const spawn = require('child_process').spawn; @@ -52,11 +54,9 @@ var CrashReporter = (function() { deprecate.log('submitURL is now a required option to crashReporter.start'); return; } - start = (function(_this) { - return function() { - return binding.start(_this.productName, companyName, submitURL, autoSubmit, ignoreSystemCrashHandler, extra); - }; - })(this); + start = () => { + binding.start(this.productName, companyName, submitURL, autoSubmit, ignoreSystemCrashHandler, extra); + }; if (process.platform === 'win32') { args = ["--reporter-url=" + submitURL, "--application-name=" + this.productName, "--v=1"]; env = { diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 2b0e48b3dd3..c44218e8a56 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -1,3 +1,5 @@ +'use strict'; + const ipcRenderer = require('electron').ipcRenderer; const remote = require('electron').remote; @@ -37,12 +39,10 @@ var BrowserWindowProxy = (function() { function BrowserWindowProxy(guestId1) { this.guestId = guestId1; this.closed = false; - ipcRenderer.once("ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_" + this.guestId, (function(_this) { - return function() { - BrowserWindowProxy.remove(_this.guestId); - return (_this.closed = true); - }; - })(this)); + ipcRenderer.once("ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_" + this.guestId, () => { + BrowserWindowProxy.remove(this.guestId); + this.closed = true; + }); } BrowserWindowProxy.prototype.close = function() { @@ -182,7 +182,7 @@ if (process.openerId != null) { ipcRenderer.on('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', function (event, isVisible, isMinimized) { var hasChanged = _isVisible != isVisible || _isMinimized != isMinimized; - + if (hasChanged) { _isVisible = isVisible; _isMinimized = isMinimized; diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index 5b135e0427a..38ee57a96f6 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -86,25 +86,22 @@ var WebViewImpl = (function() { WebViewImpl.prototype.setupFocusPropagation = function() { if (!this.webviewNode.hasAttribute('tabIndex')) { - // needs a tabIndex in order to be focusable. // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute // to allow to be focusable. // See http://crbug.com/231664. this.webviewNode.setAttribute('tabIndex', -1); } - this.webviewNode.addEventListener('focus', (function(_this) { - return function() { - // Focus the BrowserPlugin when the takes focus. - return _this.browserPluginNode.focus(); - }; - })(this)); - return this.webviewNode.addEventListener('blur', (function(_this) { - return function() { - // Blur the BrowserPlugin when the loses focus. - return _this.browserPluginNode.blur(); - }; - })(this)); + + // Focus the BrowserPlugin when the takes focus. + this.webviewNode.addEventListener('focus', () => { + this.browserPluginNode.focus(); + }); + + // Blur the BrowserPlugin when the loses focus. + this.webviewNode.addEventListener('blur', () => { + this.browserPluginNode.blur(); + }); }; @@ -178,11 +175,9 @@ var WebViewImpl = (function() { }; WebViewImpl.prototype.createGuest = function() { - return guestViewInternal.createGuest(this.buildParams(), (function(_this) { - return function(event, guestInstanceId) { - return _this.attachWindow(guestInstanceId); - }; - })(this)); + return guestViewInternal.createGuest(this.buildParams(), (event, guestInstanceId) => { + this.attachWindow(guestInstanceId); + }); }; WebViewImpl.prototype.dispatchEvent = function(webViewEvent) { @@ -195,22 +190,18 @@ var WebViewImpl = (function() { var propertyName; propertyName = 'on' + eventName.toLowerCase(); return Object.defineProperty(this.webviewNode, propertyName, { - get: (function(_this) { - return function() { - return _this.on[propertyName]; - }; - })(this), - set: (function(_this) { - return function(value) { - if (_this.on[propertyName]) { - _this.webviewNode.removeEventListener(eventName, _this.on[propertyName]); - } - _this.on[propertyName] = value; - if (value) { - return _this.webviewNode.addEventListener(eventName, value); - } - }; - })(this), + get: () => { + this.on[propertyName]; + }, + set: (value) => { + if (this.on[propertyName]) { + this.webviewNode.removeEventListener(eventName, this.on[propertyName]); + } + this.on[propertyName] = value; + if (value) { + return this.webviewNode.addEventListener(eventName, value); + } + }, enumerable: true }); }; From 0ee34461098005f298ed9be1b0addb845db1f9c5 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 10 Mar 2016 11:59:50 -0800 Subject: [PATCH 463/688] Use undefined instead of void 0 --- lib/browser/api/menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index 202885d826b..83816a9905d 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -112,7 +112,7 @@ Menu.prototype._init = function() { }, getIconForCommandId: (commandId) => { var command = this.commandsMap[commandId]; - return command != null ? command.icon : void 0; + return command != null ? command.icon : undefined; }, executeCommand: (commandId) => { var command = this.commandsMap[commandId]; From 3c11f5dc4d84b7599fe0f314cebc241ef35f3121 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 11 Mar 2016 11:05:48 -0800 Subject: [PATCH 464/688] Remove returns from event handlers --- lib/browser/api/browser-window.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 7d99c483944..7e2a8d38c31 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -69,29 +69,29 @@ BrowserWindow.prototype._init = function() { // Though this hack is only needed on OS X when the app is launched from // Finder, we still do it on all platforms in case of other bugs we don't know. this.webContents.once('load-url', function() { - return this.focus(); + this.focus(); }); // Redirect focus/blur event to app instance too. this.on('blur', (event) => { - return app.emit('browser-window-blur', event, this); + app.emit('browser-window-blur', event, this); }); this.on('focus', (event) => { - return app.emit('browser-window-focus', event, this); + app.emit('browser-window-focus', event, this); }); // Evented visibilityState changes this.on('show', () => { - return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); + this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); }); this.on('hide', () => { - return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); + this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); }); this.on('minimize', () => { - return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); + this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); }); this.on('restore', () => { - return this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); + this.webContents.send('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', this.isVisible(), this.isMinimized()); }); // Notify the creation of the window. @@ -99,15 +99,15 @@ BrowserWindow.prototype._init = function() { // Be compatible with old APIs. this.webContents.on('devtools-focused', () => { - return this.emit('devtools-focused'); + this.emit('devtools-focused'); }); this.webContents.on('devtools-opened', () => { - return this.emit('devtools-opened'); + this.emit('devtools-opened'); }); this.webContents.on('devtools-closed', () => { - return this.emit('devtools-closed'); + this.emit('devtools-closed'); }); - return Object.defineProperty(this, 'devToolsWebContents', { + Object.defineProperty(this, 'devToolsWebContents', { enumerable: true, configurable: false, get: function() { From 0e5e230c037ee62909b2472fa997ea052b39f091 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 11 Mar 2016 11:12:47 -0800 Subject: [PATCH 465/688] Remove lint errors due to rebase --- lib/browser/api/menu.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index 83816a9905d..cfb00bd4527 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -122,7 +122,6 @@ Menu.prototype._init = function() { // Make sure radio groups have at least one menu item seleted. var checked, group, id, j, len, radioItem, ref1; ref1 = this.groupsMap; - results = []; for (id in ref1) { group = ref1[id]; checked = false; @@ -137,7 +136,7 @@ Menu.prototype._init = function() { if (!checked) { v8Util.setHiddenValue(group[0], 'checked', true); } - }; + } } }; }; From 28e9d87d86e5565dc46c3aba1aca1d9e37a3c9f8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 11 Mar 2016 11:16:59 -0800 Subject: [PATCH 466/688] Add back return in getter --- lib/renderer/web-view/web-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index 38ee57a96f6..554b2f04cbe 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -191,7 +191,7 @@ var WebViewImpl = (function() { propertyName = 'on' + eventName.toLowerCase(); return Object.defineProperty(this.webviewNode, propertyName, { get: () => { - this.on[propertyName]; + return this.on[propertyName]; }, set: (value) => { if (this.on[propertyName]) { From 3556507ab984fc0ac0bdd6fe5d4da52cd29e0e9a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 11 Mar 2016 14:08:14 -0800 Subject: [PATCH 467/688] Use arrow functions for this binding --- lib/renderer/web-view/web-view-attributes.js | 40 +++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/lib/renderer/web-view/web-view-attributes.js b/lib/renderer/web-view/web-view-attributes.js index bb7847fe163..e85fe716187 100644 --- a/lib/renderer/web-view/web-view-attributes.js +++ b/lib/renderer/web-view/web-view-attributes.js @@ -44,16 +44,12 @@ class WebViewAttribute { // Defines this attribute as a property on the webview node. defineProperty() { return Object.defineProperty(this.webViewImpl.webviewNode, this.name, { - get: (function(_this) { - return function() { - return _this.getValue(); - }; - })(this), - set: (function(_this) { - return function(value) { - return _this.setValue(value); - }; - })(this), + get: () => { + return this.getValue(); + }, + set: (value) => { + return this.setValue(value); + }, enumerable: true }); } @@ -203,20 +199,18 @@ class SrcAttribute extends WebViewAttribute { // spawns off a new process. setupMutationObserver() { var params; - this.observer = new MutationObserver((function(_this) { - return function(mutations) { - var i, len, mutation, newValue, oldValue; - for (i = 0, len = mutations.length; i < len; i++) { - mutation = mutations[i]; - oldValue = mutation.oldValue; - newValue = _this.getValue(); - if (oldValue !== newValue) { - return; - } - _this.handleMutation(oldValue, newValue); + this.observer = new MutationObserver((mutations) => { + var i, len, mutation, newValue, oldValue; + for (i = 0, len = mutations.length; i < len; i++) { + mutation = mutations[i]; + oldValue = mutation.oldValue; + newValue = this.getValue(); + if (oldValue !== newValue) { + return; } - }; - })(this)); + this.handleMutation(oldValue, newValue); + } + }); params = { attributes: true, attributeOldValue: true, From 71fb6840694aef4d39450c6e45609918c2566f58 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 12 Mar 2016 09:17:28 +0900 Subject: [PATCH 468/688] spec: Skip webview.executeJavaScript in Travis on OS X It is very easy to get timeout. --- spec/webview-spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index ba3913e2e47..5963709e6f0 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -568,7 +568,9 @@ describe(' tag', function() { }); it('can return the result of the executed script', function(done) { - this.timeout(50000); + if (process.env.TRAVIS === 'true' && process.platform == 'darwin') + return done(); + var listener = function() { var jsScript = "'4'+2"; webview.executeJavaScript(jsScript, false, function(result) { From 0e1bb989132e20b317735c8c134580f85d5e6714 Mon Sep 17 00:00:00 2001 From: Habib Rehman Date: Sat, 12 Mar 2016 00:26:29 +0000 Subject: [PATCH 469/688] Fix broken/outdated link and push up the version --- docs/tutorial/debugging-main-process.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorial/debugging-main-process.md b/docs/tutorial/debugging-main-process.md index 6fbb858bc28..c7a373f0a45 100644 --- a/docs/tutorial/debugging-main-process.md +++ b/docs/tutorial/debugging-main-process.md @@ -40,11 +40,11 @@ $ npm install git+https://git@github.com/enlight/node-pre-gyp.git#detect-electro ### 4. Recompile the `node-inspector` `v8` modules for electron (change the target to your electron version number) ```bash -$ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-debug/ --dist-url=https://atom.io/download/atom-shell reinstall -$ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-profiler/ --dist-url=https://atom.io/download/atom-shell reinstall +$ node_modules/.bin/node-pre-gyp --target=0.36.11 --runtime=electron --fallback-to-build --directory node_modules/v8-debug/ --dist-url=https://atom.io/download/atom-shell reinstall +$ node_modules/.bin/node-pre-gyp --target=0.36.11 --runtime=electron --fallback-to-build --directory node_modules/v8-profiler/ --dist-url=https://atom.io/download/atom-shell reinstall ``` -See also [How to install native modules](how-to-install-native-modules). +See also [How to install native modules](using-native-node-modules.md). ### 5. Enable debug mode for Electron From b10f196d169ebc5bf8c274a8fb3ac15c93c15458 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 12 Mar 2016 09:54:10 +0900 Subject: [PATCH 470/688] Bump v0.37.0 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 4 ++-- package.json | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/atom.gyp b/atom.gyp index 27b7ecd256b..969a0665f9f 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.36.11', + 'version%': '0.37.0', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 267df223e2b..6b504728ae3 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.36.11 + 0.37.0 CFBundleShortVersionString - 0.36.11 + 0.37.0 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 222c4ac4610..bdffd90effd 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,36,11,0 - PRODUCTVERSION 0,36,11,0 + FILEVERSION 0,37,0,0 + PRODUCTVERSION 0,37,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.36.11" + VALUE "FileVersion", "0.37.0" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.36.11" + VALUE "ProductVersion", "0.37.0" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 362e4dc7b88..1b1aee905ce 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -6,8 +6,8 @@ #define ATOM_VERSION_H #define ATOM_MAJOR_VERSION 0 -#define ATOM_MINOR_VERSION 36 -#define ATOM_PATCH_VERSION 11 +#define ATOM_MINOR_VERSION 37 +#define ATOM_PATCH_VERSION 0 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index 343f1baa8fc..6b6abb5bc68 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.36.11", + "version": "0.37.0", "devDependencies": { "asar": "^0.10.0", "eslint": "^2.1.0", From c9375688464f0e82435f481845810919f9fc9a73 Mon Sep 17 00:00:00 2001 From: "Brian R. Bondy" Date: Fri, 11 Mar 2016 20:38:53 -0500 Subject: [PATCH 471/688] Fix libffmpeg.dylib path for install_name_tool --- atom.gyp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom.gyp b/atom.gyp index 969a0665f9f..37a2c5d3a0a 100644 --- a/atom.gyp +++ b/atom.gyp @@ -489,7 +489,7 @@ 'action': [ 'install_name_tool', '-change', - '@loader_path/libffmpeg.dylib', + '/usr/local/lib/libffmpeg.dylib', '@rpath/libffmpeg.dylib', '${BUILT_PRODUCTS_DIR}/<(product_name) Framework.framework/Versions/A/<(product_name) Framework', ], From 96d271e57ce9e2eb6e9b2b611b7c513109c1fed8 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Sun, 13 Mar 2016 06:10:00 +0900 Subject: [PATCH 472/688] :memo: Update Korean docs as upstream [ci skip] --- docs-translations/ko-KR/api/browser-window.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index c5030e04d1a..1ebf7743c2f 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -401,6 +401,10 @@ var win = new BrowserWindow({ width: 800, height: 600 }); 윈도우에 포커스를 맞춥니다. +### `win.blur()` + +윈도우의 포커스를 없앱니다. + ### `win.isFocused()` 윈도우가 포커스되었는지 여부를 반환합니다. From 7569d180c9f73a22f0ea9a3373f6552bd759c230 Mon Sep 17 00:00:00 2001 From: Todd Wolfson Date: Sat, 12 Mar 2016 18:05:01 -0600 Subject: [PATCH 473/688] Added support for window.location on window.open windows --- lib/browser/guest-window-manager.js | 4 ++-- lib/renderer/override.js | 9 +++++++++ spec/chromium-spec.js | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index 50c6a62eb0c..bdd32af7a61 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -101,8 +101,8 @@ ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', function(event, guest ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', function() { var args, guestId, method, ref1; - guestId = arguments[1], method = arguments[2], args = 4 <= arguments.length ? slice.call(arguments, 3) : []; - return (ref1 = BrowserWindow.fromId(guestId)) != null ? ref1[method].apply(ref1, args) : void 0; + event = arguments[0], guestId = arguments[1], method = arguments[2], args = 4 <= arguments.length ? slice.call(arguments, 3) : []; + return event.returnValue = (ref1 = BrowserWindow.fromId(guestId)) != null ? ref1[method].apply(ref1, args) : void 0; }); ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', function(event, guestId, message, targetOrigin, sourceOrigin) { diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 2b0e48b3dd3..6717db931dc 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -57,6 +57,15 @@ var BrowserWindowProxy = (function() { return ipcRenderer.send('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'blur'); }; + Object.defineProperty(BrowserWindowProxy.prototype, 'location', { + get: function() { + return ipcRenderer.sendSync('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'getURL'); + }, + set: function(url) { + return ipcRenderer.sendSync('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'loadURL', url); + } + }); + BrowserWindowProxy.prototype.postMessage = function(message, targetOrigin) { if (targetOrigin == null) { targetOrigin = '*'; diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 67b2d263204..71cef125618 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -193,6 +193,32 @@ describe('chromium feature', function() { window.addEventListener('message', listener); b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', "show=no,width=" + size.width + ",height=" + size.height); }); + + it('defines a window.location getter', function(done) { + var b, targetURL; + targetURL = "file://" + fixtures + "/pages/base-page.html"; + b = window.open(targetURL); + BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { + assert.equal(b.location, targetURL); + b.close(); + done(); + }); + }); + + it('defines a window.location setter', function(done) { + // Load a page that definitely won't redirect + var b; + b = window.open("about:blank"); + BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { + // When it loads, redirect + b.location = "file://" + fixtures + "/pages/base-page.html"; + BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { + // After our second redirect, cleanup and callback + b.close(); + done(); + }); + }); + }); }); describe('window.opener', function() { From 78c66da9e80c61d9d5d2cf70bccb1a6dda23e7ad Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 13 Mar 2016 10:11:15 +0900 Subject: [PATCH 474/688] Update brightray: dealy loading powrprof.dll --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index c1f3bb4ecf4..d6bafa3ac1b 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit c1f3bb4ecf4cacb33bf56b9ebd3656a4defbeb64 +Subproject commit d6bafa3ac1b56b24e8944ebbc87ed51ad417a21d From d96e03c40251f53fb5724b7081373d0c0a1a96b6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 13 Mar 2016 10:11:26 +0900 Subject: [PATCH 475/688] Bump v0.37.1 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index 37a2c5d3a0a..24456ca479d 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.37.0', + 'version%': '0.37.1', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 6b504728ae3..613fa39e9da 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.37.0 + 0.37.1 CFBundleShortVersionString - 0.37.0 + 0.37.1 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index bdffd90effd..3b587f62da8 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,37,0,0 - PRODUCTVERSION 0,37,0,0 + FILEVERSION 0,37,1,0 + PRODUCTVERSION 0,37,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.37.0" + VALUE "FileVersion", "0.37.1" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.37.0" + VALUE "ProductVersion", "0.37.1" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 1b1aee905ce..27b3fec626f 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 37 -#define ATOM_PATCH_VERSION 0 +#define ATOM_PATCH_VERSION 1 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index 6b6abb5bc68..a4e3686bffd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.37.0", + "version": "0.37.1", "devDependencies": { "asar": "^0.10.0", "eslint": "^2.1.0", From 29609b6e5d272bb71fbb9b4eccfe50cb08f3e9fb Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Sun, 13 Mar 2016 14:15:11 +0800 Subject: [PATCH 476/688] add powerMonitor first --- docs-translations/zh-CN/api/power-monitor.md | 36 ++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs-translations/zh-CN/api/power-monitor.md diff --git a/docs-translations/zh-CN/api/power-monitor.md b/docs-translations/zh-CN/api/power-monitor.md new file mode 100644 index 00000000000..3394b4a284e --- /dev/null +++ b/docs-translations/zh-CN/api/power-monitor.md @@ -0,0 +1,36 @@ +# powerMonitor + +`power-monitor`模块是用来监听能源区改变的.只能在主进程中使用.在 `app` 模块的 `ready` 事件触发之后就不能使用这个模块了. + +例如: + +```javascript +app.on('ready', function() { + require('electron').powerMonitor.on('suspend', function() { + console.log('The system is going to sleep'); + }); +}); +``` + +## 事件 + +`power-monitor` 模块可以触发下列事件: + +### Event: 'suspend' + +在系统挂起的时候触发. + +### Event: 'resume' + +在系统恢复继续工作的时候触发. +Emitted when system is resuming. + +### Event: 'on-ac' + +在系统使用交流电的时候触发. +Emitted when the system changes to AC power. + +### Event: 'on-battery' + +在系统使用电池电源的时候触发. +Emitted when system changes to battery power. \ No newline at end of file From d96836e608ac33b501cb1d139313d97727d35197 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Sun, 13 Mar 2016 22:06:19 +0800 Subject: [PATCH 477/688] add power-save-blocker first --- .../zh-CN/api/power-save-blocker.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 docs-translations/zh-CN/api/power-save-blocker.md diff --git a/docs-translations/zh-CN/api/power-save-blocker.md b/docs-translations/zh-CN/api/power-save-blocker.md new file mode 100644 index 00000000000..3a045eaea77 --- /dev/null +++ b/docs-translations/zh-CN/api/power-save-blocker.md @@ -0,0 +1,48 @@ +# powerSaveBlocker + +`powerSaveBlocker` 模块是用来阻止应用系统进入睡眠模式的,因此这允许应用保持系统和屏幕继续工作. + +例如: + +```javascript +const powerSaveBlocker = require('electron').powerSaveBlocker; + +var id = powerSaveBlocker.start('prevent-display-sleep'); +console.log(powerSaveBlocker.isStarted(id)); + +powerSaveBlocker.stop(id); +``` + +## 方法 + +`powerSaveBlocker` 模块有如下方法: + +### `powerSaveBlocker.start(type)` + +* `type` String - 强行保存阻塞类型. + * `prevent-app-suspension` - 阻止应用挂起. + 保持系统活跃,但是允许屏幕不亮. 用例: + 下载文件或者播放音频. + * `prevent-display-sleep`- 阻止应用进入休眠. 保持系统和屏幕活跃,屏幕一直亮. 用例: 播放音频. + +开始阻止系统进入睡眠模式.返回一个整数,这个整数标识了保持活跃的blocker. + +**注意:** `prevent-display-sleep` 有更高的优先级 +`prevent-app-suspension`. 只有最高优先级生效. 换句话说, `prevent-display-sleep` 优先级永远高于 +`prevent-app-suspension`. + +例如, A 请求调用了 `prevent-app-suspension`, B请求调用了 `prevent-display-sleep`. `prevent-display-sleep` +将一直工作,直到B停止调用. 在那之后, `prevent-app-suspension` +才起效. + +### `powerSaveBlocker.stop(id)` + +* `id` Integer - 通过 `powerSaveBlocker.start` 返回的保持活跃的 blocker id. + +让指定blocker 停止活跃. + +### `powerSaveBlocker.isStarted(id)` + +* `id` Integer - 通过 `powerSaveBlocker.start` 返回的保持活跃的 blocker id. + +返回 boolean, 是否对应的 `powerSaveBlocker` 已经启动. \ No newline at end of file From 48064ee7e9a81ed431649e883d42e8e0908da4e4 Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 14 Mar 2016 03:53:39 +0530 Subject: [PATCH 478/688] browser: fix retrieving webcontents from associated process id --- atom/browser/atom_browser_client.cc | 9 ++------- atom/browser/atom_permission_manager.cc | 16 ++++++---------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index ca12723bb37..63a1ea46b16 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -46,11 +46,6 @@ namespace atom { namespace { -// The default routing id of WebContents. -// In Electron each RenderProcessHost only has one WebContents, so this ID is -// same for every WebContents. -int kDefaultRoutingID = 1; - // Next navigation should not restart renderer process. bool g_suppress_renderer_process_restart = false; @@ -278,8 +273,8 @@ brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( void AtomBrowserClient::WebNotificationAllowed( int render_process_id, const base::Callback& callback) { - content::WebContents* web_contents = content::WebContents::FromRenderViewHost( - content::RenderViewHost::FromID(render_process_id, kDefaultRoutingID)); + content::WebContents* web_contents = + WebContentsPreferences::GetWebContentsFromProcessID(render_process_id); if (!web_contents) { callback.Run(false); return; diff --git a/atom/browser/atom_permission_manager.cc b/atom/browser/atom_permission_manager.cc index 720d1f93b32..f7523c07ff8 100644 --- a/atom/browser/atom_permission_manager.cc +++ b/atom/browser/atom_permission_manager.cc @@ -6,6 +6,7 @@ #include +#include "atom/browser/web_contents_preferences.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/permission_type.h" #include "content/public/browser/render_frame_host.h" @@ -17,17 +18,12 @@ namespace atom { namespace { -// Must be kept in sync with atom_browser_client.cc -int kDefaultRoutingID = 2; - bool WebContentsDestroyed(int process_id) { - auto rvh = content::RenderViewHost::FromID(process_id, kDefaultRoutingID); - if (rvh) { - auto contents = content::WebContents::FromRenderViewHost(rvh); - return contents->IsBeingDestroyed(); - } - - return true; + auto contents = + WebContentsPreferences::GetWebContentsFromProcessID(process_id); + if (!contents) + return true; + return contents->IsBeingDestroyed(); } } // namespace From 8378cbb1e84bad2380ef833147b79ddc2226bccf Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 14 Mar 2016 06:49:45 +0530 Subject: [PATCH 479/688] webcontents: provide position of match with found-in-page event --- atom/browser/api/atom_api_web_contents.cc | 1 + docs/api/web-contents.md | 1 + docs/api/web-view-tag.md | 1 + spec/webview-spec.js | 13 +++++++++++-- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index c8b597704cd..4a548cb4a33 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -456,6 +456,7 @@ void WebContents::FindReply(content::WebContents* web_contents, result.Set("requestId", request_id); result.Set("selectionArea", selection_rect); result.Set("finalUpdate", final_update); + result.Set("activeMatchOrdinal", active_match_ordinal); Emit("found-in-page", result); } else if (final_update) { result.Set("requestId", request_id); diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 8eda16b6860..5295b79ceb3 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -259,6 +259,7 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - Indicates if more responses are to follow. + * `activeMatchOrdinal` Integer (optional) - Position of the active match. * `matches` Integer (optional) - Number of Matches. * `selectionArea` Object (optional) - Coordinates of first match region. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index fa48ef60f3f..cba48e40db1 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -573,6 +573,7 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - Indicates if more responses are to follow. + * `activeMatchOrdinal` Integer (optional) - Position of the active match. * `matches` Integer (optional) - Number of Matches. * `selectionArea` Object (optional) - Coordinates of first match region. diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 5963709e6f0..2d0a6282be3 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -642,12 +642,21 @@ describe(' tag', function() { describe('found-in-page event', function() { it('emits when a request is made', function(done) { var requestId = null; + var totalMatches = null; + var activeMatchOrdinal = []; var listener = function(e) { assert.equal(e.result.requestId, requestId); if (e.result.finalUpdate) { assert.equal(e.result.matches, 3); - webview.stopFindInPage("clearSelection"); - done(); + totalMatches = e.result.matches; + listener2(); + } else { + activeMatchOrdinal.push(e.result.activeMatchOrdinal); + if (e.result.activeMatchOrdinal == totalMatches) { + assert.deepEqual(activeMatchOrdinal, [1, 2, 3]); + webview.stopFindInPage("clearSelection"); + done(); + } } }; var listener2 = function() { From 92a9c49a77b59c71408baad2483783747e41391d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 14 Mar 2016 10:39:33 +0900 Subject: [PATCH 480/688] Update brightray for atom/brightray#203 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index d6bafa3ac1b..bde17bffdf5 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit d6bafa3ac1b56b24e8944ebbc87ed51ad417a21d +Subproject commit bde17bffdf5ff978d5d831bdebb62d12bca6c715 From b3da5370c06e5e0c7755ba633ae0e1bcef7ca640 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Sun, 13 Mar 2016 20:08:09 -0700 Subject: [PATCH 481/688] Add a new method to get the representation of an image --- atom/common/api/atom_api_native_image.h | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index 1f0fe946ba5..8bc21304041 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -61,6 +61,7 @@ class NativeImage : public mate::Wrappable { private: v8::Local ToPNG(v8::Isolate* isolate); v8::Local ToJPEG(v8::Isolate* isolate, int quality); + v8::Local AsNativeRepresentation(v8::Isolate* isolate, mate::Arguments* args); std::string ToDataURL(); bool IsEmpty(); gfx::Size GetSize(); From 262abc43f80811747c8689b85a2343ff42966a02 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Sun, 13 Mar 2016 20:08:53 -0700 Subject: [PATCH 482/688] First hack at being able to return NSImage pointers --- atom/common/api/atom_api_native_image.cc | 56 ++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 69ead046458..aac11fdfaaf 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -58,6 +58,20 @@ ScaleFactorPair kScaleFactorPairs[] = { { "@2.5x" , 2.5f }, }; +enum NativeRepresentation { + INVALID = 0, + AS_NSIMAGE, +}; + +struct NativeRepresentationPair { + const char* name; + NativeRepresentation rep; +}; + +NativeRepresentationPair kNativeRepresentations[] { + { "nsimage", NativeRepresentation::AS_NSIMAGE }, +}; + float GetScaleFactorFromPath(const base::FilePath& path) { std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe()); @@ -184,6 +198,7 @@ mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder( template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate) .SetMethod("toPng", &NativeImage::ToPNG) .SetMethod("toJpeg", &NativeImage::ToJPEG) + .SetMethod("asNativeRepresentation", &NativeImage::AsNativeRepresentation) .SetMethod("toDataURL", &NativeImage::ToDataURL) .SetMethod("toDataUrl", &NativeImage::ToDataURL) // deprecated. .SetMethod("isEmpty", &NativeImage::IsEmpty) @@ -221,6 +236,47 @@ std::string NativeImage::ToDataURL() { return data_url; } +v8::Local NativeImage::AsNativeRepresentation(v8::Isolate* isolate, mate::Arguments* args) { + NativeRepresentation desiredRep = NativeRepresentation::INVALID; + void* ptr = nullptr; + std::string type; + + if (!args->GetNext(&type)) { + args->ThrowError(); + goto out; + } + + for (const NativeRepresentationPair& item : kNativeRepresentations) { + if (type.compare(item.name) == 0) { + desiredRep = item.rep; + break; + } + } + + if (desiredRep == NativeRepresentation::INVALID) { + args->ThrowError(); + goto out; + } + + switch (desiredRep) { +#if defined(OS_MACOSX) + case NativeRepresentation::AS_NSIMAGE: + ptr = reinterpret_cast(image_.AsNSImage()); + break; +#endif + default: + args->ThrowError(); + break; + } + +out: + + return node::Buffer::Copy( + isolate, + reinterpret_cast(ptr), + sizeof(void*)).ToLocalChecked(); +} + bool NativeImage::IsEmpty() { return image_.IsEmpty(); } From 5dea4b9b1cdc402e36749aa64b2e6e515e04f5fb Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Sun, 13 Mar 2016 20:11:43 -0700 Subject: [PATCH 483/688] Add documentation --- docs/api/native-image.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/api/native-image.md b/docs/api/native-image.md index 515e89fba1a..2cae12feb47 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -133,6 +133,13 @@ Returns a [Buffer][buffer] that contains the image's `JPEG` encoded data. Returns the data URL of the image. +### `image.asNativeRepresentation(type)` + +Returns a pointer to an underlying native type (encoded as a [Buffer][buffer]) which can be used with native APIs. Note that in many cases, this pointer is a weak pointer to the underlying native image not a copy, so you _must_ ensure that the associated `nativeImage` instance is kept around. + +* `type` String (**required**) - one of: + * `nsimage` - (OS X only) a pointer to an `NSImage` + ### `image.isEmpty()` Returns a boolean whether the image is empty. From 7233c83874e6444a96045bffe511c87bf866361f Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Sun, 13 Mar 2016 20:18:03 -0700 Subject: [PATCH 484/688] Linting --- atom/common/api/atom_api_native_image.cc | 19 +++++++++++-------- atom/common/api/atom_api_native_image.h | 4 +++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index aac11fdfaaf..7a84f999949 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -198,7 +198,8 @@ mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder( template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate) .SetMethod("toPng", &NativeImage::ToPNG) .SetMethod("toJpeg", &NativeImage::ToJPEG) - .SetMethod("asNativeRepresentation", &NativeImage::AsNativeRepresentation) + .SetMethod("asNativeRepresentation", + &NativeImage::AsNativeRepresentation) .SetMethod("toDataURL", &NativeImage::ToDataURL) .SetMethod("toDataUrl", &NativeImage::ToDataURL) // deprecated. .SetMethod("isEmpty", &NativeImage::IsEmpty) @@ -236,28 +237,30 @@ std::string NativeImage::ToDataURL() { return data_url; } -v8::Local NativeImage::AsNativeRepresentation(v8::Isolate* isolate, mate::Arguments* args) { +v8::Local NativeImage::AsNativeRepresentation( + v8::Isolate* isolate, + mate::Arguments* args) { NativeRepresentation desiredRep = NativeRepresentation::INVALID; void* ptr = nullptr; std::string type; - + if (!args->GetNext(&type)) { args->ThrowError(); goto out; } - + for (const NativeRepresentationPair& item : kNativeRepresentations) { if (type.compare(item.name) == 0) { desiredRep = item.rep; break; } } - + if (desiredRep == NativeRepresentation::INVALID) { args->ThrowError(); goto out; } - + switch (desiredRep) { #if defined(OS_MACOSX) case NativeRepresentation::AS_NSIMAGE: @@ -268,9 +271,9 @@ v8::Local NativeImage::AsNativeRepresentation(v8::Isolate* isolate, m args->ThrowError(); break; } - + out: - + return node::Buffer::Copy( isolate, reinterpret_cast(ptr), diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index 8bc21304041..8b1329d2848 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -61,7 +61,9 @@ class NativeImage : public mate::Wrappable { private: v8::Local ToPNG(v8::Isolate* isolate); v8::Local ToJPEG(v8::Isolate* isolate, int quality); - v8::Local AsNativeRepresentation(v8::Isolate* isolate, mate::Arguments* args); + v8::Local AsNativeRepresentation( + v8::Isolate* isolate, + mate::Arguments* args); std::string ToDataURL(); bool IsEmpty(); gfx::Size GetSize(); From 248ac5c37b6eeeaefca70d32cbc3adf737a7da93 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Sun, 13 Mar 2016 20:25:49 -0700 Subject: [PATCH 485/688] Add unit tests --- spec/api-native-image-spec.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index 043a914578c..587ea876f29 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -34,5 +34,32 @@ describe('nativeImage module', () => { assert.equal(image.getSize().height, 190); assert.equal(image.getSize().width, 538); }); + + it('Gets an NSImage pointer on OS X', () => { + if (process.platform !== 'darwin') return; + + const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; + const image = nativeImage.createFromPath(imagePath); + const nsimage = image.asNativeRepresentation('nsimage'); + + assert.equal(nsimage.length, 8); + + // If all bytes are null, that's Bad + assert.equal(nsimage.reduce((acc,x) => acc || (x != 0)), true); + }); + + it('Throws when asNativeRepresentation gets a bogus value', () => { + const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; + const image = nativeImage.createFromPath(imagePath); + + let shouldDie = true; + try { + image.asNativeRepresentation('__foobar__'); + } catch (e) { + shouldDie = false; + } + + assert.equal(shouldDie, false); + }); }); }); From 63d917482226d5ce86038262fcd1993604883bbd Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Sun, 13 Mar 2016 20:27:44 -0700 Subject: [PATCH 486/688] :fire: build warning on Win32 --- atom/common/api/atom_api_native_image.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 7a84f999949..6c22830f674 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -267,6 +267,7 @@ v8::Local NativeImage::AsNativeRepresentation( ptr = reinterpret_cast(image_.AsNSImage()); break; #endif + case NativeRepresentation::INVALID: default: args->ThrowError(); break; From 9a13d559e9c774c2f84a77af2663f8a81001ca30 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 14 Mar 2016 13:59:31 +0900 Subject: [PATCH 487/688] Leak the JavascriptEnvironment on exit This is to work around the bug that V8 would be waiting for background tasks to finish on exit, while somehow it waits forever in Electron, more about this can be found at https://github.com/atom/electron/issues/4767. On the other handle there is actually no need to gracefully shutdown V8 on exit in the main process, we already ensured all necessary resources get cleaned up, and it would make quitting faster. --- atom/browser/atom_browser_main_parts.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index a046f34287e..a711c1c8d2b 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -46,6 +46,14 @@ AtomBrowserMainParts::AtomBrowserMainParts() } AtomBrowserMainParts::~AtomBrowserMainParts() { + // Leak the JavascriptEnvironment on exit. + // This is to work around the bug that V8 would be waiting for background + // tasks to finish on exit, while somehow it waits forever in Electron, more + // about this can be found at https://github.com/atom/electron/issues/4767. + // On the other handle there is actually no need to gracefully shutdown V8 + // on exit in the main process, we already ensured all necessary resources get + // cleaned up, and it would make quitting faster. + ignore_result(js_env_.release()); } // static @@ -172,14 +180,6 @@ void AtomBrowserMainParts::PostMainMessageLoopRun() { ++iter; callback.Run(); } - - // Destroy JavaScript environment immediately after running destruction - // callbacks. - gc_timer_.Stop(); - node_debugger_.reset(); - atom_bindings_.reset(); - node_bindings_.reset(); - js_env_.reset(); } } // namespace atom From 152e6af4b4c962d118a14e719544e4c4fdd08d55 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 14 Mar 2016 14:54:45 +0900 Subject: [PATCH 488/688] spec: Add test case for #4785 --- spec/api-app-spec.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index cbf8223401c..1b12f6f733c 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -7,7 +7,11 @@ const app = remote.require('electron').app; const BrowserWindow = remote.require('electron').BrowserWindow; describe('electron module', function() { - it ('can prevent exposing internal modules to require', function(done) { + it('allows old style require by default', function() { + require('shell'); + }); + + it('can prevent exposing internal modules to require', function(done) { const electron = require('electron'); const clipboard = require('clipboard'); assert.equal(typeof clipboard, 'object'); From 81a16b424f5760f091885d7ec3d2708d91aa2cf9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 14 Mar 2016 16:28:01 +0900 Subject: [PATCH 489/688] Add extension to filename automatically for GTK+ save dialog --- atom/browser/ui/file_dialog_gtk.cc | 34 +++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/atom/browser/ui/file_dialog_gtk.cc b/atom/browser/ui/file_dialog_gtk.cc index ed79449655f..5a82a849395 100644 --- a/atom/browser/ui/file_dialog_gtk.cc +++ b/atom/browser/ui/file_dialog_gtk.cc @@ -39,7 +39,8 @@ class FileChooserDialog { const std::string& title, const base::FilePath& default_path, const Filters& filters) - : dialog_scope_(parent_window) { + : dialog_scope_(parent_window), + filters_(filters) { const char* confirm_text = GTK_STOCK_OK; if (action == GTK_FILE_CHOOSER_ACTION_SAVE) confirm_text = GTK_STOCK_SAVE; @@ -111,7 +112,7 @@ class FileChooserDialog { base::FilePath GetFileName() const { gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog_)); - base::FilePath path(filename); + base::FilePath path = AddExtensionForFilename(filename); g_free(filename); return path; } @@ -121,7 +122,8 @@ class FileChooserDialog { GSList* filenames = gtk_file_chooser_get_filenames( GTK_FILE_CHOOSER(dialog_)); for (GSList* iter = filenames; iter != NULL; iter = g_slist_next(iter)) { - base::FilePath path(static_cast(iter->data)); + base::FilePath path = AddExtensionForFilename( + static_cast(iter->data)); g_free(iter->data); paths.push_back(path); } @@ -135,11 +137,13 @@ class FileChooserDialog { private: void AddFilters(const Filters& filters); + base::FilePath AddExtensionForFilename(const gchar* filename) const; atom::NativeWindow::DialogScope dialog_scope_; GtkWidget* dialog_; + Filters filters_; SaveDialogCallback save_callback_; OpenDialogCallback open_callback_; @@ -184,6 +188,30 @@ void FileChooserDialog::AddFilters(const Filters& filters) { } } +base::FilePath FileChooserDialog::AddExtensionForFilename( + const gchar* filename) const { + base::FilePath path(filename); + GtkFileFilter* selected_filter = + gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog_)); + if (!selected_filter) + return path; + + GSList* filters = gtk_file_chooser_list_filters(GTK_FILE_CHOOSER(dialog_)); + int i = g_slist_index(filters, selected_filter); + g_slist_free(filters); + if (i >= filters_.size()) + return path; + + const auto& extensions = filters_[i].second; + for (const auto& extension : extensions) { + if (extension == "*" || path.MatchesExtension("." + extension)) + return path; + } + + return path.AddExtension(extensions[0]); +} + + } // namespace bool ShowOpenDialog(atom::NativeWindow* parent_window, From 06a8db8a66c4ccb07bf1c329d4ee6f71ba56a1f5 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Mon, 14 Mar 2016 15:43:04 +0800 Subject: [PATCH 490/688] add protocol && session first --- docs-translations/zh-CN/api/protocol.md | 183 +++++++++ docs-translations/zh-CN/api/session.md | 481 ++++++++++++++++++++++++ 2 files changed, 664 insertions(+) create mode 100644 docs-translations/zh-CN/api/protocol.md create mode 100644 docs-translations/zh-CN/api/session.md diff --git a/docs-translations/zh-CN/api/protocol.md b/docs-translations/zh-CN/api/protocol.md new file mode 100644 index 00000000000..a7dab97c5d5 --- /dev/null +++ b/docs-translations/zh-CN/api/protocol.md @@ -0,0 +1,183 @@ +# 协议 + +`protocol` 模块可以注册一个自定义协议,或者使用一个已经存在的协议. + +例子,使用一个与 `file://` 功能相似的协议 : + +```javascript +const electron = require('electron'); +const app = electron.app; +const path = require('path'); + +app.on('ready', function() { + var protocol = electron.protocol; + protocol.registerFileProtocol('atom', function(request, callback) { + var url = request.url.substr(7); + callback({path: path.normalize(__dirname + '/' + url)}); + }, function (error) { + if (error) + console.error('Failed to register protocol') + }); +}); +``` + +**注意:** 这个模块只有在 `app` 模块的 `ready` 事件触发之后才可使用. + +## 方法 + +`protocol` 模块有如下方法: + +### `protocol.registerStandardSchemes(schemes)` + +* `schemes` Array - 将一个自定义的方案注册为标准的方案. + +一个标准的 `scheme` 遵循 RFC 3986 的 +[generic URI syntax](https://tools.ietf.org/html/rfc3986#section-3) 标准. 这包含了 `file:` 和 `filesystem:`. + +### `protocol.registerServiceWorkerSchemes(schemes)` + +* `schemes` Array - 将一个自定义的方案注册为处理 service workers. + +### `protocol.registerFileProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (可选) + +注册一个协议,用来发送响应文件.当通过这个协议来发起一个请求的时候,将使用 `handler(request, callback)` 来调用 +`handler` .当 `scheme` 被成功注册或者完成(错误)时失败,将使用 `completion(null)` 调用 `completion`. + +* `request` Object + * `url` String + * `referrer` String + * `method` String + * `uploadData` Array (可选) +* `callback` Function + +`uploadData` 是一个 `data` 对象数组: + +* `data` Object + * `bytes` Buffer - 被发送的内容. + * `file` String - 上传的文件路径. + +为了处理请求,调用 `callback` 时需要使用文件路径或者一个带 `path` 参数的对象, 例如 `callback(filePath)` 或 +`callback({path: filePath})`. + +当不使用任何参数调用 `callback` 时,你可以指定一个数字或一个带有 `error` 参数的对象,来标识 `request` 失败.你可以使用的 error number 可以参考 +[net error list][net-error]. + +默认 `scheme` 会被注册为一个 `http:` 协议,它与遵循 "generic URI syntax" 规则的协议解析不同,例如 `file:` ,所以你或许应该调用 `protocol.registerStandardSchemes` 来创建一个标准的 scheme. + +### `protocol.registerBufferProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (可选) + +注册一个 `scheme` 协议,用来发送响应 `Buffer` . + +这个方法的用法类似 `registerFileProtocol`,除非使用一个 `Buffer` 对象,或一个有 `data`, +`mimeType`, 和 `charset` 属性的对象来调用 `callback` . + +例子: + +```javascript +protocol.registerBufferProtocol('atom', function(request, callback) { + callback({mimeType: 'text/html', data: new Buffer('
Response
')}); +}, function (error) { + if (error) + console.error('Failed to register protocol') +}); +``` + +### `protocol.registerStringProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (可选) + +注册一个 `scheme` 协议,用来发送响应 `String` . + +这个方法的用法类似 `registerFileProtocol`,除非使用一个 `String` 对象,或一个有 `data`, +`mimeType`, 和 `charset` 属性的对象来调用 `callback` . + +### `protocol.registerHttpProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (可选) + +注册一个 `scheme` 协议,用来发送 HTTP 请求作为响应. + +这个方法的用法类似 `registerFileProtocol`,除非使用一个 `redirectRequest` 对象,或一个有 `url`, `method`, +`referrer`, `uploadData` 和 `session` 属性的对象来调用 `callback` . + +* `redirectRequest` Object + * `url` String + * `method` String + * `session` Object (可选) + * `uploadData` Object (可选) + +默认这个 HTTP 请求会使用当前 session .如果你想使用不同的session值,你应该设置 `session` 为 `null`. + +POST 请求应当包含 `uploadData` 对象. + +* `uploadData` object + * `contentType` String - 内容的 MIME type. + * `data` String - 被发送的内容. + +### `protocol.unregisterProtocol(scheme[, completion])` + +* `scheme` String +* `completion` Function (可选) + +注销自定义协议 `scheme`. + +### `protocol.isProtocolHandled(scheme, callback)` + +* `scheme` String +* `callback` Function + +将使用一个布尔值来调用 `callback` ,这个布尔值标识了是否已经存在 `scheme` 的句柄了. + +### `protocol.interceptFileProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (可选) + +拦截 `scheme` 协议并且使用 `handler` 作为协议的新的句柄来发送响应文件. + +### `protocol.interceptStringProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (可选) + +拦截 `scheme` 协议并且使用 `handler` 作为协议的新的句柄来发送响应 `String`. + +### `protocol.interceptBufferProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (可选) + +拦截 `scheme` 协议并且使用 `handler` 作为协议的新的句柄来发送响应 `Buffer`. + +### `protocol.interceptHttpProtocol(scheme, handler[, completion])` + +* `scheme` String +* `handler` Function +* `completion` Function (optional) + +拦截 `scheme` 协议并且使用 `handler` 作为协议的新的句柄来发送新的响应 HTTP 请求. +Intercepts `scheme` protocol and uses `handler` as the protocol's new handler +which sends a new HTTP request as a response. + +### `protocol.uninterceptProtocol(scheme[, completion])` + +* `scheme` String +* `completion` Function +取消对 `scheme` 的拦截,使用它的原始句柄进行处理. + +[net-error]: https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h \ No newline at end of file diff --git a/docs-translations/zh-CN/api/session.md b/docs-translations/zh-CN/api/session.md new file mode 100644 index 00000000000..b9664c08e65 --- /dev/null +++ b/docs-translations/zh-CN/api/session.md @@ -0,0 +1,481 @@ +# session + +`session` 模块可以用来创建一个新的 `Session` 对象. + +你也可以通过使用 [`webContents`](web-contents.md) 的属性 `session` 来使用一个已有页面的 `session` ,`webContents` 是[`BrowserWindow`](browser-window.md) 的属性. + +```javascript +const BrowserWindow = require('electron').BrowserWindow; + +var win = new BrowserWindow({ width: 800, height: 600 }); +win.loadURL("http://github.com"); + +var ses = win.webContents.session; +``` + +## 方法 + +`session` 模块有如下方法: + +### session.fromPartition(partition) + +* `partition` String + +从字符串 `partition` 返回一个新的 `Session` 实例. + +如果 `partition` 以 `persist:` 开头,那么这个page将使用一个持久的 session,这个 session 将对应用的所有 page 可用.如果没前缀,这个 page 将使用一个历史 session.如果 `partition` 为空,那么将返回应用的默认 session . + +## 属性 + +`session` 模块有如下属性: + +### session.defaultSession + +返回应用的默认 session 对象. + +## Class: Session + +可以在 `session` 模块中创建一个 `Session` 对象 : + +```javascript +const session = require('electron').session; + +var ses = session.fromPartition('persist:name'); +``` + +### 实例事件 + +实例 `Session` 有以下事件: + +#### Event: 'will-download' + +* `event` Event +* `item` [DownloadItem](download-item.md) +* `webContents` [WebContents](web-contents.md) + +当 Electron 将要从 `webContents` 下载 `item` 时触发. + +调用 `event.preventDefault()` 可以取消下载,并且在进程的下个 tick中,这个 `item` 也不可用. + +```javascript +session.defaultSession.on('will-download', function(event, item, webContents) { + event.preventDefault(); + require('request')(item.getURL(), function(data) { + require('fs').writeFileSync('/somewhere', data); + }); +}); +``` + +### 实例方法 + +实例 `Session` 有以下方法: + +#### `ses.cookies` + +`cookies` 赋予你全力来查询和修改 cookies. 例如: + +```javascript +// 查询所有 cookies. +session.defaultSession.cookies.get({}, function(error, cookies) { + console.log(cookies); +}); + +// 查询与指定 url 相关的所有 cookies. +session.defaultSession.cookies.get({ url : "http://www.github.com" }, function(error, cookies) { + console.log(cookies); +}); + +// 设置 cookie; +// may overwrite equivalent cookies if they exist. +var cookie = { url : "http://www.github.com", name : "dummy_name", value : "dummy" }; +session.defaultSession.cookies.set(cookie, function(error) { + if (error) + console.error(error); +}); +``` + +#### `ses.cookies.get(filter, callback)` + +* `filter` Object + * `url` String (可选) - 与获取 cookies 相关的 + `url`.不设置的话就是从所有 url 获取 cookies . + * `name` String (可选) - 通过 name 过滤 cookies. + * `domain` String (可选) - 获取对应域名或子域名的 cookies . + * `path` String (可选) - 获取对应路径的 cookies . + * `secure` Boolean (可选) - 通过安全性过滤 cookies. + * `session` Boolean (可选) - 过滤掉 session 或 持久的 cookies. +* `callback` Function + +发送一个请求,希望获得所有匹配 `details` 的 cookies, +在完成的时候,将通过 `callback(error, cookies)` 调用 `callback`. + +`cookies`是一个 `cookie` 对象. + +* `cookie` Object + * `name` String - cookie 名. + * `value` String - cookie值. + * `domain` String - cookie域名. + * `hostOnly` String - 是否 cookie 是一个 host-only cookie. + * `path` String - cookie路径. + * `secure` Boolean - 是否是安全 cookie. + * `httpOnly` Boolean - 是否只是 HTTP cookie. + * `session` Boolean - cookie 是否是一个 session cookie 或一个带截至日期的持久 + cookie . + * `expirationDate` Double (可选) - cookie的截至日期,数值为UNIX纪元以来的秒数. 对session cookies 不提供. + +#### `ses.cookies.set(details, callback)` + +* `details` Object + * `url` String - 与获取 cookies 相关的 + `url`. + * `name` String - cookie 名. 忽略默认为空. + * `value` String - cookie 值. 忽略默认为空. + * `domain` String - cookie的域名. 忽略默认为空. + * `path` String - cookie 的路径. 忽略默认为空. + * `secure` Boolean - 是否已经进行了安全性标识. 默认为 + false. + * `session` Boolean - 是否已经 HttpOnly 标识. 默认为 false. + * `expirationDate` Double - cookie的截至日期,数值为UNIX纪元以来的秒数. 如果忽略, cookie 变为 session cookie. +* `callback` Function + +使用 `details` 设置 cookie, 完成时使用 `callback(error)` 掉哟个 `callback` . + +#### `ses.cookies.remove(url, name, callback)` + +* `url` String - 与 cookies 相关的 + `url`. +* `name` String - 需要删除的 cookie 名. +* `callback` Function + +删除匹配 `url` 和 `name` 的 cookie, 完成时使用 `callback()`调用`callback`. + +#### `ses.getCacheSize(callback)` + +* `callback` Function + * `size` Integer - 单位 bytes 的缓存 size. + +返回 session 的当前缓存 size . + +#### `ses.clearCache(callback)` + +* `callback` Function - 操作完成时调用 + +清空 session 的 HTTP 缓存. + +#### `ses.clearStorageData([options, ]callback)` + +* `options` Object (可选) + * `origin` String - 应当遵循 `window.location.origin` 的格式 + `scheme://host:port`. + * `storages` Array - 需要清理的 storages 类型, 可以包含 : + `appcache`, `cookies`, `filesystem`, `indexdb`, `local storage`, + `shadercache`, `websql`, `serviceworkers` + * `quotas` Array - 需要清理的类型指标, 可以包含: + `temporary`, `persistent`, `syncable`. +* `callback` Function - 操作完成时调用. + +清除 web storages 的数据. + +#### `ses.flushStorageData()` + +将没有写入的 DOMStorage 写入磁盘. + +#### `ses.setProxy(config, callback)` + +* `config` Object + * `pacScript` String - 与 PAC 文件相关的 URL. + * `proxyRules` String - 代理使用规则. +* `callback` Function - 操作完成时调用. + +设置 proxy settings. + +当 `pacScript` 和 `proxyRules` 一同提供时,将忽略 `proxyRules`,并且使用 `pacScript` 配置 . + +`proxyRules` 需要遵循下面的规则: + +``` +proxyRules = schemeProxies[";"] +schemeProxies = ["="] +urlScheme = "http" | "https" | "ftp" | "socks" +proxyURIList = [","] +proxyURL = ["://"][":"] +``` + +例子: + +* `http=foopy:80;ftp=foopy2` - 为 `http://` URL 使用 HTTP 代理 `foopy:80` , 和为 `ftp://` URL + HTTP 代理 `foopy2:80` . +* `foopy:80` - 为所有 URL 使用 HTTP 代理 `foopy:80` . +* `foopy:80,bar,direct://` - 为所有 URL 使用 HTTP 代理 `foopy:80` , 如果 `foopy:80` 不可用,则切换使用 `bar`, 再往后就不使用代理了. +* `socks4://foopy` - 为所有 URL 使用 SOCKS v4 代理 `foopy:1080`. +* `http=foopy,socks5://bar.com` - 为所有 URL 使用 HTTP 代理 `foopy`, 如果 `foopy`不可用,则切换到 SOCKS5 代理 `bar.com`. +* `http=foopy,direct://` - 为所有http url 使用 HTTP 代理,如果 `foopy`不可用,则不使用代理. +* `http=foopy;socks=foopy2` - 为所有http url 使用 `foopy` 代理,为所有其他 url 使用 `socks4://foopy2` 代理. + +### `ses.resolveProxy(url, callback)` + +* `url` URL +* `callback` Function + +解析 `url` 的代理信息.当请求完成的时候使用 `callback(proxy)` 调用 `callback`. + +#### `ses.setDownloadPath(path)` + +* `path` String - 下载地址 + +设置下载保存地址,默认保存地址为各自 app 应用的 `Downloads`目录. + +#### `ses.enableNetworkEmulation(options)` + +* `options` Object + * `offline` Boolean - 是否模拟网络故障. + * `latency` Double - 每毫秒的 RTT + * `downloadThroughput` Double - 每 Bps 的下载速率. + * `uploadThroughput` Double - 每 Bps 的上载速率. + +通过给定配置的 `session` 来模拟网络. + +```javascript +// 模拟 GPRS 连接,使用的 50kbps 流量,500 毫秒的 rtt. +window.webContents.session.enableNetworkEmulation({ + latency: 500, + downloadThroughput: 6400, + uploadThroughput: 6400 +}); + +// 模拟网络故障. +window.webContents.session.enableNetworkEmulation({offline: true}); +``` + +#### `ses.disableNetworkEmulation()` + +停止所有已经使用 `session` 的活跃模拟网络. +重置为原始网络类型. + +#### `ses.setCertificateVerifyProc(proc)` + +* `proc` Function + +为 `session` 设置证书验证过程,当请求一个服务器的证书验证时,使用 `proc(hostname, certificate, callback)` 调用 `proc`.调用 `callback(true)` 来接收证书,调用 `callback(false)` 来拒绝验证证书. + +调用了 `setCertificateVerifyProc(null)` ,则将会回复到默认证书验证过程. + +```javascript +myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, callback) { + if (hostname == 'github.com') + callback(true); + else + callback(false); +}); +``` + +#### `ses.setPermissionRequestHandler(handler)` + +* `handler` Function + * `webContents` Object - [WebContents](web-contents.md) 请求许可. + * `permission` String - 枚举了 'media', 'geolocation', 'notifications', 'midiSysex', 'pointerLock', 'fullscreen'. + * `callback` Function - 允许或禁止许可. + +为对应 `session` 许可请求设置响应句柄.调用 `callback(true)` 接收许可,调用 `callback(false)` 禁止许可. + +```javascript +session.fromPartition(partition).setPermissionRequestHandler(function(webContents, permission, callback) { + if (webContents.getURL() === host) { + if (permission == "notifications") { + callback(false); // denied. + return; + } + } + + callback(true); +}); +``` + +#### `ses.clearHostResolverCache([callback])` + +* `callback` Function (可选) - 操作结束调用. + +清除主机解析缓存. + +#### `ses.webRequest` + +在其生命周期的不同阶段,`webRequest` API 设置允许拦截并修改请求内容. + +每个 API 接收一可选的 `filter` 和 `listener`,当 API 事件发生的时候使用 `listener(details)` 调用 `listener`,`details` 是一个用来描述请求的对象.为 `listener` 使用 `null` 则会退定事件. + +`filter` 是一个拥有 `urls` 属性的对象,这是一个 url 模式数组,这用来过滤掉不匹配指定 url 模式的请求.如果忽略 `filter` ,那么所有请求都将可以成功匹配. + +所有事件的 `listener` 都有一个回调事件,当 `listener` 完成它的工作的时候,它将使用一个 `response` 对象来调用. + +```javascript +// 将所有请求的代理都修改为下列 url. +var filter = { + urls: ["https://*.github.com/*", "*://electron.github.io"] +}; + +session.defaultSession.webRequest.onBeforeSendHeaders(filter, function(details, callback) { + details.requestHeaders['User-Agent'] = "MyAgent"; + callback({cancel: false, requestHeaders: details.requestHeaders}); +}); +``` + +#### `ses.webRequest.onBeforeRequest([filter, ]listener)` + +* `filter` Object +* `listener` Function + +当一个请求即将开始的时候,使用 `listener(details, callback)` 调用 `listener`. + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `uploadData` Array (可选) +* `callback` Function + +`uploadData` 是一个 `data` 数组对象: + +* `data` Object + * `bytes` Buffer - 被发送的内容. + * `file` String - 上载文件路径. + +`callback` 必须使用一个 `response` 对象来调用: + +* `response` Object + * `cancel` Boolean (可选) + * `redirectURL` String (可选) - 原始请求阻止发送或完成,而不是重定向. + +#### `ses.webRequest.onBeforeSendHeaders([filter, ]listener)` + +* `filter` Object +* `listener` Function + +一旦请求报文头可用了,在发送 HTTP 请求的之前,使用 `listener(details, callback)` 调用 `listener`.这也许会在服务器发起一个tcp 连接,但是在发送任何 http 数据之前发生. + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `requestHeaders` Object +* `callback` Function + +必须使用一个 `response` 对象来调用 `callback` : + +* `response` Object + * `cancel` Boolean (可选) + * `requestHeaders` Object (可选) - 如果提供了,将使用这些 headers 来创建请求. + +#### `ses.webRequest.onSendHeaders([filter, ]listener)` + +* `filter` Object +* `listener` Function + +在一个请求正在发送到服务器的时候,使用 `listener(details)` 来调用 `listener` ,之前 `onBeforeSendHeaders` 修改部分响应可用,同时取消监听. + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `requestHeaders` Object + +#### `ses.webRequest.onHeadersReceived([filter,] listener)` + +* `filter` Object +* `listener` Function + +当 HTTP 请求报文头已经到达的时候,使用 `listener(details, callback)` 调用 `listener` . + +* `details` Object + * `id` String + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `statusLine` String + * `statusCode` Integer + * `responseHeaders` Object +* `callback` Function + +必须使用一个 `response` 对象来调用 `callback` : + +* `response` Object + * `cancel` Boolean + * `responseHeaders` Object (可选) - 如果提供, 服务器将假定使用这些头来响应. + +#### `ses.webRequest.onResponseStarted([filter, ]listener)` + +* `filter` Object +* `listener` Function + +当响应body的首字节到达的时候,使用 `listener(details)` 调用 `listener`.对 http 请求来说,这意味着状态线和响应头可用了. + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `responseHeaders` Object + * `fromCache` Boolean - 标识响应是否来自磁盘 + cache. + * `statusCode` Integer + * `statusLine` String + +#### `ses.webRequest.onBeforeRedirect([filter, ]listener)` + +* `filter` Object +* `listener` Function + +当服务器的重定向初始化正要启动时,使用 `listener(details)` 调用 `listener`. + +* `details` Object + * `id` String + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `redirectURL` String + * `statusCode` Integer + * `ip` String (可选) - 请求的真实服务器ip 地址 + * `fromCache` Boolean + * `responseHeaders` Object + +#### `ses.webRequest.onCompleted([filter, ]listener)` + +* `filter` Object +* `listener` Function + +当请求完成的时候,使用 `listener(details)` 调用 `listener`. + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `responseHeaders` Object + * `fromCache` Boolean + * `statusCode` Integer + * `statusLine` String + +#### `ses.webRequest.onErrorOccurred([filter, ]listener)` + +* `filter` Object +* `listener` Function + +当一个错误发生的时候,使用 `listener(details)` 调用 `listener`. + +* `details` Object + * `id` Integer + * `url` String + * `method` String + * `resourceType` String + * `timestamp` Double + * `fromCache` Boolean + * `error` String - 错误描述. \ No newline at end of file From c2797e186446ff456b1f74450f1e5fc1b4aa6836 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 14 Mar 2016 17:08:32 +0900 Subject: [PATCH 491/688] Replace extension with the one in filter --- atom/browser/ui/file_dialog_gtk.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/ui/file_dialog_gtk.cc b/atom/browser/ui/file_dialog_gtk.cc index 5a82a849395..6d19a2eda46 100644 --- a/atom/browser/ui/file_dialog_gtk.cc +++ b/atom/browser/ui/file_dialog_gtk.cc @@ -208,7 +208,7 @@ base::FilePath FileChooserDialog::AddExtensionForFilename( return path; } - return path.AddExtension(extensions[0]); + return path.ReplaceExtension(extensions[0]); } From e92d002eec310fd9b534bf7694c017490746fdaf Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 14 Mar 2016 17:22:09 +0900 Subject: [PATCH 492/688] Bump v0.37.2 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index 24456ca479d..df7ec4ed329 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.37.1', + 'version%': '0.37.2', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 613fa39e9da..06405d836b4 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.37.1 + 0.37.2 CFBundleShortVersionString - 0.37.1 + 0.37.2 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 3b587f62da8..be2e5666bbf 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,37,1,0 - PRODUCTVERSION 0,37,1,0 + FILEVERSION 0,37,2,0 + PRODUCTVERSION 0,37,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.37.1" + VALUE "FileVersion", "0.37.2" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.37.1" + VALUE "ProductVersion", "0.37.2" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 27b3fec626f..8821ec4e159 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 37 -#define ATOM_PATCH_VERSION 1 +#define ATOM_PATCH_VERSION 2 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index a4e3686bffd..21ac10cff25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.37.1", + "version": "0.37.2", "devDependencies": { "asar": "^0.10.0", "eslint": "^2.1.0", From f8f3fba433190437c400ca1814ace640200671b3 Mon Sep 17 00:00:00 2001 From: Robo Date: Sun, 13 Mar 2016 09:46:33 +0530 Subject: [PATCH 493/688] webview: allow setting background color --- atom/browser/api/atom_api_web_contents.cc | 6 ---- atom/browser/api/atom_api_web_contents.h | 1 - atom/browser/web_view_guest_delegate.cc | 34 +++----------------- atom/browser/web_view_guest_delegate.h | 6 ---- atom/common/api/api_messages.h | 2 ++ atom/renderer/atom_render_view_observer.cc | 9 ++++++ atom/renderer/atom_render_view_observer.h | 1 + lib/browser/guest-view-manager.js | 8 ----- lib/renderer/web-view/guest-view-internal.js | 3 -- lib/renderer/web-view/web-view-attributes.js | 15 --------- lib/renderer/web-view/web-view-constants.js | 1 - 11 files changed, 17 insertions(+), 69 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index c8b597704cd..e5ea7e32a29 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1100,11 +1100,6 @@ void WebContents::SetSize(const SetSizeParams& params) { guest_delegate_->SetSize(params); } -void WebContents::SetAllowTransparency(bool allow) { - if (guest_delegate_) - guest_delegate_->SetAllowTransparency(allow); -} - bool WebContents::IsGuest() const { return type_ == WEB_VIEW; } @@ -1202,7 +1197,6 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, &WebContents::BeginFrameSubscription) .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription) .SetMethod("setSize", &WebContents::SetSize) - .SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency) .SetMethod("isGuest", &WebContents::IsGuest) .SetMethod("getWebPreferences", &WebContents::GetWebPreferences) .SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index d98b838fb46..b734dc304df 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -131,7 +131,6 @@ class WebContents : public mate::TrackableObject, // Methods for creating . void SetSize(const SetSizeParams& params); - void SetAllowTransparency(bool allow); bool IsGuest() const; // Callback triggered on permission response. diff --git a/atom/browser/web_view_guest_delegate.cc b/atom/browser/web_view_guest_delegate.cc index 38f0fb1783f..47fcc204a4d 100644 --- a/atom/browser/web_view_guest_delegate.cc +++ b/atom/browser/web_view_guest_delegate.cc @@ -5,6 +5,7 @@ #include "atom/browser/web_view_guest_delegate.h" #include "atom/browser/api/atom_api_web_contents.h" +#include "atom/common/api/api_messages.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "content/public/browser/guest_host.h" #include "content/public/browser/render_frame_host.h" @@ -22,8 +23,7 @@ const int kDefaultHeight = 300; } // namespace WebViewGuestDelegate::WebViewGuestDelegate() - : guest_opaque_(true), - guest_host_(nullptr), + : guest_host_(nullptr), auto_size_enabled_(false), is_full_page_plugin_(false), api_web_contents_(nullptr) { @@ -96,23 +96,6 @@ void WebViewGuestDelegate::SetSize(const SetSizeParams& params) { auto_size_enabled_ = enable_auto_size; } -void WebViewGuestDelegate::SetAllowTransparency(bool allow) { - if (guest_opaque_ != allow) - return; - - auto render_view_host = web_contents()->GetRenderViewHost(); - guest_opaque_ = !allow; - if (!render_view_host->GetWidget()->GetView()) - return; - - if (guest_opaque_) { - render_view_host->GetWidget()->GetView()->SetBackgroundColorToDefault(); - } else { - render_view_host->GetWidget()->GetView()->SetBackgroundColor( - SK_ColorTRANSPARENT); - } -} - void WebViewGuestDelegate::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { @@ -121,16 +104,9 @@ void WebViewGuestDelegate::HandleKeyboardEvent( } void WebViewGuestDelegate::RenderViewReady() { - // We don't want to accidentally set the opacity of an interstitial page. - // WebContents::GetRenderWidgetHostView will return the RWHV of an - // interstitial page if one is showing at this time. We only want opacity - // to apply to web pages. - auto render_view_host_view = - web_contents()->GetRenderViewHost()->GetWidget()->GetView(); - if (guest_opaque_) - render_view_host_view->SetBackgroundColorToDefault(); - else - render_view_host_view->SetBackgroundColor(SK_ColorTRANSPARENT); + // Set default UA-dependent background as transparent. + api_web_contents_->Send(new AtomViewMsg_SetTransparentBackground( + api_web_contents_->routing_id())); } void WebViewGuestDelegate::DidCommitProvisionalLoadForFrame( diff --git a/atom/browser/web_view_guest_delegate.h b/atom/browser/web_view_guest_delegate.h index 65e0bcde191..d4549e8dba4 100644 --- a/atom/browser/web_view_guest_delegate.h +++ b/atom/browser/web_view_guest_delegate.h @@ -49,9 +49,6 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, // and normal sizes. void SetSize(const SetSizeParams& params); - // Sets the transparency of the guest. - void SetAllowTransparency(bool allow); - // Transfer the keyboard event to embedder. void HandleKeyboardEvent(content::WebContents* source, const content::NativeWebKeyboardEvent& event); @@ -85,9 +82,6 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, // Returns the default size of the guestview. gfx::Size GetDefaultSize() const; - // Stores whether the contents of the guest can be transparent. - bool guest_opaque_; - // The WebContents that attaches this guest view. content::WebContents* embedder_web_contents_; diff --git a/atom/common/api/api_messages.h b/atom/common/api/api_messages.h index eeb26614847..e98f1bdfba0 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -37,3 +37,5 @@ IPC_MESSAGE_ROUTED2(AtomViewMsg_Message, // Sent by the renderer when the draggable regions are updated. IPC_MESSAGE_ROUTED1(AtomViewHostMsg_UpdateDraggableRegions, std::vector /* regions */) + +IPC_MESSAGE_ROUTED0(AtomViewMsg_SetTransparentBackground) diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index cdbdb3d7c3c..19eaec9e07b 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -22,6 +22,7 @@ #include "ipc/ipc_message_macros.h" #include "net/base/net_module.h" #include "net/grit/net_resources.h" +#include "third_party/skia/include/core/SkColor.h" #include "third_party/WebKit/public/web/WebDraggableRegion.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebFrame.h" @@ -113,6 +114,8 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(AtomRenderViewObserver, message) IPC_MESSAGE_HANDLER(AtomViewMsg_Message, OnBrowserMessage) + IPC_MESSAGE_HANDLER(AtomViewMsg_SetTransparentBackground, + OnSetTransparentBackground) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -148,4 +151,10 @@ void AtomRenderViewObserver::OnBrowserMessage(const base::string16& channel, } } +void AtomRenderViewObserver::OnSetTransparentBackground() { + if (!render_view()->GetWebView()) + return; + render_view()->GetWebView()->setBaseBackgroundColor(SK_ColorTRANSPARENT); +} + } // namespace atom diff --git a/atom/renderer/atom_render_view_observer.h b/atom/renderer/atom_render_view_observer.h index 4b9d59f3fa0..3fcaeaa331f 100644 --- a/atom/renderer/atom_render_view_observer.h +++ b/atom/renderer/atom_render_view_observer.h @@ -32,6 +32,7 @@ class AtomRenderViewObserver : public content::RenderViewObserver { void OnBrowserMessage(const base::string16& channel, const base::ListValue& args); + void OnSetTransparentBackground(); // Weak reference to renderer client. AtomRendererClient* renderer_client_; diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index b41b9b3a0f5..574207dd5b1 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -131,9 +131,6 @@ var createGuest = function(embedder, params) { } this.loadURL(params.src, opts); } - if (params.allowtransparency != null) { - this.setAllowTransparency(params.allowtransparency); - } return guest.allowPopups = params.allowpopups; }); @@ -229,11 +226,6 @@ ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', function(event, id, params) return (ref1 = guestInstances[id]) != null ? ref1.guest.setSize(params) : void 0; }); -ipcMain.on('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', function(event, id, allowtransparency) { - var ref1; - return (ref1 = guestInstances[id]) != null ? ref1.guest.setAllowTransparency(allowtransparency) : void 0; -}); - // Returns WebContents from its guest id. exports.getGuest = function(id) { var ref1; diff --git a/lib/renderer/web-view/guest-view-internal.js b/lib/renderer/web-view/guest-view-internal.js index a7427abd631..c6e46fab954 100644 --- a/lib/renderer/web-view/guest-view-internal.js +++ b/lib/renderer/web-view/guest-view-internal.js @@ -106,7 +106,4 @@ module.exports = { setSize: function(guestInstanceId, params) { return ipcRenderer.send('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', guestInstanceId, params); }, - setAllowTransparency: function(guestInstanceId, allowtransparency) { - return ipcRenderer.send('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', guestInstanceId, allowtransparency); - } }; diff --git a/lib/renderer/web-view/web-view-attributes.js b/lib/renderer/web-view/web-view-attributes.js index bb7847fe163..e47b42c0261 100644 --- a/lib/renderer/web-view/web-view-attributes.js +++ b/lib/renderer/web-view/web-view-attributes.js @@ -81,20 +81,6 @@ class BooleanAttribute extends WebViewAttribute { } } -// Attribute that specifies whether transparency is allowed in the webview. -class AllowTransparencyAttribute extends BooleanAttribute { - constructor(webViewImpl) { - super(webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, webViewImpl); - } - - handleMutation() { - if (!this.webViewImpl.guestInstanceId) { - return; - } - return guestViewInternal.setAllowTransparency(this.webViewImpl.guestInstanceId, this.getValue()); - } -} - // Attribute used to define the demension limits of autosizing. class AutosizeDimensionAttribute extends WebViewAttribute { constructor(name, webViewImpl) { @@ -298,7 +284,6 @@ class BlinkFeaturesAttribute extends WebViewAttribute { // Sets up all of the webview attributes. WebViewImpl.prototype.setupWebViewAttributes = function() { this.attributes = {}; - this.attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] = new AllowTransparencyAttribute(this); this.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE] = new AutosizeAttribute(this); this.attributes[webViewConstants.ATTRIBUTE_PARTITION] = new PartitionAttribute(this); this.attributes[webViewConstants.ATTRIBUTE_SRC] = new SrcAttribute(this); diff --git a/lib/renderer/web-view/web-view-constants.js b/lib/renderer/web-view/web-view-constants.js index de2a571f5d5..297941aa801 100644 --- a/lib/renderer/web-view/web-view-constants.js +++ b/lib/renderer/web-view/web-view-constants.js @@ -1,6 +1,5 @@ module.exports = { // Attributes. - ATTRIBUTE_ALLOWTRANSPARENCY: 'allowtransparency', ATTRIBUTE_AUTOSIZE: 'autosize', ATTRIBUTE_MAXHEIGHT: 'maxheight', ATTRIBUTE_MAXWIDTH: 'maxwidth', From fd53a4b24daffa1e2bcec5d3a5467ac3ea9a4b95 Mon Sep 17 00:00:00 2001 From: Robo Date: Mon, 14 Mar 2016 19:24:04 +0530 Subject: [PATCH 494/688] modify default background for all render views --- atom/browser/web_view_guest_delegate.cc | 7 ------- atom/browser/web_view_guest_delegate.h | 1 - atom/common/api/api_messages.h | 2 -- atom/renderer/atom_render_view_observer.cc | 9 --------- atom/renderer/atom_render_view_observer.h | 1 - atom/renderer/atom_renderer_client.cc | 4 ++++ 6 files changed, 4 insertions(+), 20 deletions(-) diff --git a/atom/browser/web_view_guest_delegate.cc b/atom/browser/web_view_guest_delegate.cc index 47fcc204a4d..6abb9713bfa 100644 --- a/atom/browser/web_view_guest_delegate.cc +++ b/atom/browser/web_view_guest_delegate.cc @@ -5,7 +5,6 @@ #include "atom/browser/web_view_guest_delegate.h" #include "atom/browser/api/atom_api_web_contents.h" -#include "atom/common/api/api_messages.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "content/public/browser/guest_host.h" #include "content/public/browser/render_frame_host.h" @@ -103,12 +102,6 @@ void WebViewGuestDelegate::HandleKeyboardEvent( embedder_web_contents_->GetDelegate()->HandleKeyboardEvent(source, event); } -void WebViewGuestDelegate::RenderViewReady() { - // Set default UA-dependent background as transparent. - api_web_contents_->Send(new AtomViewMsg_SetTransparentBackground( - api_web_contents_->routing_id())); -} - void WebViewGuestDelegate::DidCommitProvisionalLoadForFrame( content::RenderFrameHost* render_frame_host, const GURL& url, ui::PageTransition transition_type) { diff --git a/atom/browser/web_view_guest_delegate.h b/atom/browser/web_view_guest_delegate.h index d4549e8dba4..95888ff749f 100644 --- a/atom/browser/web_view_guest_delegate.h +++ b/atom/browser/web_view_guest_delegate.h @@ -55,7 +55,6 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, protected: // content::WebContentsObserver: - void RenderViewReady() override; void DidCommitProvisionalLoadForFrame( content::RenderFrameHost* render_frame_host, const GURL& url, ui::PageTransition transition_type) override; diff --git a/atom/common/api/api_messages.h b/atom/common/api/api_messages.h index e98f1bdfba0..eeb26614847 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -37,5 +37,3 @@ IPC_MESSAGE_ROUTED2(AtomViewMsg_Message, // Sent by the renderer when the draggable regions are updated. IPC_MESSAGE_ROUTED1(AtomViewHostMsg_UpdateDraggableRegions, std::vector /* regions */) - -IPC_MESSAGE_ROUTED0(AtomViewMsg_SetTransparentBackground) diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index 19eaec9e07b..cdbdb3d7c3c 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -22,7 +22,6 @@ #include "ipc/ipc_message_macros.h" #include "net/base/net_module.h" #include "net/grit/net_resources.h" -#include "third_party/skia/include/core/SkColor.h" #include "third_party/WebKit/public/web/WebDraggableRegion.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebFrame.h" @@ -114,8 +113,6 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(AtomRenderViewObserver, message) IPC_MESSAGE_HANDLER(AtomViewMsg_Message, OnBrowserMessage) - IPC_MESSAGE_HANDLER(AtomViewMsg_SetTransparentBackground, - OnSetTransparentBackground) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -151,10 +148,4 @@ void AtomRenderViewObserver::OnBrowserMessage(const base::string16& channel, } } -void AtomRenderViewObserver::OnSetTransparentBackground() { - if (!render_view()->GetWebView()) - return; - render_view()->GetWebView()->setBaseBackgroundColor(SK_ColorTRANSPARENT); -} - } // namespace atom diff --git a/atom/renderer/atom_render_view_observer.h b/atom/renderer/atom_render_view_observer.h index 3fcaeaa331f..4b9d59f3fa0 100644 --- a/atom/renderer/atom_render_view_observer.h +++ b/atom/renderer/atom_render_view_observer.h @@ -32,7 +32,6 @@ class AtomRenderViewObserver : public content::RenderViewObserver { void OnBrowserMessage(const base::string16& channel, const base::ListValue& args); - void OnSetTransparentBackground(); // Weak reference to renderer client. AtomRendererClient* renderer_client_; diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index a996bd0efb2..50ff109a2fc 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -25,6 +25,7 @@ #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_thread.h" +#include "content/public/renderer/render_view.h" #include "ipc/ipc_message_macros.h" #include "third_party/WebKit/public/web/WebCustomElement.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" @@ -131,6 +132,9 @@ void AtomRendererClient::RenderFrameCreated( } void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) { + // Set default UA-dependent background as transparent. + render_view->GetWebView()->setBaseBackgroundColor(SK_ColorTRANSPARENT); + new printing::PrintWebViewHelper(render_view); new AtomRenderViewObserver(render_view, this); } From cdc7b8d15e881f12c1ff3cba7dd92fb2fd759730 Mon Sep 17 00:00:00 2001 From: Robo Date: Tue, 15 Mar 2016 07:51:36 +0530 Subject: [PATCH 495/688] devtools: fix filesyatem api usage and use prefs to track filesystem paths --- atom/browser/atom_browser_context.cc | 1 + atom/browser/common_web_contents_delegate.cc | 119 +++++++++++++------ atom/browser/common_web_contents_delegate.h | 6 +- chromium_src/chrome/common/pref_names.cc | 1 + chromium_src/chrome/common/pref_names.h | 1 + 5 files changed, 86 insertions(+), 42 deletions(-) diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 2ff9a510db4..d6724ff5338 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -194,6 +194,7 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) { PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &download_dir); pref_registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory, download_dir); + pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths); } bool AtomBrowserContext::AllowNTLMCredentialsForDomain(const GURL& origin) { diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index 07cc20c7d10..62e854ac565 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -4,17 +4,22 @@ #include "atom/browser/common_web_contents_delegate.h" +#include #include #include +#include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_javascript_dialog_manager.h" #include "atom/browser/native_window.h" #include "atom/browser/ui/file_dialog.h" #include "atom/browser/web_dialog_helper.h" #include "base/files/file_util.h" +#include "base/prefs/pref_service.h" +#include "base/prefs/scoped_user_pref_update.h" #include "chrome/browser/printing/print_preview_message_handler.h" #include "chrome/browser/printing/print_view_manager_basic.h" #include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/common/pref_names.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/render_process_host.h" @@ -36,6 +41,8 @@ namespace atom { namespace { +const char kRootName[] = ""; + struct FileSystem { FileSystem() { } @@ -53,14 +60,14 @@ struct FileSystem { }; std::string RegisterFileSystem(content::WebContents* web_contents, - const base::FilePath& path, - std::string* registered_name) { + const base::FilePath& path) { auto isolated_context = storage::IsolatedContext::GetInstance(); + std::string root_name(kRootName); std::string file_system_id = isolated_context->RegisterFileSystemForPath( storage::kFileSystemTypeNativeLocal, std::string(), path, - registered_name); + &root_name); content::ChildProcessSecurityPolicy* policy = content::ChildProcessSecurityPolicy::GetInstance(); @@ -80,13 +87,12 @@ std::string RegisterFileSystem(content::WebContents* web_contents, FileSystem CreateFileSystemStruct( content::WebContents* web_contents, const std::string& file_system_id, - const std::string& registered_name, const std::string& file_system_path) { const GURL origin = web_contents->GetURL().GetOrigin(); std::string file_system_name = storage::GetIsolatedFileSystemName(origin, file_system_id); std::string root_url = storage::GetIsolatedFileSystemRootURIString( - origin, file_system_id, registered_name); + origin, file_system_id, kRootName); return FileSystem(file_system_name, root_url, file_system_path); } @@ -114,6 +120,26 @@ void AppendToFile(const base::FilePath& path, base::AppendToFile(path, content.data(), content.size()); } +PrefService* GetPrefService(content::WebContents* web_contents) { + auto context = web_contents->GetBrowserContext(); + return static_cast(context)->prefs(); +} + +std::set GetAddedFileSystemPaths( + content::WebContents* web_contents) { + auto pref_service = GetPrefService(web_contents); + const base::DictionaryValue* file_system_paths_value = + pref_service->GetDictionary(prefs::kDevToolsFileSystemPaths); + std::set result; + if (file_system_paths_value) { + base::DictionaryValue::Iterator it(*file_system_paths_value); + for (; !it.IsAtEnd(); it.Advance()) { + result.insert(it.key()); + } + } + return result; +} + } // namespace CommonWebContentsDelegate::CommonWebContentsDelegate() @@ -278,6 +304,34 @@ void CommonWebContentsDelegate::DevToolsAppendToFile( base::Unretained(this), url)); } +void CommonWebContentsDelegate::DevToolsRequestFileSystems() { + auto file_system_paths = GetAddedFileSystemPaths(GetDevToolsWebContents()); + if (file_system_paths.empty()) { + base::ListValue empty_file_system_value; + web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded", + &empty_file_system_value, + nullptr, nullptr); + return; + } + + std::vector file_systems; + for (auto file_system_path : file_system_paths) { + base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path); + std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(), + path); + FileSystem file_system = CreateFileSystemStruct(GetDevToolsWebContents(), + file_system_id, + file_system_path); + file_systems.push_back(file_system); + } + + base::ListValue file_system_value; + for (size_t i = 0; i < file_systems.size(); ++i) + file_system_value.Append(CreateFileSystemValue(file_systems[i])); + web_contents_->CallClientFunction("DevToolsAPI.fileSystemsLoaded", + &file_system_value, nullptr, nullptr); +} + void CommonWebContentsDelegate::DevToolsAddFileSystem( const base::FilePath& file_system_path) { base::FilePath path = file_system_path; @@ -293,32 +347,26 @@ void CommonWebContentsDelegate::DevToolsAddFileSystem( path = paths[0]; } - std::string registered_name; std::string file_system_id = RegisterFileSystem(GetDevToolsWebContents(), - path, - ®istered_name); - - WorkspaceMap::iterator it = saved_paths_.find(file_system_id); - if (it != saved_paths_.end()) + path); + auto file_system_paths = GetAddedFileSystemPaths(GetDevToolsWebContents()); + if (file_system_paths.find(path.AsUTF8Unsafe()) != file_system_paths.end()) return; - saved_paths_[file_system_id] = path; - FileSystem file_system = CreateFileSystemStruct(GetDevToolsWebContents(), - file_system_id, - registered_name, - path.AsUTF8Unsafe()); + file_system_id, + path.AsUTF8Unsafe()); + scoped_ptr file_system_value( + CreateFileSystemValue(file_system)); - scoped_ptr error_string_value( - new base::StringValue(std::string())); - scoped_ptr file_system_value; - if (!file_system.file_system_path.empty()) - file_system_value.reset(CreateFileSystemValue(file_system)); - web_contents_->CallClientFunction( - "DevToolsAPI.fileSystemAdded", - error_string_value.get(), - file_system_value.get(), - nullptr); + auto pref_service = GetPrefService(GetDevToolsWebContents()); + DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths); + update.Get()->SetWithoutPathExpansion( + path.AsUTF8Unsafe(), base::Value::CreateNullValue()); + + web_contents_->CallClientFunction("DevToolsAPI.fileSystemAdded", + file_system_value.get(), + nullptr, nullptr); } void CommonWebContentsDelegate::DevToolsRemoveFileSystem( @@ -326,21 +374,18 @@ void CommonWebContentsDelegate::DevToolsRemoveFileSystem( if (!web_contents_) return; + std::string path = file_system_path.AsUTF8Unsafe(); storage::IsolatedContext::GetInstance()-> RevokeFileSystemByPath(file_system_path); - for (auto it = saved_paths_.begin(); it != saved_paths_.end(); ++it) - if (it->second == file_system_path) { - saved_paths_.erase(it); - break; - } + auto pref_service = GetPrefService(GetDevToolsWebContents()); + DictionaryPrefUpdate update(pref_service, prefs::kDevToolsFileSystemPaths); + update.Get()->RemoveWithoutPathExpansion(path, nullptr); - base::StringValue file_system_path_value(file_system_path.AsUTF8Unsafe()); - web_contents_->CallClientFunction( - "DevToolsAPI.fileSystemRemoved", - &file_system_path_value, - nullptr, - nullptr); + base::StringValue file_system_path_value(path); + web_contents_->CallClientFunction("DevToolsAPI.fileSystemRemoved", + &file_system_path_value, + nullptr, nullptr); } void CommonWebContentsDelegate::OnDevToolsSaveToFile( diff --git a/atom/browser/common_web_contents_delegate.h b/atom/browser/common_web_contents_delegate.h index 83ef2850bd9..61ff63793df 100644 --- a/atom/browser/common_web_contents_delegate.h +++ b/atom/browser/common_web_contents_delegate.h @@ -83,6 +83,7 @@ class CommonWebContentsDelegate bool save_as) override; void DevToolsAppendToFile(const std::string& url, const std::string& content) override; + void DevToolsRequestFileSystems() override; void DevToolsAddFileSystem(const base::FilePath& path) override; void DevToolsRemoveFileSystem( const base::FilePath& file_system_path) override; @@ -128,11 +129,6 @@ class CommonWebContentsDelegate typedef std::map PathsMap; PathsMap saved_files_; - // Maps file system id to file path, used by the file system requests - // sent from devtools. - typedef std::map WorkspaceMap; - WorkspaceMap saved_paths_; - DISALLOW_COPY_AND_ASSIGN(CommonWebContentsDelegate); }; diff --git a/chromium_src/chrome/common/pref_names.cc b/chromium_src/chrome/common/pref_names.cc index 3e3a73b9983..23235cd1f4b 100644 --- a/chromium_src/chrome/common/pref_names.cc +++ b/chromium_src/chrome/common/pref_names.cc @@ -8,5 +8,6 @@ namespace prefs { const char kSelectFileLastDirectory[] = "selectfile.last_directory"; const char kDownloadDefaultDirectory[] = "download.default_directory"; +const char kDevToolsFileSystemPaths[] = "devtools.file_system_paths"; } // namespace prefs diff --git a/chromium_src/chrome/common/pref_names.h b/chromium_src/chrome/common/pref_names.h index 542a2d2c733..5101c720133 100644 --- a/chromium_src/chrome/common/pref_names.h +++ b/chromium_src/chrome/common/pref_names.h @@ -8,5 +8,6 @@ namespace prefs { extern const char kSelectFileLastDirectory[]; extern const char kDownloadDefaultDirectory[]; +extern const char kDevToolsFileSystemPaths[]; } // namespace prefs From e3e6cd6fd8d3b55677be9972c38a8dcaf5ea6a7d Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 14 Mar 2016 19:48:40 -0700 Subject: [PATCH 496/688] Remove type parameter --- atom/common/api/atom_api_native_image.cc | 50 ++---------------------- 1 file changed, 4 insertions(+), 46 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 6c22830f674..3932921646e 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -58,20 +58,6 @@ ScaleFactorPair kScaleFactorPairs[] = { { "@2.5x" , 2.5f }, }; -enum NativeRepresentation { - INVALID = 0, - AS_NSIMAGE, -}; - -struct NativeRepresentationPair { - const char* name; - NativeRepresentation rep; -}; - -NativeRepresentationPair kNativeRepresentations[] { - { "nsimage", NativeRepresentation::AS_NSIMAGE }, -}; - float GetScaleFactorFromPath(const base::FilePath& path) { std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe()); @@ -240,40 +226,12 @@ std::string NativeImage::ToDataURL() { v8::Local NativeImage::AsNativeRepresentation( v8::Isolate* isolate, mate::Arguments* args) { - NativeRepresentation desiredRep = NativeRepresentation::INVALID; - void* ptr = nullptr; - std::string type; - - if (!args->GetNext(&type)) { - args->ThrowError(); - goto out; - } - - for (const NativeRepresentationPair& item : kNativeRepresentations) { - if (type.compare(item.name) == 0) { - desiredRep = item.rep; - break; - } - } - - if (desiredRep == NativeRepresentation::INVALID) { - args->ThrowError(); - goto out; - } - - switch (desiredRep) { #if defined(OS_MACOSX) - case NativeRepresentation::AS_NSIMAGE: - ptr = reinterpret_cast(image_.AsNSImage()); - break; + void* ptr = reinterpret_cast(image_.AsNSImage()); +#else + args.ThrowError(); + return v8::Undefined(isolate); #endif - case NativeRepresentation::INVALID: - default: - args->ThrowError(); - break; - } - -out: return node::Buffer::Copy( isolate, From d344c1e408324a39c703183c7541ea444d5ba18f Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 14 Mar 2016 19:50:31 -0700 Subject: [PATCH 497/688] AsNativeRepresentation => getNativeHandle --- atom/common/api/atom_api_native_image.cc | 6 +++--- atom/common/api/atom_api_native_image.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 3932921646e..d616b428330 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -184,8 +184,8 @@ mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder( template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate) .SetMethod("toPng", &NativeImage::ToPNG) .SetMethod("toJpeg", &NativeImage::ToJPEG) - .SetMethod("asNativeRepresentation", - &NativeImage::AsNativeRepresentation) + .SetMethod("getNativeHandle", + &NativeImage::GetNativeHandle) .SetMethod("toDataURL", &NativeImage::ToDataURL) .SetMethod("toDataUrl", &NativeImage::ToDataURL) // deprecated. .SetMethod("isEmpty", &NativeImage::IsEmpty) @@ -223,7 +223,7 @@ std::string NativeImage::ToDataURL() { return data_url; } -v8::Local NativeImage::AsNativeRepresentation( +v8::Local NativeImage::GetNativeHandle( v8::Isolate* isolate, mate::Arguments* args) { #if defined(OS_MACOSX) diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index 8b1329d2848..145f5ff1dcd 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -61,7 +61,7 @@ class NativeImage : public mate::Wrappable { private: v8::Local ToPNG(v8::Isolate* isolate); v8::Local ToJPEG(v8::Isolate* isolate, int quality); - v8::Local AsNativeRepresentation( + v8::Local GetNativeHandle( v8::Isolate* isolate, mate::Arguments* args); std::string ToDataURL(); From f59752bf4f7829bdcd3f0cd967938afea9bf62c6 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 14 Mar 2016 19:51:37 -0700 Subject: [PATCH 498/688] Update the docs to match --- docs/api/native-image.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/api/native-image.md b/docs/api/native-image.md index 2cae12feb47..c33f35c6fe5 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -133,12 +133,11 @@ Returns a [Buffer][buffer] that contains the image's `JPEG` encoded data. Returns the data URL of the image. -### `image.asNativeRepresentation(type)` +### `image.getNativeHandle()` Returns a pointer to an underlying native type (encoded as a [Buffer][buffer]) which can be used with native APIs. Note that in many cases, this pointer is a weak pointer to the underlying native image not a copy, so you _must_ ensure that the associated `nativeImage` instance is kept around. -* `type` String (**required**) - one of: - * `nsimage` - (OS X only) a pointer to an `NSImage` +Returns a [Buffer][buffer] that represents a pointer to a native type - on OS X, this type is an NSImage object. ### `image.isEmpty()` From ae701977c6972cf615a5f17045e1de5fedd672e0 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Tue, 15 Mar 2016 11:13:43 +0800 Subject: [PATCH 499/688] add web-contents first --- docs-translations/zh-CN/api/web-contents.md | 861 ++++++++++++++++++++ 1 file changed, 861 insertions(+) create mode 100644 docs-translations/zh-CN/api/web-contents.md diff --git a/docs-translations/zh-CN/api/web-contents.md b/docs-translations/zh-CN/api/web-contents.md new file mode 100644 index 00000000000..1b7011bb0fa --- /dev/null +++ b/docs-translations/zh-CN/api/web-contents.md @@ -0,0 +1,861 @@ +# webContents + +`webContents` 是一个 +[事件发出者](http://nodejs.org/api/events.html#events_class_events_eventemitter). + +它负责渲染并控制网页,也是 [`BrowserWindow`](browser-window.md) 对象的属性.一个使用 `webContents` 的例子: + +```javascript +const BrowserWindow = require('electron').BrowserWindow; + +var win = new BrowserWindow({width: 800, height: 1500}); +win.loadURL("http://github.com"); + +var webContents = win.webContents; +``` + +## 事件 + +`webContents` 对象可发出下列事件: + +### Event: 'did-finish-load' + +当导航完成时发出事件,`onload` 事件也完成. + +### Event: 'did-fail-load' + +返回: + +* `event` Event +* `errorCode` Integer +* `errorDescription` String +* `validatedURL` String + +这个事件类似 `did-finish-load` ,但是是在加载失败或取消加载时发出, 例如, `window.stop()` 请求结束.错误代码的完整列表和它们的含义都可以在 [here](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h) 找到. + +### Event: 'did-frame-finish-load' + +返回: + +* `event` Event +* `isMainFrame` Boolean + +当一个 frame 导航完成的时候发出事件. + +### Event: 'did-start-loading' + +当 tab 的spinner 开始 spinning的时候. + +### Event: 'did-stop-loading' + +当 tab 的spinner 结束 spinning的时候. + +### Event: 'did-get-response-details' + +返回: + +* `event` Event +* `status` Boolean +* `newURL` String +* `originalURL` String +* `httpResponseCode` Integer +* `requestMethod` String +* `referrer` String +* `headers` Object + +当有关请求资源的详细信息可用的时候发出事件. +`status` 标识了 socket链接来下载资源. + +### Event: 'did-get-redirect-request' + +返回: + +* `event` Event +* `oldURL` String +* `newURL` String +* `isMainFrame` Boolean +* `httpResponseCode` Integer +* `requestMethod` String +* `referrer` String +* `headers` Object + +当在请求资源时收到重定向的时候发出事件. + +### Event: 'dom-ready' + +返回: + +* `event` Event + +当指定 frame 中的 文档加载完成的时候发出事件. + +### Event: 'page-favicon-updated' + +返回: + +* `event` Event +* `favicons` Array - Array of URLs + +当 page 收到图标 url 的时候发出事件. + +### Event: 'new-window' + +返回: + +* `event` Event +* `url` String +* `frameName` String +* `disposition` String - 可为 `default`, `foreground-tab`, `background-tab`, + `new-window` 和 `other`. +* `options` Object - 创建新的 `BrowserWindow`时使用的参数. + +当 page 请求打开指定 url 窗口的时候发出事件.这可以是通过 `window.open` 或一个外部连接如 `` 发出的请求. + +默认指定 `url` 的 `BrowserWindow` 会被创建. + +调用 `event.preventDefault()` 可以用来阻止打开窗口. + +### Event: 'will-navigate' + +返回: + +* `event` Event +* `url` String + +当用户或 page 想要开始导航的时候发出事件.它可在当 `window.location` 对象改变或用户点击 page 中的链接的时候发生. + +当使用 api(如 `webContents.loadURL` 和 `webContents.back`) 以编程方式来启动导航的时候,这个事件将不会发出. + +它也不会在页内跳转发生, 例如点击锚链接或更新 `window.location.hash`.使用 `did-navigate-in-page` 事件可以达到目的. + +调用 `event.preventDefault()` 可以阻止导航. + +### Event: 'did-navigate' + +返回: + +* `event` Event +* `url` String + +当一个导航结束时候发出事件. + +页内跳转时不会发出这个事件,例如点击锚链接或更新 `window.location.hash`.使用 `did-navigate-in-page` 事件可以达到目的. + +### Event: 'did-navigate-in-page' + +返回: + +* `event` Event +* `url` String + +当页内导航发生的时候发出事件. + +当页内导航发生的时候,page 的url 改变,但是不会跳出界面.例如当点击锚链接时或者 DOM 的 `hashchange` 事件发生. + +### Event: 'crashed' + +当渲染进程崩溃的时候发出事件. + +### Event: 'plugin-crashed' + +返回: + +* `event` Event +* `name` String +* `version` String + +当插件进程崩溃时候发出事件. + +### Event: 'destroyed' + +当 `webContents` 被删除的时候发出事件. + +### Event: 'devtools-opened' + +当开发者工具栏打开的时候发出事件. + +### Event: 'devtools-closed' + +当开发者工具栏关闭时候发出事件. + +### Event: 'devtools-focused' + +当开发者工具栏获得焦点或打开的时候发出事件. + +### Event: 'certificate-error' + +返回: + +* `event` Event +* `url` URL +* `error` String - The error code +* `certificate` Object + * `data` Buffer - PEM encoded data + * `issuerName` String +* `callback` Function + +当验证证书或 `url` 失败的时候发出事件. + +使用方法类似 [`app` 的 `certificate-error` 事件](app.md#event-certificate-error). + +### Event: 'select-client-certificate' + +返回: + +* `event` Event +* `url` URL +* `certificateList` [Objects] + * `data` Buffer - PEM encoded data + * `issuerName` String - Issuer's Common Name +* `callback` Function + +当请求客户端证书的时候发出事件. + +使用方法类似 [`app` 的 `select-client-certificate` 事件](app.md#event-select-client-certificate). + +### Event: 'login' + +返回: + +* `event` Event +* `request` Object + * `method` String + * `url` URL + * `referrer` URL +* `authInfo` Object + * `isProxy` Boolean + * `scheme` String + * `host` String + * `port` Integer + * `realm` String +* `callback` Function + +当 `webContents` 想做基本验证的时候发出事件. + +使用方法类似 [the `login` event of `app`](app.md#event-login). + +### Event: 'found-in-page' + +返回: + +* `event` Event +* `result` Object + * `requestId` Integer + * `finalUpdate` Boolean - 标识是否还有更多的值可以查看. + * `matches` Integer (可选) - 匹配数量. + * `selectionArea` Object (可选) - 协调首个匹配位置. + +当使用 [`webContents.findInPage`](web-contents.md#webcontentsfindinpage) 进行页内查找并且找到可用值得时候发出事件. + +### Event: 'media-started-playing' + +当媒体开始播放的时候发出事件. + +### Event: 'media-paused' + +当媒体停止播放的时候发出事件. + +### Event: 'did-change-theme-color' + +当page 的主题色时候发出事件.这通常由于引入了一个 meta 标签 : + +```html + +``` + +### Event: 'cursor-changed' + +返回: + +* `event` Event +* `type` String +* `image` NativeImage (可选) +* `scale` Float (可选) + +当鼠标的类型发生改变的时候发出事件. `type` 的参数可以是 `default`, +`crosshair`, `pointer`, `text`, `wait`, `help`, `e-resize`, `n-resize`, +`ne-resize`, `nw-resize`, `s-resize`, `se-resize`, `sw-resize`, `w-resize`, +`ns-resize`, `ew-resize`, `nesw-resize`, `nwse-resize`, `col-resize`, +`row-resize`, `m-panning`, `e-panning`, `n-panning`, `ne-panning`, `nw-panning`, +`s-panning`, `se-panning`, `sw-panning`, `w-panning`, `move`, `vertical-text`, +`cell`, `context-menu`, `alias`, `progress`, `nodrop`, `copy`, `none`, +`not-allowed`, `zoom-in`, `zoom-out`, `grab`, `grabbing`, `custom`. + +如果 `type` 参数值为 `custom`, `image` 参数会在一个`NativeImage` 中控制自定义鼠标图片, 并且 `scale` 会控制图片的缩放比例. + +## 实例方法 + +`webContents` 对象有如下的实例方法: + +### `webContents.loadURL(url[, options])` + +* `url` URL +* `options` Object (可选) + * `httpReferrer` String - A HTTP Referrer url. + * `userAgent` String - 产生请求的用户代理 + * `extraHeaders` String - 以 "\n" 分隔的额外头 + +在窗口中加载 `url` , `url` 必须包含协议前缀, +比如 `http://` 或 `file://`. 如果加载想要忽略 http 缓存,可以使用 `pragma` 头来达到目的. + +```javascript +const options = {"extraHeaders" : "pragma: no-cache\n"} +webContents.loadURL(url, options) +``` + +### `webContents.downloadURL(url)` + +* `url` URL + +初始化一个指定 `url` 的资源下载,不导航跳转. `session` 的 `will-download` 事件会触发. + +### `webContents.getURL()` + +返回当前page 的 url. + +```javascript +var win = new BrowserWindow({width: 800, height: 600}); +win.loadURL("http://github.com"); + +var currentURL = win.webContents.getURL(); +``` + +### `webContents.getTitle()` + +返回当前page 的 标题. + +### `webContents.isLoading()` + +返回一个布尔值,标识当前页是否正在加载. + +### `webContents.isWaitingForResponse()` + +返回一个布尔值,标识当前页是否正在等待主要资源的第一次响应. + +### `webContents.stop()` + +停止还为开始的导航. + +### `webContents.reload()` + +重载当前页. + +### `webContents.reloadIgnoringCache()` + +重载当前页,忽略缓存. + +### `webContents.canGoBack()` + +返回一个布尔值,标识浏览器是否能回到前一个page. + +### `webContents.canGoForward()` + +返回一个布尔值,标识浏览器是否能前往下一个page. + +### `webContents.canGoToOffset(offset)` + +* `offset` Integer + +返回一个布尔值,标识浏览器是否能前往指定 `offset` 的page. + +### `webContents.clearHistory()` + +清除导航历史. + +### `webContents.goBack()` + +让浏览器回退到前一个page. + +### `webContents.goForward()` + +让浏览器回前往下一个page. + +### `webContents.goToIndex(index)` + +* `index` Integer + +让浏览器回前往指定 `index` 的page. + +### `webContents.goToOffset(offset)` + +* `offset` Integer + +导航到相对于当前页的偏移位置页. + +### `webContents.isCrashed()` + +渲染进程是否崩溃. + +### `webContents.setUserAgent(userAgent)` + +* `userAgent` String + +重写本页用户代理. + +### `webContents.getUserAgent()` + +返回一个 `String` ,标识本页用户代理信息. + +### `webContents.insertCSS(css)` + +* `css` String + +为当前页插入css. + +### `webContents.executeJavaScript(code[, userGesture, callback])` + +* `code` String +* `userGesture` Boolean (可选) +* `callback` Function (可选) - 脚本执行完成后调用的回调函数. + * `result` + +评估 page `代码`. + +浏览器窗口中的一些 HTML API ,例如 `requestFullScreen`,只能被用户手势请求.设置 `userGesture` 为 `true` 可以取消这个限制. + +### `webContents.setAudioMuted(muted)` + +* `muted` Boolean + +减缓当前也的 audio 的播放速度. + +### `webContents.isAudioMuted()` + +返回一个布尔值,标识当前页是否减缓了 audio 的播放速度. + +### `webContents.undo()` + +执行网页的编辑命令 `undo` . + +### `webContents.redo()` + +执行网页的编辑命令 `redo` . + +### `webContents.cut()` + +执行网页的编辑命令 `cut` . + +### `webContents.copy()` + +执行网页的编辑命令 `copy` . + +### `webContents.paste()` + +执行网页的编辑命令 `paste` . + +### `webContents.pasteAndMatchStyle()` + +执行网页的编辑命令 `pasteAndMatchStyle` . + +### `webContents.delete()` + +执行网页的编辑命令 `delete` . + +### `webContents.selectAll()` + +执行网页的编辑命令 `selectAll` . + +### `webContents.unselect()` + +执行网页的编辑命令 `unselect` . + +### `webContents.replace(text)` + +* `text` String + +执行网页的编辑命令 `replace` . + +### `webContents.replaceMisspelling(text)` + +* `text` String + +执行网页的编辑命令 `replaceMisspelling` . + +### `webContents.insertText(text)` + +* `text` String + +插入 `text` 到获得了焦点的元素. + +### `webContents.findInPage(text[, options])` + +* `text` String - 查找内容, 不能为空. +* `options` Object (可选) + * `forward` Boolean - 是否向前或向后查找, 默认为 `true`. + * `findNext` Boolean - 当前操作是否是第一次查找或下一次查找, + 默认为 `false`. + * `matchCase` Boolean - 查找是否区分大小写, + 默认为 `false`. + * `wordStart` Boolean -是否仅以首字母查找. + 默认为 `false`. + * `medialCapitalAsWordStart` Boolean - 是否结合 `wordStart`,如果匹配是大写字母开头,后面接小写字母或无字母,那么就接受这个词中匹配.接受几个其它的合成词匹配, 默认为 `false`. + +发起请求,在网页中查找所有与 `text` 相匹配的项,并且返回一个 `Integer` 来表示这个请求用的请求Id.这个请求结果可以通过订阅 + [`found-in-page`](web-contents.md#event-found-in-page) 事件来取得. + +### `webContents.stopFindInPage(action)` + +* `action` String - 指定一个行为来接替停止 + [`webContents.findInPage`](web-contents.md#webcontentfindinpage) 请求. + * `clearSelection` - 转变为一个普通的 selection. + * `keepSelection` - 清除 selection. + * `activateSelection` - 获取焦点并点击 selection node. + +使用给定的 `action` 来为 `webContents` 停止任何 `findInPage` 请求. + +```javascript +webContents.on('found-in-page', function(event, result) { + if (result.finalUpdate) + webContents.stopFindInPage("clearSelection"); +}); + +const requestId = webContents.findInPage("api"); +``` + +### `webContents.hasServiceWorker(callback)` + +* `callback` Function + +检查是否有任何 ServiceWorker 注册了,并且返回一个布尔值,来作为 `callback`响应的标识. + +### `webContents.unregisterServiceWorker(callback)` + +* `callback` Function + +如果存在任何 ServiceWorker ,则全部注销,并且当JS承诺执行行或JS拒绝执行而失败的时候,返回一个布尔值,它标识了相应的 `callback`. + +### `webContents.print([options])` + +* `options` Object (可选) + * `silent` Boolean - 不需要请求用户的打印设置. 默认为 `false`. + * `printBackground` Boolean - 打印背景和网页图片. 默认为 `false`. + +打印窗口的网页. 当设置 `silent` 为 `false` 的时候,Electron 将使用系统默认的打印机和打印方式来打印. + +在网页中调用 `window.print()` 和 调用 `webContents.print({silent: false, printBackground: false})`具有相同的作用. + +**注意:** 在 Windows, 打印 API 依赖于 `pdf.dll`. 如果你的应用不使用任何的打印, 你可以安全删除 `pdf.dll` 来减少二进制文件的size. + +### `webContents.printToPDF(options, callback)` + +* `options` Object + * `marginsType` Integer - 指定使用的 margin type. 默认 margin 使用 0, 无 margin 使用 1, 最小化 margin 使用 2. + * `pageSize` String - 指定生成的PDF文件的page size. 可以是 `A3`, + `A4`, `A5`, `Legal`, `Letter` 和 `Tabloid`. + * `printBackground` Boolean - 是否打印 css 背景. + * `printSelectionOnly` Boolean - 是否只打印选中的部分. + * `landscape` Boolean - landscape 为 `true`, portrait 为 `false`. +* `callback` Function + +打印窗口的网页为 pdf ,使用 Chromium 预览打印的自定义设置. + +完成时使用 `callback(error, data)` 调用 `callback` . `data` 是一个 `Buffer` ,包含了生成的 pdf 数据. + +默认,空的 `options` 被视为 : + +```javascript +{ + marginsType: 0, + printBackground: false, + printSelectionOnly: false, + landscape: false +} +``` + +```javascript +const BrowserWindow = require('electron').BrowserWindow; +const fs = require('fs'); + +var win = new BrowserWindow({width: 800, height: 600}); +win.loadURL("http://github.com"); + +win.webContents.on("did-finish-load", function() { + // Use default printing options + win.webContents.printToPDF({}, function(error, data) { + if (error) throw error; + fs.writeFile("/tmp/print.pdf", data, function(error) { + if (error) + throw error; + console.log("Write PDF successfully."); + }) + }) +}); +``` + +### `webContents.addWorkSpace(path)` + +* `path` String + +添加指定的路径给开发者工具栏的 workspace.必须在 DevTools 创建之后使用它 : + +```javascript +mainWindow.webContents.on('devtools-opened', function() { + mainWindow.webContents.addWorkSpace(__dirname); +}); +``` + +### `webContents.removeWorkSpace(path)` + +* `path` String + +从开发者工具栏的 workspace 删除指定的路径. + +### `webContents.openDevTools([options])` + +* `options` Object (可选) + * `detach` Boolean - 在一个新窗口打开开发者工具栏 + +打开开发者工具栏. + +### `webContents.closeDevTools()` + +关闭开发者工具栏. + +### `webContents.isDevToolsOpened()` + +返回布尔值,开发者工具栏是否打开. + +### `webContents.isDevToolsFocused()` + +返回布尔值,开发者工具栏视图是否获得焦点. + +### `webContents.toggleDevTools()` + +Toggles 开发者工具. + +### `webContents.inspectElement(x, y)` + +* `x` Integer +* `y` Integer + +在 (`x`, `y`) 开始检测元素. + +### `webContents.inspectServiceWorker()` + +为 service worker 上下文打开开发者工具栏. + +### `webContents.send(channel[, arg1][, arg2][, ...])` + +* `channel` String +* `arg` (可选) + +通过 `channel` 发送异步消息给渲染进程,你也可发送任意的参数.参数应该在 JSON 内部序列化,并且此后没有函数或原形链被包括了. + +渲染进程可以通过使用 `ipcRenderer` 监听 `channel` 来处理消息. + +例子,从主进程向渲染进程发送消息 : + +```javascript +// 主进程. +var window = null; +app.on('ready', function() { + window = new BrowserWindow({width: 800, height: 600}); + window.loadURL('file://' + __dirname + '/index.html'); + window.webContents.on('did-finish-load', function() { + window.webContents.send('ping', 'whoooooooh!'); + }); +}); +``` + +```html + + + + + + +``` + +### `webContents.enableDeviceEmulation(parameters)` + +`parameters` Object, properties: + +* `screenPosition` String - 指定需要模拟的屏幕 + (默认 : `desktop`) + * `desktop` + * `mobile` +* `screenSize` Object - 设置模拟屏幕 size (screenPosition == mobile) + * `width` Integer - 设置模拟屏幕 width + * `height` Integer - 设置模拟屏幕 height +* `viewPosition` Object - 在屏幕放置 view + (screenPosition == mobile) (默认: `{x: 0, y: 0}`) + * `x` Integer - 设置偏移左上角的x轴 + * `y` Integer - 设置偏移左上角的y轴 +* `deviceScaleFactor` Integer - 设置设备比例因子 (如果为0,默认为原始屏幕比例) (默认: `0`) +* `viewSize` Object - 设置模拟视图 size (空表示不覆盖) + * `width` Integer - 设置模拟视图 width + * `height` Integer - 设置模拟视图 height +* `fitToView` Boolean - 如果有必要的话,是否把模拟视图按比例缩放来适应可用空间 (默认: `false`) +* `offset` Object - 可用空间内的模拟视图偏移 (不在适应模式) (默认: `{x: 0, y: 0}`) + * `x` Float - 设置相对左上角的x轴偏移值 + * `y` Float - 设置相对左上角的y轴偏移值 +* `scale` Float - 可用空间内的模拟视图偏移 (不在适应视图模式) (默认: `1`) + +使用给定的参数来开启设备模拟. + +### `webContents.disableDeviceEmulation()` + +使用 `webContents.enableDeviceEmulation` 关闭设备模拟. + +### `webContents.sendInputEvent(event)` + +* `event` Object + * `type` String (**必需**) - 事件类型,可以是 `mouseDown`, + `mouseUp`, `mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`, + `mouseMove`, `keyDown`, `keyUp`, `char`. + * `modifiers` Array - 事件的 modifiers 数组, 可以是 + include `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`, + `leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`, + `numLock`, `left`, `right`. + +向 page 发送一个输入 `event` . + +对键盘事件来说,`event` 对象还有如下属性 : + +* `keyCode` String (**必需**) - 特点是将作为键盘事件发送. 可用的 key codes [Accelerator](accelerator.md). + + +对鼠标事件来说,`event` 对象还有如下属性 : + +* `x` Integer (**required**) +* `y` Integer (**required**) +* `button` String - button 按下, 可以是 `left`, `middle`, `right` +* `globalX` Integer +* `globalY` Integer +* `movementX` Integer +* `movementY` Integer +* `clickCount` Integer + +对鼠标滚轮事件来说,`event` 对象还有如下属性 : + +* `deltaX` Integer +* `deltaY` Integer +* `wheelTicksX` Integer +* `wheelTicksY` Integer +* `accelerationRatioX` Integer +* `accelerationRatioY` Integer +* `hasPreciseScrollingDeltas` Boolean +* `canScroll` Boolean + +### `webContents.beginFrameSubscription(callback)` + +* `callback` Function + +开始订阅 提交 事件和捕获数据帧,当有 提交 事件时,使用 `callback(frameBuffer)` 调用 `callback`. + +`frameBuffer` 是一个包含原始像素数据的 `Buffer`,像素数据是按照 32bit BGRA 格式有效存储的,但是实际情况是取决于处理器的字节顺序的(大多数的处理器是存放小端序的,如果是在大端序的处理器上,数据是 32bit ARGB 格式). + +### `webContents.endFrameSubscription()` + +停止订阅帧提交事件. + +### `webContents.savePage(fullPath, saveType, callback)` + +* `fullPath` String - 文件的完整路径. +* `saveType` String - 指定保存类型. + * `HTMLOnly` - 只保存html. + * `HTMLComplete` - 保存整个 page 内容. + * `MHTML` - 保存完整的 html 为 MHTML. +* `callback` Function - `function(error) {}`. + * `error` Error + +如果保存界面过程初始化成功,返回 true. + +```javascript +win.loadURL('https://github.com'); + +win.webContents.on('did-finish-load', function() { + win.webContents.savePage('/tmp/test.html', 'HTMLComplete', function(error) { + if (!error) + console.log("Save page successfully"); + }); +}); +``` + +## 实例属性 + +`WebContents` 对象也有下列属性: + +### `webContents.session` + +返回这个 `webContents` 使用的 [session](session.md) 对象. + +### `webContents.hostWebContents` + +返回这个 `webContents` 的父 `webContents` . + +### `webContents.devToolsWebContents` + +获取这个 `WebContents` 的开发者工具栏的 `WebContents` . + +**注意:** 用户不可保存这个对象,因为当开发者工具栏关闭的时候它的值为 `null` . + +### `webContents.debugger` + +调试 API 为 [remote debugging protocol][rdp] 提供交替传送. + +```javascript +try { + win.webContents.debugger.attach("1.1"); +} catch(err) { + console.log("Debugger attach failed : ", err); +}; + +win.webContents.debugger.on('detach', function(event, reason) { + console.log("Debugger detached due to : ", reason); +}); + +win.webContents.debugger.on('message', function(event, method, params) { + if (method == "Network.requestWillBeSent") { + if (params.request.url == "https://www.github.com") + win.webContents.debugger.detach(); + } +}) + +win.webContents.debugger.sendCommand("Network.enable"); +``` + +#### `webContents.debugger.attach([protocolVersion])` + +* `protocolVersion` String (可选) - 请求调试协议版本. + +添加 `webContents` 调试. + +#### `webContents.debugger.isAttached()` + +返回一个布尔值,标识是否已经给 `webContents` 添加了调试. + +#### `webContents.debugger.detach()` + +删除 `webContents` 调试. + +#### `webContents.debugger.sendCommand(method[, commandParams, callback])` + +* `method` String - 方法名, 应该是由远程调试协议定义的方法. +* `commandParams` Object (可选) - 请求参数为 JSON 对象. +* `callback` Function (可选) - Response + * `error` Object - 错误消息,标识命令失败. + * `result` Object - 回复在远程调试协议中由 'returns'属性定义的命令描述. + +发送给定命令给调试目标. + +#### Event: 'detach' + +* `event` Event +* `reason` String - 拆分调试器原因. + +在调试 session 结束时发出事件.这在 `webContents` 关闭时或 `webContents` 请求开发者工具栏时发生. + +#### Event: 'message' + +* `event` Event +* `method` String - 方法名. +* `params` Object - 在远程调试协议中由 'parameters' 属性定义的事件参数. + +每当调试目标发出事件时发出. + +[rdp]: https://developer.chrome.com/devtools/docs/debugger-protocol \ No newline at end of file From 3ee4790dab54385a4cd83a2fab8deb185b19c902 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 14 Mar 2016 20:36:48 -0700 Subject: [PATCH 500/688] Automatically set app user model ID We shouldn't ask users to figure out this piece of Windows Arcana when they're using Squirrel, let's just do it automatically. --- lib/browser/init.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/browser/init.js b/lib/browser/init.js index e1105df9b13..471cc3a5a0a 100644 --- a/lib/browser/init.js +++ b/lib/browser/init.js @@ -78,6 +78,35 @@ app.on('quit', function(event, exitCode) { return process.emit('exit', exitCode); }); +if (process.platform === 'win32') { + // If we are a Squirrel.Windows-installed app, set app user model ID + // so that users don't have to do this. + // + // Squirrel packages are always of the form: + // + // PACKAGE-NAME + // - Update.exe + // - app-VERSION + // - OUREXE.exe + // + // Squirrel itself will always set the shortcut's App User Model ID to the + // form `com.squirrel.PACKAGE-NAME.OUREXE`. We need to call + // app.setAppUserModelId with a matching identifier so that renderer processes + // will inherit this value. + var updateDotExe = path.join( + path.dirname(process.execPath), + '..', + 'update.exe'); + + if (fs.statSyncNoException(updateDotExe)) { + var packageDir = path.dirname(path.resolve(updateDotExe)); + var packageName = path.basename(packageDir); + var exeName = path.basename(process.execPath).replace(/\.exe$/i, ''); + + app.setAppUserModelId(`com.squirrel.${packageName}.${exeName}`); + } +} + // Map process.exit to app.exit, which quits gracefully. process.exit = app.exit; From 665d3166ed02a3d169f69d3a52cd5fad2996803e Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 14 Mar 2016 21:00:58 -0700 Subject: [PATCH 501/688] Update the tests --- spec/api-native-image-spec.js | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index 587ea876f29..e411fb11002 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -40,26 +40,12 @@ describe('nativeImage module', () => { const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; const image = nativeImage.createFromPath(imagePath); - const nsimage = image.asNativeRepresentation('nsimage'); + const nsimage = image.getNativeHandle(); assert.equal(nsimage.length, 8); // If all bytes are null, that's Bad assert.equal(nsimage.reduce((acc,x) => acc || (x != 0)), true); }); - - it('Throws when asNativeRepresentation gets a bogus value', () => { - const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; - const image = nativeImage.createFromPath(imagePath); - - let shouldDie = true; - try { - image.asNativeRepresentation('__foobar__'); - } catch (e) { - shouldDie = false; - } - - assert.equal(shouldDie, false); - }); }); }); From 3c007d1333f7908e32d6b644f43547e5bf0ecc7a Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Tue, 15 Mar 2016 14:00:40 +0800 Subject: [PATCH 502/688] add tray first --- docs-translations/zh-CN/api/tray.md | 205 ++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 docs-translations/zh-CN/api/tray.md diff --git a/docs-translations/zh-CN/api/tray.md b/docs-translations/zh-CN/api/tray.md new file mode 100644 index 00000000000..d5647871ac7 --- /dev/null +++ b/docs-translations/zh-CN/api/tray.md @@ -0,0 +1,205 @@ +# Tray + +用一个 `Tray` 来表示一个图标,这个图标处于正在运行的系统的通知区 ,通常被添加到一个 context menu 上. + +```javascript +const electron = require('electron'); +const app = electron.app; +const Menu = electron.Menu; +const Tray = electron.Tray; + +var appIcon = null; +app.on('ready', function(){ + appIcon = new Tray('/path/to/my/icon'); + var contextMenu = Menu.buildFromTemplate([ + { label: 'Item1', type: 'radio' }, + { label: 'Item2', type: 'radio' }, + { label: 'Item3', type: 'radio', checked: true }, + { label: 'Item4', type: 'radio' } + ]); + appIcon.setToolTip('This is my application.'); + appIcon.setContextMenu(contextMenu); +}); + +``` + +__平台限制:__ + +* 在 Linux, 如果支持应用指示器则使用它,否则使用 `GtkStatusIcon` 代替. +* 在 Linux ,配置了只有有了应用指示器的支持, 你必须安装 `libappindicator1` 来让 tray icon 执行. +* 应用指示器只有在它拥有 context menu 时才会显示. +* 当在linux 上使用了应用指示器,将忽略点击事件. +* 在 Linux,为了让单独的 `MenuItem` 起效,需要再次调用 `setContextMenu` .例如: + +```javascript +contextMenu.items[2].checked = false; +appIcon.setContextMenu(contextMenu); +``` +如果想在所有平台保持完全相同的行为,不应该依赖点击事件,而是一直将一个 context menu 添加到 tray icon. + +## Class: Tray + +`Tray` 是一个 [事件发出者][event-emitter]. + +### `new Tray(image)` + +* `image` [NativeImage](native-image.md) + +创建一个与 `image` 相关的 icon. + +## 事件 + +`Tray` 模块可发出下列事件: + +**注意:** 一些事件只能在特定的os中运行,已经标明. + +### Event: 'click' + +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean + * `metaKey` Boolean +* `bounds` Object - tray icon 的 bounds. + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer + +当tray icon被点击的时候发出事件. + +__注意:__ `bounds` 只在 OS X 和 Windows 上起效. + +### Event: 'right-click' _OS X_ _Windows_ + +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean + * `metaKey` Boolean +* `bounds` Object - tray icon 的 bounds. + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer + +当tray icon被鼠标右键点击的时候发出事件. + +### Event: 'double-click' _OS X_ _Windows_ + +* `event` Event + * `altKey` Boolean + * `shiftKey` Boolean + * `ctrlKey` Boolean + * `metaKey` Boolean +* `bounds` Object - tray icon 的 bounds. + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer + +当tray icon被双击的时候发出事件. + +### Event: 'balloon-show' _Windows_ + +当tray 气泡显示的时候发出事件. + +### Event: 'balloon-click' _Windows_ + +当tray 气泡被点击的时候发出事件. + +### Event: 'balloon-closed' _Windows_ + +当tray 气泡关闭的时候发出事件,因为超时或人为关闭. + +### Event: 'drop' _OS X_ + +当tray icon上的任何可拖动项被删除的时候发出事件. + +### Event: 'drop-files' _OS X_ + +* `event` +* `files` Array - 已删除文件的路径. + +当tray icon上的可拖动文件被删除的时候发出事件. + +### Event: 'drag-enter' _OS X_ + +当一个拖动操作进入tray icon的时候发出事件. + +### Event: 'drag-leave' _OS X_ + +当一个拖动操作离开tray icon的时候发出事件. +Emitted when a drag operation exits the tray icon. + +### Event: 'drag-end' _OS X_ + +当一个拖动操作在tray icon上或其它地方停止拖动的时候发出事件. + +## 方法 + +`Tray` 模块有以下方法: + +**Note:** 一些方法只能在特定的os中运行,已经标明. + +### `Tray.destroy()` + +立刻删除 tray icon. + +### `Tray.setImage(image)` + +* `image` [NativeImage](native-image.md) + +让 `image` 与 tray icon 关联起来. + +### `Tray.setPressedImage(image)` _OS X_ + +* `image` [NativeImage](native-image.md) + +当在 OS X 上按压 tray icon 的时候, 让 `image` 与 tray icon 关联起来. + +### `Tray.setToolTip(toolTip)` + +* `toolTip` String + +为 tray icon 设置 hover text. + +### `Tray.setTitle(title)` _OS X_ + +* `title` String + +在状态栏沿着 tray icon 设置标题. + +### `Tray.setHighlightMode(highlight)` _OS X_ + +* `highlight` Boolean + +当 tray icon 被点击的时候,是否设置它的背景色变为高亮(blue).默认为 true. + +### `Tray.displayBalloon(options)` _Windows_ + +* `options` Object + * `icon` [NativeImage](native-image.md) + * `title` String + * `content` String + +展示一个 tray balloon. + +### `Tray.popUpContextMenu([menu, position])` _OS X_ _Windows_ + +* `menu` Menu (optional) +* `position` Object (可选) - 上托位置. + * `x` Integer + * `y` Integer + +从 tray icon 上托出 context menu . 当划过 `menu` 的时候, `menu` 显示,代替 tray 的 context menu . + +`position` 只在 windows 上可用,默认为 (0, 0) . + +### `Tray.setContextMenu(menu)` + +* `menu` Menu + +为这个 icon 设置 context menu . + +[event-emitter]: http://nodejs.org/api/events.html#events_class_events_eventemitter \ No newline at end of file From c2c91b6477a8842234d194bde62320e339e5d4b4 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Tue, 15 Mar 2016 15:11:28 +0800 Subject: [PATCH 503/688] add three render process's files first --- .../zh-CN/api/desktop-capturer.md | 64 +++++++++++ docs-translations/zh-CN/api/ipc-renderer.md | 69 ++++++++++++ docs-translations/zh-CN/api/web-frame.md | 101 ++++++++++++++++++ 3 files changed, 234 insertions(+) create mode 100644 docs-translations/zh-CN/api/desktop-capturer.md create mode 100644 docs-translations/zh-CN/api/ipc-renderer.md create mode 100644 docs-translations/zh-CN/api/web-frame.md diff --git a/docs-translations/zh-CN/api/desktop-capturer.md b/docs-translations/zh-CN/api/desktop-capturer.md new file mode 100644 index 00000000000..954520d05ea --- /dev/null +++ b/docs-translations/zh-CN/api/desktop-capturer.md @@ -0,0 +1,64 @@ +# desktopCapturer + +`desktopCapturer` 模块可用来获取可用资源,这个资源可通过 `getUserMedia` 捕获得到. + +```javascript +// 在渲染进程中. +var desktopCapturer = require('electron').desktopCapturer; + +desktopCapturer.getSources({types: ['window', 'screen']}, function(error, sources) { + if (error) throw error; + for (var i = 0; i < sources.length; ++i) { + if (sources[i].name == "Electron") { + navigator.webkitGetUserMedia({ + audio: false, + video: { + mandatory: { + chromeMediaSource: 'desktop', + chromeMediaSourceId: sources[i].id, + minWidth: 1280, + maxWidth: 1280, + minHeight: 720, + maxHeight: 720 + } + } + }, gotStream, getUserMediaError); + return; + } + } +}); + +function gotStream(stream) { + document.querySelector('video').src = URL.createObjectURL(stream); +} + +function getUserMediaError(e) { + console.log('getUserMediaError'); +} +``` + +当调用 `navigator.webkitGetUserMedia` 时创建一个约束对象,如果使用 `desktopCapturer` 的资源,必须设置 `chromeMediaSource` 为 `"desktop"` ,并且 `audio` 为 `false`. + +如果你想捕获整个桌面的 audio 和 video,你可以设置 `chromeMediaSource` 为 `"screen"` ,和 `audio` 为 `true`. +当使用这个方法的时候,不可以指定一个 `chromeMediaSourceId`. + +## 方法 + +`desktopCapturer` 模块有如下方法: + +### `desktopCapturer.getSources(options, callback)` + +* `options` Object + * `types` Array - 一个 String 数组,列出了可以捕获的桌面资源类型, 可用类型为 `screen` 和 `window`. + * `thumbnailSize` Object (可选) - 建议缩略可被缩放的 size, 默认为 `{width: 150, height: 150}`. +* `callback` Function + +发起一个请求,获取所有桌面资源,当请求完成的时候使用 `callback(error, sources)` 调用 `callback` . + +`sources` 是一个 `Source` 对象数组, 每个 `Source` 表示了一个捕获的屏幕或单独窗口,并且有如下属性 : +* `id` String - 在 `navigator.webkitGetUserMedia` 中使用的捕获窗口或屏幕的 id . 格式为 `window:XX` 祸 + `screen:XX`,`XX` 是一个随机数. +* `name` String - 捕获窗口或屏幕的描述名 . 如果资源为屏幕,名字为 `Entire Screen` 或 `Screen `; 如果资源为窗口, 名字为窗口的标题. +* `thumbnail` [NativeImage](NativeImage.md) - 缩略图. + +**注意:** 不能保证 `source.thumbnail` 的 size 和 `options` 中的 `thumnbailSize` 一直一致. 它也取决于屏幕或窗口的缩放比例. \ No newline at end of file diff --git a/docs-translations/zh-CN/api/ipc-renderer.md b/docs-translations/zh-CN/api/ipc-renderer.md new file mode 100644 index 00000000000..beeaa6d7623 --- /dev/null +++ b/docs-translations/zh-CN/api/ipc-renderer.md @@ -0,0 +1,69 @@ +# ipcRenderer + +`ipcRenderer` 模块是一个 +[EventEmitter](https://nodejs.org/api/events.html) 类的实例. 它提供了有限的方法,你可以从渲染进程向主进程发送同步或异步消息. 也可以收到主进程的相应. + +查看 [ipcMain](ipc-main.md) 代码例子. + +## 消息监听 + +`ipcRenderer` 模块有下列方法来监听事件: + +### `ipcRenderer.on(channel, listener)` + +* `channel` String +* `listener` Function + +监听 `channel`, 当有新消息到达,使用 `listener(event, args...)` 调用 `listener` . + +### `ipcRenderer.once(channel, listener)` + +* `channel` String +* `listener` Function + +为这个事件添加一个一次性 `listener` 函数.这个 `listener` 将在下一次有新消息被发送到 `channel` 的时候被请求调用,之后就被删除了. + +### `ipcRenderer.removeListener(channel, listener)` + +* `channel` String +* `listener` Function + +从指定的 `channel` 中的监听者数组删除指定的 `listener` . + +### `ipcRenderer.removeAllListeners([channel])` + +* `channel` String (optional) + +删除所有的监听者,或者删除指定 `channel` 中的全部. + +## 发送消息 + +`ipcRenderer` 模块有如下方法来发送消息: + +### `ipcRenderer.send(channel[, arg1][, arg2][, ...])` + +* `channel` String +* `arg` (可选) + +通过 `channel` 向主进程发送异步消息,也可以发送任意参数.参数会被JSON序列化,之后就不会包含函数或原型链. + +主进程通过使用 `ipcMain` 模块来监听 `channel`,从而处理消息. + +### `ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])` + +* `channel` String +* `arg` (可选) + +通过 `channel` 向主进程发送同步消息,也可以发送任意参数.参数会被JSON序列化,之后就不会包含函数或原型链. + +主进程通过使用 `ipcMain` 模块来监听 `channel`,从而处理消息, +通过 `event.returnValue` 来响应. + +__注意:__ 发送同步消息将会阻塞整个渲染进程,除非你知道你在做什么,否则就永远不要用它 . + +### `ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])` + +* `channel` String +* `arg` (可选) + +类似 `ipcRenderer.send` ,但是它的事件将发往 host page 的 `` 元素,而不是主进程. \ No newline at end of file diff --git a/docs-translations/zh-CN/api/web-frame.md b/docs-translations/zh-CN/api/web-frame.md new file mode 100644 index 00000000000..d278e942713 --- /dev/null +++ b/docs-translations/zh-CN/api/web-frame.md @@ -0,0 +1,101 @@ +# webFrame + +`web-frame` 模块允许你自定义如何渲染当前网页 . + +例子,放大当前页到 200%. + +```javascript +var webFrame = require('electron').webFrame; + +webFrame.setZoomFactor(2); +``` + +## 方法 + +`web-frame` 模块有如下方法: + +### `webFrame.setZoomFactor(factor)` + +* `factor` Number - 缩放参数. + +将缩放参数修改为指定的参数值.缩放参数是百分制的,所以 300% = 3.0. + +### `webFrame.getZoomFactor()` + +返回当前缩放参数值. + +### `webFrame.setZoomLevel(level)` + +* `level` Number - 缩放水平 + +将缩放水平修改为指定的水平值. 原始 size 为 0 ,并且每次增长都表示放大 20% 或缩小 20%,默认限制为原始 size 的 300% 到 50% 之间 . + +### `webFrame.getZoomLevel()` + +返回当前缩放水平值. + +### `webFrame.setZoomLevelLimits(minimumLevel, maximumLevel)` + +* `minimumLevel` Number +* `maximumLevel` Number + +设置缩放水平的最大值和最小值. + +### `webFrame.setSpellCheckProvider(language, autoCorrectWord, provider)` + +* `language` String +* `autoCorrectWord` Boolean +* `provider` Object + +为输入框或文本域设置一个拼写检查 provider . + +`provider` 必须是一个对象,它有一个 `spellCheck` 方法,这个方法返回扫过的单词是否拼写正确 . + +例子,使用 [node-spellchecker][spellchecker] 作为一个 provider: + +```javascript +webFrame.setSpellCheckProvider("en-US", true, { + spellCheck: function(text) { + return !(require('spellchecker').isMisspelled(text)); + } +}); +``` + +### `webFrame.registerURLSchemeAsSecure(scheme)` + +* `scheme` String + +注册 `scheme` 为一个安全的 scheme. + + +安全的 schemes 不会引发混合内容 warnings.例如, `https` 和 +`data` 是安全的 schemes ,因为它们不能被活跃网络攻击而失效. + +### `webFrame.registerURLSchemeAsBypassingCSP(scheme)` + +* `scheme` String + +忽略当前网页内容的安全策略,直接从 `scheme` 加载. + +### `webFrame.registerURLSchemeAsPrivileged(scheme)` + +* `scheme` String + +通过资源的内容安全策略,注册 `scheme` 为安全的 scheme,允许注册 ServiceWorker并且支持 fetch API. + +### `webFrame.insertText(text)` + +* `text` String + +向获得焦点的原色插入内容 . + +### `webFrame.executeJavaScript(code[, userGesture])` + +* `code` String +* `userGesture` Boolean (可选) - 默认为 `false`. + +评估页面代码 . + +在浏览器窗口中,一些 HTML APIs ,例如 `requestFullScreen`,只可以通过用户手势来使用.设置`userGesture` 为 `true` 可以突破这个限制 . + +[spellchecker]: https://github.com/atom/node-spellchecker \ No newline at end of file From b105bf59c129e2f6320e74923333d3c3a6a6f1e5 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Tue, 15 Mar 2016 17:03:48 +0800 Subject: [PATCH 504/688] add last api files first --- docs-translations/zh-CN/api/clipboard.md | 117 +++++++++++++++ docs-translations/zh-CN/api/crash-reporter.md | 61 ++++++++ docs-translations/zh-CN/api/native-image.md | 142 ++++++++++++++++++ docs-translations/zh-CN/api/screen.md | 135 +++++++++++++++++ 4 files changed, 455 insertions(+) create mode 100644 docs-translations/zh-CN/api/clipboard.md create mode 100644 docs-translations/zh-CN/api/crash-reporter.md create mode 100644 docs-translations/zh-CN/api/native-image.md create mode 100644 docs-translations/zh-CN/api/screen.md diff --git a/docs-translations/zh-CN/api/clipboard.md b/docs-translations/zh-CN/api/clipboard.md new file mode 100644 index 00000000000..77aa6d65c0b --- /dev/null +++ b/docs-translations/zh-CN/api/clipboard.md @@ -0,0 +1,117 @@ +# clipboard + +`clipboard` 模块提供方法来供复制和粘贴操作 . +下面例子展示了如何将一个字符串写道 clipboard 上: + +```javascript +const clipboard = require('electron').clipboard; +clipboard.writeText('Example String'); +``` + +在 X Window 系统上, 有一个可选的 clipboard. 你可以为每个方法使用 `selection` 来控制它: + +```javascript +clipboard.writeText('Example String', 'selection'); +console.log(clipboard.readText('selection')); +``` + +## 方法 + +`clipboard` 模块有以下方法: + +**注意:** 测试 APIs 已经标明,并且在将来会被删除 . + +### `clipboard.readText([type])` + +* `type` String (可选) + +以纯文本形式从 clipboard 返回内容 . + +### `clipboard.writeText(text[, type])` + +* `text` String +* `type` String (可选) + +以纯文本形式向 clipboard 添加内容 . + +### `clipboard.readHtml([type])` + +* `type` String (可选) + +返回 clipboard 中的标记内容. + +### `clipboard.writeHtml(markup[, type])` + +* `markup` String +* `type` String (可选) + +向 clipboard 添加 `markup` 内容 . + +### `clipboard.readImage([type])` + +* `type` String (可选) + +从 clipboard 中返回 [NativeImage](native-image.md) 内容. + +### `clipboard.writeImage(image[, type])` + +* `image` [NativeImage](native-image.md) +* `type` String (可选) + +向 clipboard 中写入 `image` . + +### `clipboard.readRtf([type])` + +* `type` String (可选) + +从 clipboard 中返回 RTF 内容. + +### `clipboard.writeRtf(text[, type])` + +* `text` String +* `type` String (可选) + +向 clipboard 中写入 RTF 格式的 `text` . + +### `clipboard.clear([type])` + +* `type` String (可选) + +清空 clipboard 内容. + +### `clipboard.availableFormats([type])` + +* `type` String (可选) + +返回 clipboard 支持的格式数组 . + +### `clipboard.has(data[, type])` _Experimental_ + +* `data` String +* `type` String (可选) + +返回 clipboard 是否支持指定 `data` 的格式. + +```javascript +console.log(clipboard.has('

selection

')); +``` + +### `clipboard.read(data[, type])` _Experimental_ + +* `data` String +* `type` String (可选) + +读取 clipboard 的 `data`. + +### `clipboard.write(data[, type])` + +* `data` Object + * `text` String + * `html` String + * `image` [NativeImage](native-image.md) +* `type` String (可选) + +```javascript +clipboard.write({text: 'test', html: "test"}); +``` +向 clipboard 写入 `data` . \ No newline at end of file diff --git a/docs-translations/zh-CN/api/crash-reporter.md b/docs-translations/zh-CN/api/crash-reporter.md new file mode 100644 index 00000000000..a4646401ad8 --- /dev/null +++ b/docs-translations/zh-CN/api/crash-reporter.md @@ -0,0 +1,61 @@ +# crashReporter + +`crash-reporter` 模块开启发送应用崩溃报告. + +下面是一个自动提交崩溃报告给服务器的例子 : + +```javascript +const crashReporter = require('electron').crashReporter; + +crashReporter.start({ + productName: 'YourName', + companyName: 'YourCompany', + submitURL: 'https://your-domain.com/url-to-submit', + autoSubmit: true +}); +``` + +## 方法 + +`crash-reporter` 模块有如下方法: + +### `crashReporter.start(options)` + +* `options` Object + * `companyName` String + * `submitURL` String - 崩溃报告发送的路径,以post方式. + * `productName` String (可选) - 默认为 `Electron`. + * `autoSubmit` Boolean - 是否自动提交. + 默认为 `true`. + * `ignoreSystemCrashHandler` Boolean - 默认为 `false`. + * `extra` Object - 一个你可以定义的对象,附带在崩溃报告上一起发送 . 只有字符串属性可以被正确发送,不支持嵌套对象. + +只可以在使用其它 `crashReporter` APIs 之前使用这个方法. + +**注意:** 在 OS X, Electron 使用一个新的 `crashpad` 客户端, 与 Windows 和 Linux 的 `breakpad` 不同. 为了开启崩溃点搜集,你需要在主进程和其它每个你需要搜集崩溃报告的渲染进程中调用 `crashReporter.start` API 来初始化 `crashpad`. + +### `crashReporter.getLastCrashReport()` + +返回最后一个崩溃报告的日期和 ID.如果没有过崩溃报告发送过来,或者还没有开始崩溃报告搜集,将返回 `null` . + +### `crashReporter.getUploadedReports()` + +返回所有上载的崩溃报告,每个报告包含了上载日期和 ID. + +## crash-reporter Payload + +崩溃报告将发送下面的数据给 `POST` 型的 `提交 URL` : + +* `ver` String - Electron 版本. +* `platform` String - 例如 'win32'. +* `process_type` String - 例如 'renderer'. +* `guid` String - 例如 '5e1286fc-da97-479e-918b-6bfb0c3d1c72' +* `_version` String - `package.json` 版本. +* `_productName` String - `crashReporter` `options` + 对象中的产品名字. +* `prod` String - 基础产品名字. 这种情况为 Electron. +* `_companyName` String - `crashReporter` `options` + 对象中的公司名字. +* `upload_file_minidump` File - 崩溃报告为文件. +* `crashReporter` 中的 `extra` 对象的所有等级和一个属性. + `options` object \ No newline at end of file diff --git a/docs-translations/zh-CN/api/native-image.md b/docs-translations/zh-CN/api/native-image.md new file mode 100644 index 00000000000..cb2569922b2 --- /dev/null +++ b/docs-translations/zh-CN/api/native-image.md @@ -0,0 +1,142 @@ +# nativeImage + +在 Electron 中, 对所有创建 images 的 api 来说, 你可以使用文件路径或 `nativeImage` 实例. 如果使用 `null` ,将创建一个空的image 对象. + +例如, 当创建一个 tray 或设置窗口的图标时候,你可以使用一个字符串的图片路径 : + +```javascript +var appIcon = new Tray('/Users/somebody/images/icon.png'); +var window = new BrowserWindow({icon: '/Users/somebody/images/window.png'}); +``` + +或者从剪切板中读取图片,它返回的是 `nativeImage`: + +```javascript +var image = clipboard.readImage(); +var appIcon = new Tray(image); +``` + +## 支持的格式 + +当前支持 `PNG` 和 `JPEG` 图片格式. 推荐 `PNG` ,因为它支持透明和无损压缩. + +在 Windows, 你也可以使用 `ICO` 图标的格式. + +## 高分辨率图片 + +如果平台支持 high-DPI,你可以在图片基础路径后面添加 `@2x` ,可以标识它为高分辨率的图片. + +例如,如果 `icon.png` 是一个普通图片并且拥有标准分辨率,然后 `icon@2x.png`将被当作高分辨率的图片处理,它将拥有双倍 DPI 密度. + +如果想同时支持展示不同分辨率的图片,你可以将拥有不同size 的图片放在同一个文件夹下,不用 DPI 后缀.例如 : + +```text +images/ +├── icon.png +├── icon@2x.png +└── icon@3x.png +``` + + +```javascript +var appIcon = new Tray('/Users/somebody/images/icon.png'); +``` + +也支持下面这些 DPI 后缀: + +* `@1x` +* `@1.25x` +* `@1.33x` +* `@1.4x` +* `@1.5x` +* `@1.8x` +* `@2x` +* `@2.5x` +* `@3x` +* `@4x` +* `@5x` + +## 模板图片 + +模板图片由黑色和清色(和一个 alpha 通道)组成. +模板图片不是单独使用的,而是通常和其它内容混合起来创建期望的最终效果. + +最常见的用力是将模板图片用到菜单栏图片上,所以它可以同时适应亮、黑不同的菜单栏. + +**注意:** 模板图片只在 OS X 上可用. + +为了将图片标识为一个模板图片,它的文件名应当以 `Template` 结尾. 例如: + +* `xxxTemplate.png` +* `xxxTemplate@2x.png` + +## 方法 + +`nativeImage` 类有如下方法: + +### `nativeImage.createEmpty()` + +创建一个空的 `nativeImage` 实例. + +### `nativeImage.createFromPath(path)` + +* `path` String + +从指定 `path` 创建一个新的 `nativeImage` 实例 . + +### `nativeImage.createFromBuffer(buffer[, scaleFactor])` + +* `buffer` [Buffer][buffer] +* `scaleFactor` Double (可选) + +从 `buffer` 创建一个新的 `nativeImage` 实例 .默认 `scaleFactor` 是 1.0. + +### `nativeImage.createFromDataURL(dataURL)` + +* `dataURL` String + +从 `dataURL` 创建一个新的 `nativeImage` 实例 . + +## 实例方法 + +`nativeImage` 有如下方法: + +```javascript +const nativeImage = require('electron').nativeImage; + +var image = nativeImage.createFromPath('/Users/somebody/images/icon.png'); +``` + +### `image.toPng()` + +返回一个 [Buffer][buffer] ,它包含了图片的 `PNG` 编码数据. + +### `image.toJpeg(quality)` + +* `quality` Integer (**必须**) - 在 0 - 100 之间. + +返回一个 [Buffer][buffer] ,它包含了图片的 `JPEG` 编码数据. + +### `image.toDataURL()` + +返回图片数据的 URL. + +### `image.isEmpty()` + +返回一个 boolean ,标识图片是否为空. + +### `image.getSize()` + +返回图片的 size. + +[buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer + +### `image.setTemplateImage(option)` + +* `option` Boolean + +将图片标识为模板图片. + +### `image.isTemplateImage()` + +返回一个 boolean ,标识图片是否是模板图片. \ No newline at end of file diff --git a/docs-translations/zh-CN/api/screen.md b/docs-translations/zh-CN/api/screen.md new file mode 100644 index 00000000000..0de4c975afb --- /dev/null +++ b/docs-translations/zh-CN/api/screen.md @@ -0,0 +1,135 @@ +# screen + +`screen` 模块检索屏幕的 size,显示,鼠标位置等的信息.在 `app` 模块的`ready` 事件触发之前不可使用这个模块. + +`screen` 是一个 [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter). + +**注意:** 在渲染进程 / 开发者工具栏, `window.screen` 是一个预设值的 DOM +属性, 所以这样写 `var screen = require('electron').screen` 将不会工作. +在我们下面的例子, 我们取代使用可变名字的 `electronScreen`. +一个例子,创建一个充满真个屏幕的窗口 : + +```javascript +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; + +var mainWindow; + +app.on('ready', function() { + var electronScreen = electron.screen; + var size = electronScreen.getPrimaryDisplay().workAreaSize; + mainWindow = new BrowserWindow({ width: size.width, height: size.height }); +}); +``` + +另一个例子,在次页外创建一个窗口: + +```javascript +const electron = require('electron'); +const app = electron.app; +const BrowserWindow = electron.BrowserWindow; + +var mainWindow; + +app.on('ready', function() { + var electronScreen = electron.screen; + var displays = electronScreen.getAllDisplays(); + var externalDisplay = null; + for (var i in displays) { + if (displays[i].bounds.x != 0 || displays[i].bounds.y != 0) { + externalDisplay = displays[i]; + break; + } + } + + if (externalDisplay) { + mainWindow = new BrowserWindow({ + x: externalDisplay.bounds.x + 50, + y: externalDisplay.bounds.y + 50 + }); + } +}); +``` + +## `Display` 对象 + +`Display` 对象表示了物力方式连接系统. 一个伪造的 `Display` 或许存在于一个无头系统中,或者一个 `Display` 相当于一个远程的、虚拟的 display. + +* `display` object + * `id` Integer - 与display 相关的唯一性标志. + * `rotation` Integer - 可以是 0, 1, 2, 3, 每个代表了屏幕旋转的度数 0, 90, 180, 270. + * `scaleFactor` Number - Output device's pixel scale factor. + * `touchSupport` String - 可以是 `available`, `unavailable`, `unknown`. + * `bounds` Object + * `size` Object + * `workArea` Object + * `workAreaSize` Object + +## 事件 + +`screen` 模块有如下事件: + +### Event: 'display-added' + +返回: + +* `event` Event +* `newDisplay` Object + +当添加了 `newDisplay` 时发出事件 + +### Event: 'display-removed' + +返回: + +* `event` Event +* `oldDisplay` Object + +当移出了 `oldDisplay` 时发出事件 + +### Event: 'display-metrics-changed' + +返回: + +* `event` Event +* `display` Object +* `changedMetrics` Array + +当一个 `display` 中的一个或更多的 metrics 改变时发出事件. +`changedMetrics` 是一个用来描述这个改变的数组.可能的变化为 `bounds`, +`workArea`, `scaleFactor` 和 `rotation`. + +## 方法 + +`screen` 模块有如下方法: + +### `screen.getCursorScreenPoint()` + +返回当前鼠标的绝对路径 . + +### `screen.getPrimaryDisplay()` + +返回最主要的 display. + +### `screen.getAllDisplays()` + +返回一个当前可用的 display 数组. + +### `screen.getDisplayNearestPoint(point)` + +* `point` Object + * `x` Integer + * `y` Integer + +返回离指定点最近的 display. + +### `screen.getDisplayMatching(rect)` + +* `rect` Object + * `x` Integer + * `y` Integer + * `width` Integer + * `height` Integer + +返回与提供的边界范围最密切相关的 display. \ No newline at end of file From dbb8a6bf52887252fd8f92046c1104c6ac4c07b0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 15 Mar 2016 21:08:43 +0900 Subject: [PATCH 505/688] Update brightray for atom/brightray#204 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index bde17bffdf5..c7abfaafc70 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit bde17bffdf5ff978d5d831bdebb62d12bca6c715 +Subproject commit c7abfaafc70bdc22604574a8ed2b8c8a7c0e27d3 From 492269a0fdc2a19a39ece921ed6fe636838bcb46 Mon Sep 17 00:00:00 2001 From: Thanasis Polychronakis Date: Tue, 15 Mar 2016 15:49:34 +0200 Subject: [PATCH 506/688] More info for crash reporter form type and payload --- docs/api/crash-reporter.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index 98465dffc97..5a7ff720bfd 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -54,7 +54,7 @@ ID. ## crash-reporter Payload -The crash reporter will send the following data to the `submitURL` as `POST`: +The crash reporter will send the following data to the `submitURL` as a `multipart/form-data` `POST`: * `ver` String - The version of Electron. * `platform` String - e.g. 'win32'. @@ -66,6 +66,6 @@ The crash reporter will send the following data to the `submitURL` as `POST`: * `prod` String - Name of the underlying product. In this case Electron. * `_companyName` String - The company name in the `crashReporter` `options` object. -* `upload_file_minidump` File - The crash report as file. +* `upload_file_minidump` File - The crash report as file, a binary. * All level one properties of the `extra` object in the `crashReporter`. `options` object From 12f218c747850a66aefb2caf8686785d0d89583c Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Wed, 16 Mar 2016 10:26:49 +0800 Subject: [PATCH 507/688] add build-system-overview first --- .../development/build-system-overview.md | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 docs-translations/zh-CN/development/build-system-overview.md diff --git a/docs-translations/zh-CN/development/build-system-overview.md b/docs-translations/zh-CN/development/build-system-overview.md new file mode 100644 index 00000000000..20b0ff185fe --- /dev/null +++ b/docs-translations/zh-CN/development/build-system-overview.md @@ -0,0 +1,42 @@ +# Build System Overview + +Electron 使用 `gyp` 来生成项目 ,使用 `ninja` 来编译项目. 项目配置可以在 `.gyp` 和 `.gypi` 文件中找到. + +## Gyp 文件 + +下面的 `gyp` 文件包含了编译 Electron 的主要规则 : + +* `atom.gyp` 定义了 Electron 它自己是怎样被编译的. +* `common.gypi` 调整 node 的编译配置,来让它结合 Chromium 一起编译. +* `vendor/brightray/brightray.gyp` 定义了 `brightray` 是如何被编译的,并且包含了默认配置来连接到 Chromium. +* `vendor/brightray/brightray.gypi` 包含了常用的创建配置. + +## 创建组件 + +在 Chromium 还是一个相当大的项目的时候,最后链接阶段会花了好几分钟,这让开发变得很困难. 为了解决这个困难,Chromium 引入了 "component build" ,这让每个创建的组建都是分隔开的共享库,让链接更快,但是这浪费了文件大小和性能. + +在 Electron 中,我们采用了一个非常相似的方法 : 在创建 `Debug` , 二进制文件会被链接进入一个 Chromium 组件的共享版本库来达到快速链接; 在创建 `Release`, 二进制文件会被链接进入一个静态版本库, 所以我们可以有最小的二进制文件size和最佳的体验. + +## Minimal Bootstrapping + +在运行 bootstrap 脚本的时候,所有的 Chromium 预编译二进制文件会被下载.默认静态库和共享库会被下载,并且项目的最后大小会在 800MB 到 2GB 之间,这取决于平台类型. + +默认,`libchromiumcontent` 是从 Amazon Web Services 上下载下来的.如果设置了 `LIBCHROMIUMCONTENT_MIRROR` 环境变量,bootstrap脚本会从这里下载下来. [`libchromiumcontent-qiniu-mirror`](https://github.com/hokein/libchromiumcontent-qiniu-mirror) 是 `libchromiumcontent` 的映射.如果你不能连接 AWS,你可以切换下载路径:`export LIBCHROMIUMCONTENT_MIRROR=http://7xk3d2.dl1.z0.glb.clouddn.com/` +如果只是想快速搭建一个 Electron 的测试或开发环境,可以通过 `--dev` 参数只下载共享版本库: + +```bash +$ ./script/bootstrap.py --dev +$ ./script/build.py -c D +``` + +## Two-Phase Project Generation + +在 `Release` 和 `Debug` 编译的时候后,Electron 链接了不同配置的库 .然而 `gyp`不支持为不同的配置文件进行不同的链接设置. + +为了规避这个问题,Electron 在运行 `gyp` 的时候,使用了一个 `gyp` 的变量 `libchromiumcontent_component`来控制应该使用哪个链接设置,并且只生成一个目标. + +## Target Names + +与大多数的项目不同,它们使用 `Release` 和 `Debug` 作为目标名字,而 Electron 使用使用的是 `R` 和 `D`.这是因为如果只定义了一个 `Release` 或 `Debug` 编译配置,`gyp` 会随机崩溃,并且在同一时候,Electron 只生成一个目标,如上所述. + +这只对开发者可用,如果想重新编译 Electron ,将不会成功. \ No newline at end of file From 3eac767e729d59d76f67379ee72ef5b02b8291d6 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Wed, 16 Mar 2016 11:54:33 +0800 Subject: [PATCH 508/688] add build-instructions three first --- .../development/build-instructions-linux.md | 123 ++++++++++++++++ .../development/build-instructions-osx.md | 62 ++++++++ .../development/build-instructions-windows.md | 136 ++++++++++++++++++ .../development/build-system-overview.md | 16 +-- 4 files changed, 329 insertions(+), 8 deletions(-) create mode 100644 docs-translations/zh-CN/development/build-instructions-linux.md create mode 100644 docs-translations/zh-CN/development/build-instructions-osx.md create mode 100644 docs-translations/zh-CN/development/build-instructions-windows.md diff --git a/docs-translations/zh-CN/development/build-instructions-linux.md b/docs-translations/zh-CN/development/build-instructions-linux.md new file mode 100644 index 00000000000..0f76e78b9a5 --- /dev/null +++ b/docs-translations/zh-CN/development/build-instructions-linux.md @@ -0,0 +1,123 @@ +# Build Instructions (Linux) + +遵循下面的引导,在 Linux 上构建 Electron . + +## Prerequisites + +* Python 2.7.x. 一些发行版如 CentOS 仍然使用 Python 2.6.x ,所以或许需要 check 你的 Python 版本,使用 `python -V`. +* Node.js v0.12.x. 有很多方法来安装 Node. 可以从 [Node.js](http://nodejs.org)下载原文件并且编译它 .也可以作为一个标准的用户在 home 目录下安装 node .或者尝试使用仓库 [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories). +* Clang 3.4 或更新的版本. +* GTK+开发头文件和libnotify. + +在 Ubuntu, 安装下面的库 : + +```bash +$ sudo apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \ + libnotify-dev libgnome-keyring-dev libgconf2-dev \ + libasound2-dev libcap-dev libcups2-dev libxtst-dev \ + libxss1 libnss3-dev gcc-multilib g++-multilib +``` + +在 Fedora, 安装下面的库 : + +```bash +$ sudo yum install clang dbus-devel gtk2-devel libnotify-devel libgnome-keyring-devel \ + xorg-x11-server-utils libcap-devel cups-devel libXtst-devel \ + alsa-lib-devel libXrandr-devel GConf2-devel nss-devel +``` + +其它版本的也许提供了相似的包来安装,通过包管理器,例如 pacman. +或一个可以编译源文件的. + +## 使用虚拟机 + +如果在虚拟机上构建 Electron,你需要一个固定大小的设备,至少需要 25 gigabytes . + +## 获取代码 + +```bash +$ git clone https://github.com/atom/electron.git +``` + +## Bootstrapping + +bootstrap 脚本也是必要下载的构建依赖,来创建项目文件.需要使用 Python 2.7.x 来让脚本成功执行.正确下载文件会花费较长的时间. +注意我们使用的是 `ninja` 来构建 Electron,所以没有生成 `Makefile` 项目. + +```bash +$ cd electron +$ ./script/bootstrap.py -v +``` + +### 交叉编译 + +如果想创建一个 `arm` target ,应当还要下载下面的依赖 : + +```bash +$ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \ + g++-arm-linux-gnueabihf +``` + +为了编译 `arm` 或 `ia32` targets, 你应当为 `bootstrap.py` 脚本使用 +`--target_arch` 参数: + +```bash +$ ./script/bootstrap.py -v --target_arch=arm +``` + +## 构建 + +创建 `Release` 、 `Debug` target: + +```bash +$ ./script/build.py +``` + +这个脚本也许会在目录 `out/R` 下创建一个巨大的可执行的 Electron . 文件大小或许会超过 1.3 gigabytes. 原因是 Release target 二进制文件包含了 调试符号 .运行 `create-dist.py` 脚本来减小文件的 size : + +```bash +$ ./script/create-dist.py +``` +这会在 `dist` 目录下创建一个有大量小文件的工作空间. 运行 create-dist.py 脚本之后, 或许你想删除仍然在 `out/R` 下的 1.3+ gigabyte 二进制文件. + +可以只创建 `Debug` target: + +```bash +$ ./script/build.py -c D +``` + +创建完毕, 可以在 `out/D`下面找到 `electron`. + +## Cleaning + +删除构建文件 : + +```bash +$ ./script/clean.py +``` + +## 解决问题 + +确保你已经安装了所有的依赖 . + +### Error While Loading Shared Libraries: libtinfo.so.5 + +预构建的 `clang` 会尝试链接到 `libtinfo.so.5`. 取决于 host 架构, 适当的使用 `libncurses`: + +```bash +$ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5 +``` + +## Tests + +测试你的修改是否符合项目代码风格,使用: + +```bash +$ ./script/cpplint.py +``` + +测试有效性使用: + +```bash +$ ./script/test.py +``` \ No newline at end of file diff --git a/docs-translations/zh-CN/development/build-instructions-osx.md b/docs-translations/zh-CN/development/build-instructions-osx.md new file mode 100644 index 00000000000..18074a3085a --- /dev/null +++ b/docs-translations/zh-CN/development/build-instructions-osx.md @@ -0,0 +1,62 @@ +# Build Instructions (OS X) + +遵循下面的引导,在 OS X 上构建 Electron . + +## 前提 + +* OS X >= 10.8 +* [Xcode](https://developer.apple.com/technologies/tools/) >= 5.1 +* [node.js](http://nodejs.org) (外部) + +如果你通过 Homebrew 使用 Python 下载,需要安装下面的 Python 模块: + +* pyobjc + +## 获取代码 + +```bash +$ git clone https://github.com/atom/electron.git +``` + +## Bootstrapping + +bootstrap 脚本也是必要下载的构建依赖,来创建项目文件.注意我们使用的是 `ninja` 来构建 Electron,所以没有生成 Xcode 项目. + +```bash +$ cd electron +$ ./script/bootstrap.py -v +``` + +## 构建 + +创建 `Release` 、 `Debug` target: + +```bash +$ ./script/build.py +``` + +可以只创建 `Debug` target: + +```bash +$ ./script/build.py -c D +``` + +创建完毕, 可以在 `out/D` 下面找到 `Electron.app`. + +## 32位支持 + +在 OS X 上,构建 Electron 只支持 64位的,不支持 32位的 . + +## 测试 + +测试你的修改是否符合项目代码风格,使用: + +```bash +$ ./script/cpplint.py +``` + +测试有效性使用: + +```bash +$ ./script/test.py +``` \ No newline at end of file diff --git a/docs-translations/zh-CN/development/build-instructions-windows.md b/docs-translations/zh-CN/development/build-instructions-windows.md new file mode 100644 index 00000000000..7b11dc7f57f --- /dev/null +++ b/docs-translations/zh-CN/development/build-instructions-windows.md @@ -0,0 +1,136 @@ +# Build Instructions (Windows) + +遵循下面的引导,在 Windows 上构建 Electron . + +## 前提 + +* Windows 7 / Server 2008 R2 or higher +* Visual Studio 2013 with Update 4 - [download VS 2013 Community Edition for + free](https://www.visualstudio.com/news/vs2013-community-vs). +* [Python 2.7](http://www.python.org/download/releases/2.7/) +* [Node.js](http://nodejs.org/download/) +* [Git](http://git-scm.com) + +如果你现在还没有安装 Windows , [modern.ie](https://www.modern.ie/en-us/virtualization-tools#downloads) 有一个 timebombed 版本的 Windows ,你可以用它来构建 Electron. + +构建 Electron 完全的依赖于命令行,并且不可通过 Visual Studio. +可以使用任何的编辑器来开发 Electron ,未来会支持 Visual Studio. + +**注意:** 虽然 Visual Studio 不是用来构建的,但是它仍然 +**必须的** ,因为我们需要它提供的构建工具栏. + +**注意:** Visual Studio 2015 不可用. 请确定使用 MSVS +**2013**. + +## 获取代码 + +```powershell +$ git clone https://github.com/atom/electron.git +``` + +## Bootstrapping + +bootstrap 脚本也是必要下载的构建依赖,来创建项目文件.注意我们使用的是 `ninja` 来构建 Electron,所以没有生成 Visual Studio 项目. + +```powershell +$ cd electron +$ python script\bootstrap.py -v +``` + +## 构建 + +创建 `Release` 、 `Debug` target: + +```powershell +$ python script\build.py +``` + +可以只创建 `Debug` target: + +```powershell +$ python script\build.py -c D +``` + +创建完毕, 可以在 `out/D`(debug target) 或 `out\R` (release target) 下面找到 `electron.exe`. + +## 64bit Build + +为了构建64位的 target,在运行 bootstrap 脚本的时候需要使用 `--target_arch=x64` : + +```powershell +$ python script\bootstrap.py -v --target_arch=x64 +``` + +其他构建步骤完全相同. + +## Tests + +测试你的修改是否符合项目代码风格,使用: + +```powershell +$ python script\cpplint.py +``` + +测试有效性使用: + +```powershell +$ python script\test.py +``` +在构建 debug 时为 Tests包含原生模块 (例如 `runas`) 将不会执行(详情 [#2558](https://github.com/atom/electron/issues/2558)), 但是它们在构建 release 会起效. + +运行 release 构建使用 : + +```powershell +$ python script\test.py -R +``` + +## 解决问题 + +### Command xxxx not found + +如果你遇到了一个错误,类似 `Command xxxx not found`, 可以尝试使用 `VS2012 Command Prompt` 控制台来执行构建脚本 . + +### Fatal internal compiler error: C1001 + +确保你已经安装了 Visual Studio 的最新安装包 . + +### Assertion failed: ((handle))->activecnt >= 0 + +如果在 Cygwin 下构建的,你可能会看到 `bootstrap.py` 失败并且附带下面错误 : + +``` +Assertion failed: ((handle))->activecnt >= 0, file src\win\pipe.c, line 1430 + +Traceback (most recent call last): + File "script/bootstrap.py", line 87, in + sys.exit(main()) + File "script/bootstrap.py", line 22, in main + update_node_modules('.') + File "script/bootstrap.py", line 56, in update_node_modules + execute([NPM, 'install']) + File "/home/zcbenz/codes/raven/script/lib/util.py", line 118, in execute + raise e +subprocess.CalledProcessError: Command '['npm.cmd', 'install']' returned non-zero exit status 3 +``` + +这是由同时使用 Cygwin Python 和 Win32 Node 造成的 bug.解决办法就是使用 Win32 Python 执行 bootstrap 脚本 (假定你已经在目录 `C:\Python27` 下安装了 Python): + +```powershell +$ /cygdrive/c/Python27/python.exe script/bootstrap.py +``` + +### LNK1181: cannot open input file 'kernel32.lib' + +重新安装 32位的 Node.js. + +### Error: ENOENT, stat 'C:\Users\USERNAME\AppData\Roaming\npm' + +简单创建目录 [应该可以解决问题](http://stackoverflow.com/a/25095327/102704): + +```powershell +$ mkdir ~\AppData\Roaming\npm +``` + +### node-gyp is not recognized as an internal or external command + +如果你使用 Git Bash 来构建,或许会遇到这个错误,可以使用 PowerShell 或 VS2012 Command Prompt 来代替 . \ No newline at end of file diff --git a/docs-translations/zh-CN/development/build-system-overview.md b/docs-translations/zh-CN/development/build-system-overview.md index 20b0ff185fe..95aea7fb1f5 100644 --- a/docs-translations/zh-CN/development/build-system-overview.md +++ b/docs-translations/zh-CN/development/build-system-overview.md @@ -1,14 +1,14 @@ # Build System Overview -Electron 使用 `gyp` 来生成项目 ,使用 `ninja` 来编译项目. 项目配置可以在 `.gyp` 和 `.gypi` 文件中找到. +Electron 使用 `gyp` 来生成项目 ,使用 `ninja` 来构建项目. 项目配置可以在 `.gyp` 和 `.gypi` 文件中找到. ## Gyp 文件 -下面的 `gyp` 文件包含了编译 Electron 的主要规则 : +下面的 `gyp` 文件包含了构建 Electron 的主要规则 : -* `atom.gyp` 定义了 Electron 它自己是怎样被编译的. -* `common.gypi` 调整 node 的编译配置,来让它结合 Chromium 一起编译. -* `vendor/brightray/brightray.gyp` 定义了 `brightray` 是如何被编译的,并且包含了默认配置来连接到 Chromium. +* `atom.gyp` 定义了 Electron 它自己是怎样被构建的. +* `common.gypi` 调整 node 的构建配置,来让它结合 Chromium 一起构建. +* `vendor/brightray/brightray.gyp` 定义了 `brightray` 是如何被构建的,并且包含了默认配置来连接到 Chromium. * `vendor/brightray/brightray.gypi` 包含了常用的创建配置. ## 创建组件 @@ -31,12 +31,12 @@ $ ./script/build.py -c D ## Two-Phase Project Generation -在 `Release` 和 `Debug` 编译的时候后,Electron 链接了不同配置的库 .然而 `gyp`不支持为不同的配置文件进行不同的链接设置. +在 `Release` 和 `Debug` 构建的时候后,Electron 链接了不同配置的库 .然而 `gyp`不支持为不同的配置文件进行不同的链接设置. 为了规避这个问题,Electron 在运行 `gyp` 的时候,使用了一个 `gyp` 的变量 `libchromiumcontent_component`来控制应该使用哪个链接设置,并且只生成一个目标. ## Target Names -与大多数的项目不同,它们使用 `Release` 和 `Debug` 作为目标名字,而 Electron 使用使用的是 `R` 和 `D`.这是因为如果只定义了一个 `Release` 或 `Debug` 编译配置,`gyp` 会随机崩溃,并且在同一时候,Electron 只生成一个目标,如上所述. +与大多数的项目不同,它们使用 `Release` 和 `Debug` 作为目标名字,而 Electron 使用使用的是 `R` 和 `D`.这是因为如果只定义了一个 `Release` 或 `Debug` 构建配置,`gyp` 会随机崩溃,并且在同一时候,Electron 只生成一个目标,如上所述. -这只对开发者可用,如果想重新编译 Electron ,将不会成功. \ No newline at end of file +这只对开发者可用,如果想重新构建 Electron ,将不会成功. \ No newline at end of file From 7bcb99f8230866325d2980ed91d81e8b9b766b7e Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Wed, 16 Mar 2016 15:41:12 +0800 Subject: [PATCH 509/688] add last three files first --- .../development/setting-up-symbol-server.md | 38 +++++ .../mac-app-store-submission-guide.md | 147 ++++++++++++++++++ .../tutorial/using-widevine-cdm-plugin.md | 67 ++++++++ 3 files changed, 252 insertions(+) create mode 100644 docs-translations/zh-CN/development/setting-up-symbol-server.md create mode 100644 docs-translations/zh-CN/tutorial/mac-app-store-submission-guide.md create mode 100644 docs-translations/zh-CN/tutorial/using-widevine-cdm-plugin.md diff --git a/docs-translations/zh-CN/development/setting-up-symbol-server.md b/docs-translations/zh-CN/development/setting-up-symbol-server.md new file mode 100644 index 00000000000..01098bcc77c --- /dev/null +++ b/docs-translations/zh-CN/development/setting-up-symbol-server.md @@ -0,0 +1,38 @@ +# Setting Up Symbol Server in Debugger + +调试 symbols 让你有更好的调试 sessions. 它们有可执行的动态库的函数信息,并且提供信息来获得洁净的呼叫栈. 一个 Symbol 服务器允许调试器自动加载正确的 symbols, 二进制文件 和 资源文件,不用再去强制用户下载巨大的调试文件. 服务器函数类似 +[Microsoft's symbol server](http://support.microsoft.com/kb/311503) ,所以这里的记录可用. + +注意,因为公众版本的 Electron 构建是最优化的,调试不一定一直简单.调试器将不会给显示出所有变量内容,并且因为内联,尾调用,和其它编译器优化,执行路径会看起来很怪异 . 唯一的解决办法是搭建一个不优化的本地构建. + +Electron 使用的官方 symbol 服务器地址为 +`http://54.249.141.255:8086/atom-shell/symbols` . +你不能直接访问这个路径,必须将其添加到你的调试工具的 symbol 路径上.在下面的例子中,使用了一个本地缓存目录来避免重复从服务器获取 PDB. 在你的电脑上使用一个恰当的缓存目录来代替 `c:\code\symbols` . + +## Using the Symbol Server in Windbg + +Windbg symbol 路径被配制为一个限制带星号字符的字符串. 要只使用 Electron 的 symbol 服务器, 将下列记录添加到你的 symbol 路径 (__注意:__ 如果你愿意使用一个不同的地点来下载 symbols,你可以在你的电脑中使用任何可写的目录来代替 `c:\code\symbols`): + +``` +SRV*c:\code\symbols\*http://54.249.141.255:8086/atom-shell/symbols +``` + +使用 Windbg 菜单或通过输入 `.sympath` 命令,在环境中设置一个 `_NT_SYMBOL_PATH` 字符串.如果你也想从微软的 symbol 服务器获得 symbols ,你应当首先将它们先列出来 : + +``` +SRV*c:\code\symbols\*http://msdl.microsoft.com/download/symbols;SRV*c:\code\symbols\*http://54.249.141.255:8086/atom-shell/symbols +``` + +## 在 Visual Studio 中使用 symbol 服务器 + + + + +## Troubleshooting: Symbols will not load + +在 Windbg 中输入下列命令,打印出未什么 symbols 没有加载 : + +``` +> !sym noisy +> .reload /f chromiumcontent.dll +``` \ No newline at end of file diff --git a/docs-translations/zh-CN/tutorial/mac-app-store-submission-guide.md b/docs-translations/zh-CN/tutorial/mac-app-store-submission-guide.md new file mode 100644 index 00000000000..45cff454a96 --- /dev/null +++ b/docs-translations/zh-CN/tutorial/mac-app-store-submission-guide.md @@ -0,0 +1,147 @@ +# Mac App Store 应用提交向导 + +自从 v0.34.0, Electron 就允许提交应用包到 Mac App Store +(MAS) . 这个向导提供的信息有 : 如何提交应用和 MAS 构建的限制. + +__注意:__ 从 v0.36.0,当应用成为沙箱之后,会有一个 bug 阻止 GPU 进程开启 , 所以在这个 bug 修复之前,建议使用 v0.35.x .更多查看 [issue #3871][issue-3871] . + +__注意:__ 提交应用到 Mac App Store 需要参加 [Apple Developer +Program][developer-program] , 这需要花钱. + +## 如何提交 + +下面步骤介绍了一个简单的提交应用到商店方法.然而,这些步骤不能保证你的应用被 Apple 接受;你仍然需要阅读 Apple 的 [Submitting Your App][submitting-your-app] 关于如何满足 Mac App Store 要求的向导. + +### 获得证书 + +为了提交应用到商店,首先需要从 Apple 获得一个证书.可以遵循 [existing guides][nwjs-guide]. + +### App 签名 + +获得证书之后,你可以使用 [Application Distribution](application-distribution.md) 打包你的应用, 然后前往提交你的应用.这个步骤基本上和其他程序一样,但是这 key 一个个的标识 Electron 的每个依赖. + +首先,你需要准备2个授权文件 . + +`child.plist`: + +```xml + + + + + com.apple.security.app-sandbox + + com.apple.security.inherit + + + +``` + +`parent.plist`: + +```xml + + + + + com.apple.security.app-sandbox + + + +``` + +然后使用下面的脚本标识你的应用 : + +```bash +#!/bin/bash + +# Name of your app. +APP="YourApp" +# The path of you app to sign. +APP_PATH="/path/to/YouApp.app" +# The path to the location you want to put the signed package. +RESULT_PATH="~/Desktop/$APP.pkg" +# The name of certificates you requested. +APP_KEY="3rd Party Mac Developer Application: Company Name (APPIDENTITY)" +INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)" + +FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" + +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper.app/" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper EH.app/" +codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper NP.app/" +if [ -d "$FRAMEWORKS_PATH/Squirrel.framework/Versions/A" ]; then + # Signing a non-MAS build. + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Mantle.framework/Versions/A" + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/ReactiveCocoa.framework/Versions/A" + codesign --deep -fs "$APP_KEY" --entitlements child.plist "$FRAMEWORKS_PATH/Squirrel.framework/Versions/A" +fi +codesign -fs "$APP_KEY" --entitlements parent.plist "$APP_PATH" + +productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" +``` +如果你是 OS X 下的应用沙箱使用新手,应当仔细阅读 Apple 的 [Enabling App Sandbox][enable-app-sandbox] 来有一点基础,然后向授权文件添加你的应用需要的许可 keys . + +### 上传你的应用并检查提交 + +在签名应用之后,可以使用应用 Loader 来上传到 iTunes 链接处理 , 确保在上传之前你已经 [created a record][create-record]. 然后你能 [submit your app for review][submit-for-review]. + +## MAS构建限制 + +为了让你的应用沙箱满足所有条件,在 MAS 构建的时候,下面的模块被禁用了 : + +* `crashReporter` +* `autoUpdater` + +并且下面的行为也改变了: + +* 一些机子的视频采集功能无效. +* 某些特征不可访问. +* Apps 不可识别 DNS 改变. + +也由于应用沙箱的使用方法,应用可以访问的资源被严格限制了 ; 阅读更多信息 [App Sandboxing][app-sandboxing] . + +## Electron 使用的加密算法 + +取决于你所在地方的国家和地区 , Mac App Store 或许需要记录你应用的加密算法 , 甚至要求你提交一个 U.S 加密注册(ERN) 许可的复印件. + +Electron 使用下列加密算法: + +* AES - [NIST SP 800-38A](http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf), [NIST SP 800-38D](http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf), [RFC 3394](http://www.ietf.org/rfc/rfc3394.txt) +* HMAC - [FIPS 198-1](http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf) +* ECDSA - ANS X9.62–2005 +* ECDH - ANS X9.63–2001 +* HKDF - [NIST SP 800-56C](http://csrc.nist.gov/publications/nistpubs/800-56C/SP-800-56C.pdf) +* PBKDF2 - [RFC 2898](https://tools.ietf.org/html/rfc2898) +* RSA - [RFC 3447](http://www.ietf.org/rfc/rfc3447) +* SHA - [FIPS 180-4](http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf) +* Blowfish - https://www.schneier.com/cryptography/blowfish/ +* CAST - [RFC 2144](https://tools.ietf.org/html/rfc2144), [RFC 2612](https://tools.ietf.org/html/rfc2612) +* DES - [FIPS 46-3](http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf) +* DH - [RFC 2631](https://tools.ietf.org/html/rfc2631) +* DSA - [ANSI X9.30](http://webstore.ansi.org/RecordDetail.aspx?sku=ANSI+X9.30-1%3A1997) +* EC - [SEC 1](http://www.secg.org/sec1-v2.pdf) +* IDEA - "On the Design and Security of Block Ciphers" book by X. Lai +* MD2 - [RFC 1319](http://tools.ietf.org/html/rfc1319) +* MD4 - [RFC 6150](https://tools.ietf.org/html/rfc6150) +* MD5 - [RFC 1321](https://tools.ietf.org/html/rfc1321) +* MDC2 - [ISO/IEC 10118-2](https://www.openssl.org/docs/manmaster/crypto/mdc2.html) +* RC2 - [RFC 2268](https://tools.ietf.org/html/rfc2268) +* RC4 - [RFC 4345](https://tools.ietf.org/html/rfc4345) +* RC5 - http://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf +* RIPEMD - [ISO/IEC 10118-3](http://webstore.ansi.org/RecordDetail.aspx?sku=ISO%2FIEC%2010118-3:2004) + +如何获取 ERN 许可, 可看这篇文章: [How to legally +submit an app to Apple’s App Store when it uses encryption (or how to obtain an +ERN)][ern-tutorial]. + +[developer-program]: https://developer.apple.com/support/compare-memberships/ +[submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html +[nwjs-guide]: https://github.com/nwjs/nw.js/wiki/Mac-App-Store-%28MAS%29-Submission-Guideline#first-steps +[enable-app-sandbox]: https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html +[create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html +[submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html +[app-sandboxing]: https://developer.apple.com/app-sandboxing/ +[issue-3871]: https://github.com/atom/electron/issues/3871 +[ern-tutorial]: https://carouselapps.com/2015/12/15/legally-submit-app-apples-app-store-uses-encryption-obtain-ern/ \ No newline at end of file diff --git a/docs-translations/zh-CN/tutorial/using-widevine-cdm-plugin.md b/docs-translations/zh-CN/tutorial/using-widevine-cdm-plugin.md new file mode 100644 index 00000000000..d5df1646c48 --- /dev/null +++ b/docs-translations/zh-CN/tutorial/using-widevine-cdm-plugin.md @@ -0,0 +1,67 @@ +# 使用 Widevine CDM 插件 + +在 Electron ,你可以使用 Widevine CDM 插件装载 Chrome 浏览器 . + +## 获取插件 + +Electron 没有为 Widevine CDM 插件 配制许可 reasons, 为了获得它,首先需要安装官方的 chrome 浏览器,这匹配了体系架构和 Electron 构建使用的 chrome 版本 . + +__注意:__ Chrome 浏览器的主要版本必须和 Electron 使用的版本一样,否则插件不会有效,虽然 `navigator.plugins` 会显示你已经安装了它 . + +### Windows & OS X + +在 Chrome 浏览器中打开 `chrome://components/` ,找到 `WidevineCdm` 并且确定它更新到最新版本,然后你可以从 `APP_DATA/Google/Chrome/WidevineCDM/VERSION/_platform_specific/PLATFORM_ARCH/` 路径找到所有的插件二进制文件 . + +`APP_DATA` 是系统存放数据的地方,在 Windows 上它是 +`%LOCALAPPDATA%`, 在 OS X 上它是 `~/Library/Application Support`. `VERSION` 是 +Widevine CDM 插件的版本字符串, 类似 `1.4.8.866`. `PLATFORM` 是 `mac` 或 +`win`. `ARCH` 是 `x86` 或 `x64`. + +在 Windows,必要的二进制文件是 `widevinecdm.dll` and +`widevinecdmadapter.dll`, 在 OS X ,它们是 `libwidevinecdm.dylib` 和 +`widevinecdmadapter.plugin`. 你可以将它们复制到任何你喜欢的地方,但是它们必须要放在一起. + +### Linux + +在 Linux ,Chrome 浏览器将插件的二进制文件装载在一起 , 你可以在 `/opt/google/chrome` 下找到,文件名是 `libwidevinecdm.so` 和 +`libwidevinecdmadapter.so`. + +## 使用插件 + +在获得了插件文件后,你可以使用 `--widevine-cdm-path` 命令行开关来将 `widevinecdmadapter` 的路径传递给 Electron , 插件版本使用 `--widevine-cdm-version` 开关. + +__注意:__ 虽然只有 `widevinecdmadapter` 的二进制文件传递给了 Electron, `widevinecdm` 二进制文件应当放在它的旁边. + +必须在 `app` 模块的 `ready` 事件触发之前使用命令行开关,并且 page 使用的插件必须激活. + +示例代码 : + +```javascript +// You have to pass the filename of `widevinecdmadapter` here, it is +// * `widevinecdmadapter.plugin` on OS X, +// * `libwidevinecdmadapter.so` on Linux, +// * `widevinecdmadapter.dll` on Windows. +app.commandLine.appendSwitch('widevine-cdm-path', '/path/to/widevinecdmadapter.plugin'); +// The version of plugin can be got from `chrome://plugins` page in Chrome. +app.commandLine.appendSwitch('widevine-cdm-version', '1.4.8.866'); + +var mainWindow = null; +app.on('ready', function() { + mainWindow = new BrowserWindow({ + webPreferences: { + // The `plugins` have to be enabled. + plugins: true + } + }) +}); +``` + +## 验证插件 + +为了验证插件是否工作,你可以使用下面的方法 : + +* 打开开发者工具查看是否 `navigator.plugins` 包含了 Widevine +CDM 插件. +* 打开 `https://shaka-player-demo.appspot.com/` 加载一个使用 +`Widevine` 的 manifest. +* 打开 http://www.dash-player.com/demo/drm-test-area/, 检查是否界面输出 `bitdash uses Widevine in your browser`, 然后播放 video. \ No newline at end of file From 25931d16ab424e61e9a678ce040b1753670ddf3c Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Wed, 16 Mar 2016 15:56:52 +0800 Subject: [PATCH 510/688] modify 2days ago update 2files --- docs-translations/zh-CN/api/web-contents.md | 1 + docs-translations/zh-CN/api/web-view-tag.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs-translations/zh-CN/api/web-contents.md b/docs-translations/zh-CN/api/web-contents.md index 1b7011bb0fa..f168849863a 100644 --- a/docs-translations/zh-CN/api/web-contents.md +++ b/docs-translations/zh-CN/api/web-contents.md @@ -242,6 +242,7 @@ var webContents = win.webContents; * `result` Object * `requestId` Integer * `finalUpdate` Boolean - 标识是否还有更多的值可以查看. + * `activeMatchOrdinal` Integer (可选) - 活动匹配位置 * `matches` Integer (可选) - 匹配数量. * `selectionArea` Object (可选) - 协调首个匹配位置. diff --git a/docs-translations/zh-CN/api/web-view-tag.md b/docs-translations/zh-CN/api/web-view-tag.md index f1f3ef9080c..e1e31f6f5a0 100644 --- a/docs-translations/zh-CN/api/web-view-tag.md +++ b/docs-translations/zh-CN/api/web-view-tag.md @@ -528,6 +528,7 @@ webview.addEventListener('console-message', function(e) { * `result` Object * `requestId` Integer * `finalUpdate` Boolean - 指明下面是否还有更多的回应. + * `activeMatchOrdinal` Integer (可选) - 活动匹配位置 * `matches` Integer (optional) - 匹配数量. * `selectionArea` Object (optional) - 整合第一个匹配域. From 0d8994d81daa908e598fb8baf6d6cf3a558fceb0 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 16 Mar 2016 09:37:04 -0700 Subject: [PATCH 511/688] improve wording in the FAQ --- docs/faq/electron-faq.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index a58d31107b6..ef08de5237f 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -5,7 +5,7 @@ The Chrome version of Electron is usually bumped within one or two weeks after a new stable Chrome version gets released. -Also we only use stable channel of Chrome, if an important fix is in beta or dev +Also we only use stable channel of Chrome. If an important fix is in beta or dev channel, we will back-port it. ## When will Electron upgrade to latest Node.js? @@ -25,7 +25,7 @@ use HTML5 APIs which are already available in browsers. Good candidates are [Storage API][storage], [`localStorage`][local-storage], [`sessionStorage`][session-storage], and [IndexedDB][indexed-db]. -Or you can use the IPC system, which are specific to Electron, to store objects +Or you can use the IPC system, which is specific to Electron, to store objects in the main process as a global variable, and then to access them from the renderers through the `remote` module: @@ -51,8 +51,7 @@ console.log(require('remote').getGlobal('sharedObject').someProperty); This happens when the variable which is used to store the window/tray gets garbage collected. -It is recommended to have a reading of following articles you encountered this -problem: +If you encounter this problem, the following articles may prove helpful: * [Memory Management][memory-management] * [Variable Scope][variable-scope] @@ -78,8 +77,8 @@ app.on('ready', function() { ## I can not use jQuery/RequireJS/Meteor/AngularJS in Electron. Due to the Node.js integration of Electron, there are some extra symbols -inserted into DOM, like `module`, `exports`, `require`. This causes troubles for -some libraries since they want to insert the symbols with same names. +inserted into the DOM like `module`, `exports`, `require`. This causes troubles for +some libraries since they want to insert the symbols with the same names. To solve this, you can turn off node integration in Electron: @@ -141,7 +140,7 @@ npm uninstall -g electron ``` However if your are using the built-in module but still getting this error, it -is very likely you are using the module in wrong process. For example +is very likely you are using the module in the wrong process. For example `electron.app` can only be used in the main process, while `electron.webFrame` is only available in renderer processes. From da47b569e8e31a2e19bc7723818a92f8fec23908 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 16 Mar 2016 09:42:33 -0700 Subject: [PATCH 512/688] link to the ninja website --- docs/development/build-instructions-osx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/build-instructions-osx.md b/docs/development/build-instructions-osx.md index ac51bf0dc22..598aa01c440 100644 --- a/docs/development/build-instructions-osx.md +++ b/docs/development/build-instructions-osx.md @@ -22,7 +22,7 @@ $ git clone https://github.com/atom/electron.git ## Bootstrapping The bootstrap script will download all necessary build dependencies and create -the build project files. Notice that we're using `ninja` to build Electron so +the build project files. Notice that we're using [ninja](https://ninja-build.org/) to build Electron so there is no Xcode project generated. ```bash From 6503f32ef9b89fde1798a8ac94bf318c0606e1ed Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 16 Mar 2016 09:47:12 -0700 Subject: [PATCH 513/688] add another link to ninja --- docs/development/build-system-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/build-system-overview.md b/docs/development/build-system-overview.md index 04067ce8c79..41c65e450a4 100644 --- a/docs/development/build-system-overview.md +++ b/docs/development/build-system-overview.md @@ -1,6 +1,6 @@ # Build System Overview -Electron uses `gyp` for project generation and `ninja` for building. Project +Electron uses `gyp` for project generation and [ninja](https://ninja-build.org/) for building. Project configurations can be found in the `.gyp` and `.gypi` files. ## Gyp Files From fa197ad5832b43044f6731c83e278d4bea3b83cd Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 16 Mar 2016 12:40:28 -0700 Subject: [PATCH 514/688] Fix failing test --- spec/api-native-image-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index e411fb11002..fd13ad76db3 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -45,7 +45,7 @@ describe('nativeImage module', () => { assert.equal(nsimage.length, 8); // If all bytes are null, that's Bad - assert.equal(nsimage.reduce((acc,x) => acc || (x != 0)), true); + assert.equal(!!nsimage.reduce((acc,x) => acc || (x != 0)), true); }); }); }); From 148014f99a8a764b795233299cf0e6f4478c15ac Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 16 Mar 2016 12:42:23 -0700 Subject: [PATCH 515/688] Fix spec failure --- spec/api-native-image-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index fd13ad76db3..a7ee8be007e 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -45,7 +45,7 @@ describe('nativeImage module', () => { assert.equal(nsimage.length, 8); // If all bytes are null, that's Bad - assert.equal(!!nsimage.reduce((acc,x) => acc || (x != 0)), true); + assert.equal(nsimage.reduce((acc,x) => acc || (x != 0), false), true); }); }); }); From e94da877c2b3a205d196ee5dc5781e5b9524cc26 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 16 Mar 2016 12:49:34 -0700 Subject: [PATCH 516/688] Fix compile oopses on non-OS X --- atom/common/api/atom_api_native_image.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index d616b428330..81db35715bc 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -226,10 +226,11 @@ std::string NativeImage::ToDataURL() { v8::Local NativeImage::GetNativeHandle( v8::Isolate* isolate, mate::Arguments* args) { +void* ptr = NULL; #if defined(OS_MACOSX) - void* ptr = reinterpret_cast(image_.AsNSImage()); + ptr = reinterpret_cast(image_.AsNSImage()); #else - args.ThrowError(); + args->ThrowError(); return v8::Undefined(isolate); #endif From 5acfa8611af9fe2878d774ae2cf91d5931cc820b Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 16 Mar 2016 13:15:34 -0700 Subject: [PATCH 517/688] link to gyp --- docs/development/build-system-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/build-system-overview.md b/docs/development/build-system-overview.md index 41c65e450a4..61b88e14078 100644 --- a/docs/development/build-system-overview.md +++ b/docs/development/build-system-overview.md @@ -1,6 +1,6 @@ # Build System Overview -Electron uses `gyp` for project generation and [ninja](https://ninja-build.org/) for building. Project +Electron uses [gyp](https://gyp.gsrc.io/) for project generation and [ninja](https://ninja-build.org/) for building. Project configurations can be found in the `.gyp` and `.gypi` files. ## Gyp Files From 01980dea11bf66b0275eccf974f5d638438ee438 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Thu, 17 Mar 2016 00:03:24 -0700 Subject: [PATCH 518/688] s/troubles/problems/ --- docs/faq/electron-faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index ef08de5237f..41b301d7198 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -77,7 +77,7 @@ app.on('ready', function() { ## I can not use jQuery/RequireJS/Meteor/AngularJS in Electron. Due to the Node.js integration of Electron, there are some extra symbols -inserted into the DOM like `module`, `exports`, `require`. This causes troubles for +inserted into the DOM like `module`, `exports`, `require`. This causes problems for some libraries since they want to insert the symbols with the same names. To solve this, you can turn off node integration in Electron: From 75ec7a057a67a15816c75299cd5336a5d5553a86 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Mar 2016 21:45:13 +0900 Subject: [PATCH 519/688] Update brightray for #4681 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index c7abfaafc70..242feb1c817 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit c7abfaafc70bdc22604574a8ed2b8c8a7c0e27d3 +Subproject commit 242feb1c817565de6592e9e672c136635bfff453 From f8b9a66ead386034e6cc60e83d4a024f2a749c1e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Mar 2016 21:55:02 +0900 Subject: [PATCH 520/688] docs: Make it clear image.getNativeHandle is OS X only --- docs/api/native-image.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/api/native-image.md b/docs/api/native-image.md index c33f35c6fe5..e0c3ae46624 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -133,11 +133,14 @@ Returns a [Buffer][buffer] that contains the image's `JPEG` encoded data. Returns the data URL of the image. -### `image.getNativeHandle()` +### `image.getNativeHandle()` _OS X_ -Returns a pointer to an underlying native type (encoded as a [Buffer][buffer]) which can be used with native APIs. Note that in many cases, this pointer is a weak pointer to the underlying native image not a copy, so you _must_ ensure that the associated `nativeImage` instance is kept around. +Returns a [Buffer][buffer] that stores C pointer to underlying native handle of +the image. On OS X, a pointer to `NSImage` instance would be returned. -Returns a [Buffer][buffer] that represents a pointer to a native type - on OS X, this type is an NSImage object. +Notice that the returned pointer is a weak pointer to the underlying native +image instead of a copy, so you _must_ ensure that the associated +`nativeImage` instance is kept around. ### `image.isEmpty()` From 939d69df6e0a97ad67838f4f01888fb0f86e15de Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Mar 2016 22:01:31 +0900 Subject: [PATCH 521/688] Throw error with message of "Not implemented". --- atom/common/api/atom_api_native_image.cc | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 81db35715bc..3dda326f59f 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -184,8 +184,7 @@ mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder( template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate) .SetMethod("toPng", &NativeImage::ToPNG) .SetMethod("toJpeg", &NativeImage::ToJPEG) - .SetMethod("getNativeHandle", - &NativeImage::GetNativeHandle) + .SetMethod("getNativeHandle", &NativeImage::GetNativeHandle) .SetMethod("toDataURL", &NativeImage::ToDataURL) .SetMethod("toDataUrl", &NativeImage::ToDataURL) // deprecated. .SetMethod("isEmpty", &NativeImage::IsEmpty) @@ -223,21 +222,18 @@ std::string NativeImage::ToDataURL() { return data_url; } -v8::Local NativeImage::GetNativeHandle( - v8::Isolate* isolate, - mate::Arguments* args) { -void* ptr = NULL; +v8::Local NativeImage::GetNativeHandle(v8::Isolate* isolate, + mate::Arguments* args) { #if defined(OS_MACOSX) - ptr = reinterpret_cast(image_.AsNSImage()); + NSImage* ptr = image_.AsNSImage(); + return node::Buffer::Copy( + isolate, + reinterpret_cast(ptr), + sizeof(void*)).ToLocalChecked(); #else - args->ThrowError(); + args->ThrowError("Not implemented"); return v8::Undefined(isolate); #endif - - return node::Buffer::Copy( - isolate, - reinterpret_cast(ptr), - sizeof(void*)).ToLocalChecked(); } bool NativeImage::IsEmpty() { From cbd37ad3b9f3f565f5e5029df4125486bacbd521 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 17 Mar 2016 22:29:32 +0900 Subject: [PATCH 522/688] docs: List breakpad server implementations --- docs/api/crash-reporter.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index 5a7ff720bfd..64e5602474a 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -16,6 +16,12 @@ crashReporter.start({ }); ``` +For setting up a server to accept and process crash reports, you can use +following projects: + +* [socorro](https://github.com/mozilla/socorro) +* [mini-breakpad-server](https://github.com/atom/mini-breakpad-server) + ## Methods The `crash-reporter` module has the following methods: @@ -66,6 +72,6 @@ The crash reporter will send the following data to the `submitURL` as a `multipa * `prod` String - Name of the underlying product. In this case Electron. * `_companyName` String - The company name in the `crashReporter` `options` object. -* `upload_file_minidump` File - The crash report as file, a binary. +* `upload_file_minidump` File - The crash report in the format of `minidump`. * All level one properties of the `extra` object in the `crashReporter`. `options` object From 5c9b19b508045df6070f53422b154490be2796d7 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 16 Mar 2016 09:24:57 -0700 Subject: [PATCH 523/688] web-preferences -> webPreferences --- spec/static/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/static/main.js b/spec/static/main.js index 9a049e3f107..77a3c392722 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -82,8 +82,8 @@ app.on('ready', function() { show: false, width: 800, height: 600, - 'web-preferences': { - javascript: true // Test whether web-preferences crashes. + webPreferences: { + javascript: true // Test whether web preferences crashes. }, }); window.loadURL(url.format({ From 1e8e8f18b42f4a442e5932d20c2c8b3dd295e823 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 16 Mar 2016 09:31:32 -0700 Subject: [PATCH 524/688] Add failing specs for deprecated options usage --- spec/api-browser-window-spec.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index c6deb38684c..e0b3c75437e 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -759,4 +759,25 @@ describe('browser-window module', function() { }); }); }); + + describe('deprecated options', function() { + it('throws a deprecation error for option keys using hyphens instead of camel case', function() { + assert.throws(function () { + new BrowserWindow({'min-width': 500}) + }, 'min-width is deprecated. Use minWidth instead.'); + }); + + it('throws a deprecation error for webPreference keys using hyphens instead of camel case', function() { + assert.throws(function () { + new BrowserWindow({webPreferences: {'node-integration': false}}) + }, 'node-integration is deprecated. Use nodeIntegration instead.'); + }); + + it('throws a deprecation error for option keys that should be set on webPreferences', function() { + assert.throws(function () { + new BrowserWindow({zoomFactor: 1}) + }, 'Setting zoomFactor on options is deprecated. Set it on options.webPreferences instead.'); + }); + }) + }); From dfd13cf4ca797afc0027368640a2a65123df9e1d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 16 Mar 2016 09:33:19 -0700 Subject: [PATCH 525/688] persistented -> persisted --- lib/browser/chrome-extension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index fcbb8c7f15f..054a0cd6c67 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -132,7 +132,7 @@ app.once('ready', function() { return delete extensionInfoMap[name]; }; - // Load persistented extensions when devtools is opened. + // Load persisted extensions when devtools is opened. init = BrowserWindow.prototype._init; return BrowserWindow.prototype._init = function() { init.call(this); From 1b6e01ce6de14f4df6e57d81ceb99b9714bd6159 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 16 Mar 2016 09:35:18 -0700 Subject: [PATCH 526/688] Add missing semicolons --- spec/api-browser-window-spec.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index e0b3c75437e..00bc2fb9f18 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -763,21 +763,20 @@ describe('browser-window module', function() { describe('deprecated options', function() { it('throws a deprecation error for option keys using hyphens instead of camel case', function() { assert.throws(function () { - new BrowserWindow({'min-width': 500}) + new BrowserWindow({'min-width': 500}); }, 'min-width is deprecated. Use minWidth instead.'); }); it('throws a deprecation error for webPreference keys using hyphens instead of camel case', function() { assert.throws(function () { - new BrowserWindow({webPreferences: {'node-integration': false}}) + new BrowserWindow({webPreferences: {'node-integration': false}}); }, 'node-integration is deprecated. Use nodeIntegration instead.'); }); it('throws a deprecation error for option keys that should be set on webPreferences', function() { assert.throws(function () { - new BrowserWindow({zoomFactor: 1}) + new BrowserWindow({zoomFactor: 1}); }, 'Setting zoomFactor on options is deprecated. Set it on options.webPreferences instead.'); }); - }) - + }); }); From 15397bf879b26e56df4d28453a30f04ea915b984 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 16 Mar 2016 09:38:03 -0700 Subject: [PATCH 527/688] Report deprecated BrowserWindow options --- atom/browser/api/atom_api_window.cc | 19 +++++++++++ lib/browser/api/browser-window.js | 53 ++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 6c0f0f6f762..87f6411e665 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -52,6 +52,11 @@ namespace api { namespace { +// The DeprecatedOptionsCheckCallback funtion which is implemented in JavaScript +using DeprecatedOptionsCheckCallback = + base::Callback)>; +DeprecatedOptionsCheckCallback g_deprecated_options_check; + void OnCapturePageDone( v8::Isolate* isolate, const base::Callback& callback, @@ -291,6 +296,13 @@ mate::Wrappable* Window::New(v8::Isolate* isolate, mate::Arguments* args) { options = mate::Dictionary::CreateEmpty(isolate); } + std::string deprecation_message = g_deprecated_options_check.Run( + options.GetHandle()); + if (deprecation_message.length() > 0) { + args->ThrowError(deprecation_message); + return nullptr; + } + return new Window(isolate, options); } @@ -797,6 +809,10 @@ v8::Local Window::From(v8::Isolate* isolate, return v8::Null(isolate); } +void SetDeprecatedOptionsCheck(const DeprecatedOptionsCheckCallback& callback) { + g_deprecated_options_check = callback; +} + } // namespace api } // namespace atom @@ -816,6 +832,9 @@ void Initialize(v8::Local exports, v8::Local unused, &mate::TrackableObject::FromWeakMapID); browser_window.SetMethod("getAllWindows", &mate::TrackableObject::GetAll); + browser_window.SetMethod("_setDeprecatedOptionsCheck", + &atom::api::SetDeprecatedOptionsCheck); + mate::Dictionary dict(isolate, exports); dict.Set("BrowserWindow", browser_window); diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 7e2a8d38c31..9645f855eed 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -8,7 +8,6 @@ const BrowserWindow = process.atomBinding('window').BrowserWindow; BrowserWindow.prototype.__proto__ = EventEmitter.prototype; BrowserWindow.prototype._init = function() { - // avoid recursive require. var app, menu; app = require('electron').app; @@ -240,4 +239,56 @@ BrowserWindow.prototype.getPageTitle = deprecate('getPageTitle', 'webContents.ge return (ref1 = this.webContents) != null ? ref1.getTitle() : void 0; }); +const isDeprecatedKey = function(key) { + return key.indexOf('-') >= 0; +}; + +// Map deprecated key with hyphens to camel case key +const getNonDeprecatedKey = function(deprecatedKey) { + return deprecatedKey.replace(/-./g, function(match) { + return match[1].toUpperCase(); + }); +}; + +// TODO Remove for 1.0 +const checkForDeprecatedOptions = function(options) { + if (!options) return ''; + + let keysToCheck = Object.keys(options); + if (options.webPreferences) { + keysToCheck = keysToCheck.concat(Object.keys(options.webPreferences)); + } + + // Check options for keys with hypens in them + let deprecatedKey = keysToCheck.filter(isDeprecatedKey)[0]; + if (deprecatedKey) { + try { + deprecate.warn(deprecatedKey, getNonDeprecatedKey(deprecatedKey)); + } catch (error) { + // Return error message so it can be rethrown via C++ + return error.message; + } + } + + let webPreferenceOption; + if (options.hasOwnProperty('nodeIntegration')) { + webPreferenceOption = 'nodeIntegration'; + } else if (options.hasOwnProperty('preload')) { + webPreferenceOption = 'preload'; + } else if (options.hasOwnProperty('zoomFactor')) { + webPreferenceOption = 'zoomFactor'; + } + if (webPreferenceOption) { + try { + deprecate.log(`Setting ${webPreferenceOption} on options is deprecated. Set it on options.webPreferences instead.`); + } catch (error) { + // Return error message so it can be rethrown via C++ + return error.message; + } + } + + return ''; +}; +BrowserWindow._setDeprecatedOptionsCheck(checkForDeprecatedOptions); + module.exports = BrowserWindow; From 2acfb8ad82ee149bec56254c2f61f7fc4b69fcba Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 16 Mar 2016 10:47:55 -0700 Subject: [PATCH 528/688] node-integration -> nodeIntegration --- spec/chromium-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 71cef125618..ac9403a7ecd 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -155,7 +155,7 @@ describe('chromium feature', function() { b.close(); }); - it('accepts "node-integration" as feature', function(done) { + it('accepts "nodeIntegration" as feature', function(done) { var b; listener = function(event) { assert.equal(event.data, 'undefined'); From a14380ed01c7bf5d8535bd9515a3964d2a71db63 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 16 Mar 2016 10:59:47 -0700 Subject: [PATCH 529/688] Set webPrereferences from features tring --- lib/renderer/override.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 2aceec5353d..d9e00122870 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -101,6 +101,7 @@ window.open = function(url, frameName, features) { } options = {}; ints = ['x', 'y', 'width', 'height', 'min-width', 'max-width', 'min-height', 'max-height', 'zoom-factor']; + const webPreferences = ['zoom-factor', 'zoomFactor', 'node-integration', 'nodeIntegration', 'preload']; // Make sure to get rid of excessive whitespace in the property name ref1 = features.split(/,\s*/); @@ -109,7 +110,15 @@ window.open = function(url, frameName, features) { ref2 = feature.split(/\s*=/); name = ref2[0]; value = ref2[1]; - options[name] = value === 'yes' || value === '1' ? true : value === 'no' || value === '0' ? false : value; + value = value === 'yes' || value === '1' ? true : value === 'no' || value === '0' ? false : value; + if (webPreferences.includes(name)) { + if (options.webPreferences == null) { + options.webPreferences = {}; + } + options.webPreferences[name] = value; + } else { + options[name] = value; + } } if (options.left) { if (options.x == null) { From 3e7501579f7644e3e914bacb8ddff4b5291eb302 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 16 Mar 2016 11:00:15 -0700 Subject: [PATCH 530/688] Add camel case versions to ints array --- lib/renderer/override.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/renderer/override.js b/lib/renderer/override.js index d9e00122870..5e9d42adf61 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -100,7 +100,7 @@ window.open = function(url, frameName, features) { features = ''; } options = {}; - ints = ['x', 'y', 'width', 'height', 'min-width', 'max-width', 'min-height', 'max-height', 'zoom-factor']; + ints = ['x', 'y', 'width', 'height', 'min-width', 'max-width', 'min-height', 'minHeight', 'max-height', 'maxHeight', 'zoom-factor', 'zoomFactor']; const webPreferences = ['zoom-factor', 'zoomFactor', 'node-integration', 'nodeIntegration', 'preload']; // Make sure to get rid of excessive whitespace in the property name From 90d815ce6ca2d0e28bc29477e5df9ed6798f2b06 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 16 Mar 2016 11:03:50 -0700 Subject: [PATCH 531/688] Add todo about removing hyphenated options --- lib/renderer/override.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 5e9d42adf61..69295d1632b 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -100,6 +100,8 @@ window.open = function(url, frameName, features) { features = ''; } options = {}; + + // TODO remove hyphenated options in both of the following arrays for 1.0 ints = ['x', 'y', 'width', 'height', 'min-width', 'max-width', 'min-height', 'minHeight', 'max-height', 'maxHeight', 'zoom-factor', 'zoomFactor']; const webPreferences = ['zoom-factor', 'zoomFactor', 'node-integration', 'nodeIntegration', 'preload']; From c31882749d303ef56deadeb8d061641ea1f3f0ee Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 16 Mar 2016 15:03:53 -0700 Subject: [PATCH 532/688] Correct typos in comments --- atom/browser/api/atom_api_window.cc | 2 +- lib/browser/api/browser-window.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 87f6411e665..a41b8fae9f2 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -52,7 +52,7 @@ namespace api { namespace { -// The DeprecatedOptionsCheckCallback funtion which is implemented in JavaScript +// This function is implemented in JavaScript using DeprecatedOptionsCheckCallback = base::Callback)>; DeprecatedOptionsCheckCallback g_deprecated_options_check; diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 9645f855eed..fe9d4415d53 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -259,7 +259,7 @@ const checkForDeprecatedOptions = function(options) { keysToCheck = keysToCheck.concat(Object.keys(options.webPreferences)); } - // Check options for keys with hypens in them + // Check options for keys with hyphens in them let deprecatedKey = keysToCheck.filter(isDeprecatedKey)[0]; if (deprecatedKey) { try { From 737ffd8d7c1e7a3a7d67a237b7bde566e071c2f2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 17 Mar 2016 13:34:30 -0700 Subject: [PATCH 533/688] Improve deprecated message on webPreferences options --- lib/browser/api/browser-window.js | 2 +- spec/api-browser-window-spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index fe9d4415d53..87077ffd2d9 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -280,7 +280,7 @@ const checkForDeprecatedOptions = function(options) { } if (webPreferenceOption) { try { - deprecate.log(`Setting ${webPreferenceOption} on options is deprecated. Set it on options.webPreferences instead.`); + deprecate.log(`options.${webPreferenceOption} is deprecated. Use options.webPreferences.${webPreferenceOption} instead.`); } catch (error) { // Return error message so it can be rethrown via C++ return error.message; diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 00bc2fb9f18..beb84a8d748 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -776,7 +776,7 @@ describe('browser-window module', function() { it('throws a deprecation error for option keys that should be set on webPreferences', function() { assert.throws(function () { new BrowserWindow({zoomFactor: 1}); - }, 'Setting zoomFactor on options is deprecated. Set it on options.webPreferences instead.'); + }, 'options.zoomFactor is deprecated. Use options.webPreferences.zoomFactor instead.'); }); }); }); From 87395cdef81a73147dfc75bfb5eeac6337221d16 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Thu, 17 Mar 2016 16:09:16 -0700 Subject: [PATCH 534/688] add failing spec for undefined accelerator --- spec/api-menu-spec.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index b27840ec4f2..b7bff910f2b 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -32,6 +32,17 @@ describe('menu module', function() { ]); }); + it('does not throw exceptions for undefined/null values', function() { + assert.doesNotThrow(function(){ + Menu.buildFromTemplate([ + { + label: 'text', + accelerator: undefined + } + ]); + }); + }); + describe('Menu.buildFromTemplate should reorder based on item position specifiers', function() { it('should position before existing item', function() { var menu = Menu.buildFromTemplate([ From e9ba5abe03762232dd20b940b27298d855b6a3e1 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Thu, 17 Mar 2016 16:14:31 -0700 Subject: [PATCH 535/688] test for null accelerator too --- spec/api-menu-spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index b7bff910f2b..cd1e5987008 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -38,6 +38,10 @@ describe('menu module', function() { { label: 'text', accelerator: undefined + }, + { + label: 'text again', + accelerator: null } ]); }); From 344dda4029fa475828bf0a27ffb7a58ad08ab398 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Thu, 17 Mar 2016 16:20:23 -0700 Subject: [PATCH 536/688] ignore set menu item fields --- lib/browser/api/menu.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index cfb00bd4527..4effa10238e 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -269,7 +269,7 @@ Menu.getApplicationMenu = function() { Menu.sendActionToFirstResponder = bindings.sendActionToFirstResponder; Menu.buildFromTemplate = function(template) { - var insertIndex, item, j, k, key, len, len1, menu, menuItem, positionedTemplate, value; + var insertIndex, item, j, k, key, len, len1, menu, menuItem, positionedTemplate; if (!Array.isArray(template)) { throw new TypeError('Invalid template for Menu'); } @@ -293,9 +293,9 @@ Menu.buildFromTemplate = function(template) { } menuItem = new MenuItem(item); for (key in item) { - value = item[key]; - if (menuItem[key] == null) { - menuItem[key] = value; + // Preserve extra fields specified by user + if (!menuItem.hasOwnProperty(key)) { + menuItem[key] = item[key]; } } menu.append(menuItem); From 03319a54262a3e936c3d89cb0b2c1b94ca7c7979 Mon Sep 17 00:00:00 2001 From: James Wheare Date: Fri, 18 Mar 2016 15:20:04 +0000 Subject: [PATCH 537/688] OSX: Capture 3-finger swipe events in NativeWindow --- atom/browser/api/atom_api_window.cc | 16 ++++++++++++++++ atom/browser/api/atom_api_window.h | 4 ++++ atom/browser/native_window.cc | 20 ++++++++++++++++++++ atom/browser/native_window.h | 4 ++++ atom/browser/native_window_mac.mm | 12 ++++++++++++ atom/browser/native_window_observer.h | 4 ++++ docs/api/browser-window.md | 16 ++++++++++++++++ 7 files changed, 76 insertions(+) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 6c0f0f6f762..c99f80876b8 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -243,6 +243,22 @@ void Window::OnWindowScrollTouchEnd() { Emit("scroll-touch-end"); } +void Window::OnWindowSwipeUp() { + Emit("swipe-up"); +} + +void Window::OnWindowSwipeRight() { + Emit("swipe-right"); +} + +void Window::OnWindowSwipeDown() { + Emit("swipe-down"); +} + +void Window::OnWindowSwipeLeft() { + Emit("swipe-left"); +} + void Window::OnWindowEnterHtmlFullScreen() { Emit("enter-html-full-screen"); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index f69f5452994..33bf479b8f9 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -69,6 +69,10 @@ class Window : public mate::TrackableObject, void OnWindowMoved() override; void OnWindowScrollTouchBegin() override; void OnWindowScrollTouchEnd() override; + void OnWindowSwipeUp() override; + void OnWindowSwipeRight() override; + void OnWindowSwipeDown() override; + void OnWindowSwipeLeft() override; void OnWindowEnterFullScreen() override; void OnWindowLeaveFullScreen() override; void OnWindowEnterHtmlFullScreen() override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 6c64edec5fb..d95c2346642 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -480,6 +480,26 @@ void NativeWindow::NotifyWindowScrollTouchEnd() { OnWindowScrollTouchEnd()); } +void NativeWindow::NotifyWindowSwipeUp() { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnWindowSwipeUp()); +} + +void NativeWindow::NotifyWindowSwipeRight() { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnWindowSwipeRight()); +} + +void NativeWindow::NotifyWindowSwipeDown() { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnWindowSwipeDown()); +} + +void NativeWindow::NotifyWindowSwipeLeft() { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnWindowSwipeLeft()); +} + void NativeWindow::NotifyWindowLeaveFullScreen() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowLeaveFullScreen()); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index a215b9eb4c1..27bb4fa5de8 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -221,6 +221,10 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowMoved(); void NotifyWindowScrollTouchBegin(); void NotifyWindowScrollTouchEnd(); + void NotifyWindowSwipeUp(); + void NotifyWindowSwipeRight(); + void NotifyWindowSwipeDown(); + void NotifyWindowSwipeLeft(); void NotifyWindowEnterFullScreen(); void NotifyWindowLeaveFullScreen(); void NotifyWindowEnterHtmlFullScreen(); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index a8f7bc5c168..b0f2df4aaec 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -267,6 +267,18 @@ bool ScopedDisableResize::disable_resize_ = false; // NSWindow overrides. +- (void)swipeWithEvent:(NSEvent *)event { + if (event.deltaY == 1.0) { + shell_->NotifyWindowSwipeUp(); + } else if (event.deltaX == -1.0) { + shell_->NotifyWindowSwipeRight(); + } else if (event.deltaY == -1.0) { + shell_->NotifyWindowSwipeDown(); + } else if (event.deltaX == 1.0) { + shell_->NotifyWindowSwipeLeft(); + } +} + - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen { // Resizing is disabled. if (ScopedDisableResize::IsResizeDisabled()) diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index e9dbff4292e..e88a77af41a 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -58,6 +58,10 @@ class NativeWindowObserver { virtual void OnWindowMoved() {} virtual void OnWindowScrollTouchBegin() {} virtual void OnWindowScrollTouchEnd() {} + virtual void OnWindowSwipeUp() {} + virtual void OnWindowSwipeRight() {} + virtual void OnWindowSwipeDown() {} + virtual void OnWindowSwipeLeft() {} virtual void OnWindowEnterFullScreen() {} virtual void OnWindowLeaveFullScreen() {} virtual void OnWindowEnterHtmlFullScreen() {} diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index e2380e4cb18..3ccbb6fe9ad 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -322,6 +322,22 @@ Emitted when scroll wheel event phase has begun. Emitted when scroll wheel event phase has ended. +### Event: 'swipe-up' _OS X_ + +Emitted on 3-finger swipe up. + +### Event: 'swipe-right' _OS X_ + +Emitted on 3-finger swipe right. + +### Event: 'swipe-down' _OS X_ + +Emitted on 3-finger swipe down. + +### Event: 'swipe-left' _OS X_ + +Emitted on 3-finger swipe left. + ## Methods The `BrowserWindow` object has the following methods: From 7668c1ea0b012e4712aa16369ea723a093d7f1d1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 18 Mar 2016 09:02:58 -0700 Subject: [PATCH 538/688] Use deprecate.warn instead of deprecate.log --- lib/browser/api/browser-window.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 87077ffd2d9..ed6cbc4b80a 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -280,7 +280,7 @@ const checkForDeprecatedOptions = function(options) { } if (webPreferenceOption) { try { - deprecate.log(`options.${webPreferenceOption} is deprecated. Use options.webPreferences.${webPreferenceOption} instead.`); + deprecate.warn(`options.${webPreferenceOption}`, `options.webPreferences.${webPreferenceOption}`); } catch (error) { // Return error message so it can be rethrown via C++ return error.message; From 6aa452cda4e3ec6b975bdc9fb3ad043de5bee167 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 18 Mar 2016 09:06:03 -0700 Subject: [PATCH 539/688] Set _setDeprecatedOptionsCheck on exports --- atom/browser/api/atom_api_window.cc | 5 ++--- lib/browser/api/browser-window.js | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index a41b8fae9f2..ccc3c8695d5 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -832,12 +832,11 @@ void Initialize(v8::Local exports, v8::Local unused, &mate::TrackableObject::FromWeakMapID); browser_window.SetMethod("getAllWindows", &mate::TrackableObject::GetAll); - browser_window.SetMethod("_setDeprecatedOptionsCheck", - &atom::api::SetDeprecatedOptionsCheck); - mate::Dictionary dict(isolate, exports); dict.Set("BrowserWindow", browser_window); + dict.SetMethod("_setDeprecatedOptionsCheck", + &atom::api::SetDeprecatedOptionsCheck); } } // namespace diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index ed6cbc4b80a..244e87797a5 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -3,7 +3,7 @@ const ipcMain = require('electron').ipcMain; const deprecate = require('electron').deprecate; const EventEmitter = require('events').EventEmitter; -const BrowserWindow = process.atomBinding('window').BrowserWindow; +const {BrowserWindow, _setDeprecatedOptionsCheck} = process.atomBinding('window'); BrowserWindow.prototype.__proto__ = EventEmitter.prototype; @@ -289,6 +289,6 @@ const checkForDeprecatedOptions = function(options) { return ''; }; -BrowserWindow._setDeprecatedOptionsCheck(checkForDeprecatedOptions); +_setDeprecatedOptionsCheck(checkForDeprecatedOptions); module.exports = BrowserWindow; From 827730144b74aa0fc543cc312201cab08a1a0380 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 18 Mar 2016 10:53:49 -0700 Subject: [PATCH 540/688] style nit --- spec/api-menu-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index cd1e5987008..bb8736e144f 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -33,7 +33,7 @@ describe('menu module', function() { }); it('does not throw exceptions for undefined/null values', function() { - assert.doesNotThrow(function(){ + assert.doesNotThrow(function() { Menu.buildFromTemplate([ { label: 'text', From 99d6afb3a1e65e03c972f43b76f1be905f6aa940 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 18 Mar 2016 11:11:56 -0700 Subject: [PATCH 541/688] Add .node-version pinned to 5.1.1 --- .node-version | 1 + 1 file changed, 1 insertion(+) create mode 100644 .node-version diff --git a/.node-version b/.node-version new file mode 100644 index 00000000000..346d9cae72c --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +v5.1.1 From 8889c2986627737e4aadd80fc3f6d6afe2fac27e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 18 Mar 2016 11:51:02 -0700 Subject: [PATCH 542/688] Use rest parameters --- lib/browser/api/app.js | 8 ++--- lib/browser/api/dialog.js | 25 ++++++++-------- lib/browser/api/navigation-controller.js | 12 +++----- lib/browser/api/web-contents.js | 27 +++++++---------- lib/browser/guest-view-manager.js | 12 ++++---- lib/browser/guest-window-manager.js | 18 +++++------- lib/browser/init.js | 8 ++--- lib/common/api/callbacks-registry.js | 16 ++++------ lib/common/api/deprecate.js | 12 ++------ lib/renderer/api/ipc-renderer.js | 22 +++++--------- lib/renderer/api/ipc.js | 6 +--- lib/renderer/override.js | 20 ++++--------- lib/renderer/web-view/guest-view-internal.js | 31 +++++++++----------- lib/renderer/web-view/web-view.js | 14 ++++----- 14 files changed, 88 insertions(+), 143 deletions(-) diff --git a/lib/browser/api/app.js b/lib/browser/api/app.js index 8d2d203ee98..27b0cb410e4 100644 --- a/lib/browser/api/app.js +++ b/lib/browser/api/app.js @@ -9,8 +9,6 @@ const bindings = process.atomBinding('app'); const downloadItemBindings = process.atomBinding('download_item'); const app = bindings.app; -var slice = [].slice; - app.__proto__ = EventEmitter.prototype; app.setApplicationMenu = function(menu) { @@ -57,10 +55,8 @@ app.getAppPath = function() { // Routes the events to webContents. var ref1 = ['login', 'certificate-error', 'select-client-certificate']; var fn = function(name) { - return app.on(name, function() { - var args, event, webContents; - event = arguments[0], webContents = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - return webContents.emit.apply(webContents, [name, event].concat(slice.call(args))); + return app.on(name, function(event, webContents, ...args) { + return webContents.emit.apply(webContents, [name, event].concat(args)); }); }; var i, len; diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 102aaa3897d..8eb24aa1bbb 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -1,9 +1,10 @@ +'use strict'; + const app = require('electron').app; const BrowserWindow = require('electron').BrowserWindow; const binding = process.atomBinding('dialog'); const v8Util = process.atomBinding('v8_util'); -var slice = [].slice; var includes = [].includes; var fileDialogProperties = { @@ -41,9 +42,8 @@ var checkAppInitialized = function() { }; module.exports = { - showOpenDialog: function() { - var args, callback, options, prop, properties, ref1, value, window, wrappedCallback; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + showOpenDialog: function(...args) { + var callback, options, prop, properties, ref1, value, window, wrappedCallback; checkAppInitialized(); ref1 = parseArgs.apply(null, args), window = ref1[0], options = ref1[1], callback = ref1[2]; if (options == null) { @@ -79,9 +79,9 @@ module.exports = { } : null; return binding.showOpenDialog(String(options.title), String(options.defaultPath), options.filters, properties, window, wrappedCallback); }, - showSaveDialog: function() { - var args, callback, options, ref1, window, wrappedCallback; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + + showSaveDialog: function(...args) { + var callback, options, ref1, window, wrappedCallback; checkAppInitialized(); ref1 = parseArgs.apply(null, args), window = ref1[0], options = ref1[1], callback = ref1[2]; if (options == null) { @@ -103,9 +103,9 @@ module.exports = { } : null; return binding.showSaveDialog(String(options.title), String(options.defaultPath), options.filters, window, wrappedCallback); }, - showMessageBox: function() { - var args, callback, flags, i, j, len, messageBoxType, options, ref1, ref2, ref3, text, window; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + + showMessageBox: function(...args) { + var callback, flags, i, j, len, messageBoxType, options, ref1, ref2, ref3, text, window; checkAppInitialized(); ref1 = parseArgs.apply(null, args), window = ref1[0], options = ref1[1], callback = ref1[2]; if (options == null) { @@ -154,9 +154,8 @@ module.exports = { flags = options.noLink ? messageBoxOptions.noLink : 0; return binding.showMessageBox(messageBoxType, options.buttons, options.defaultId, options.cancelId, flags, options.title, options.message, options.detail, options.icon, window, callback); }, - showErrorBox: function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + + showErrorBox: function(...args) { return binding.showErrorBox.apply(binding, args); } }; diff --git a/lib/browser/api/navigation-controller.js b/lib/browser/api/navigation-controller.js index 8c3878a51fa..a934ffb3ba5 100644 --- a/lib/browser/api/navigation-controller.js +++ b/lib/browser/api/navigation-controller.js @@ -2,18 +2,14 @@ const ipcMain = require('electron').ipcMain; -var slice = [].slice; - // The history operation in renderer is redirected to browser. -ipcMain.on('ATOM_SHELL_NAVIGATION_CONTROLLER', function() { - var args, event, method, ref; - event = arguments[0], method = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; +ipcMain.on('ATOM_SHELL_NAVIGATION_CONTROLLER', function(event, method, ...args) { + var ref; return (ref = event.sender)[method].apply(ref, args); }); -ipcMain.on('ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', function() { - var args, event, method, ref; - event = arguments[0], method = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; +ipcMain.on('ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', function(event, method, ...args) { + var ref; return event.returnValue = (ref = event.sender)[method].apply(ref, args); }); diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index c7dd3bc7475..d1630ecf348 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -9,7 +9,7 @@ const Menu = require('electron').Menu; const binding = process.atomBinding('web_contents'); const debuggerBinding = process.atomBinding('debugger'); -let slice = [].slice; +let slice = [].slice; let nextId = 0; let getNextId = function() { @@ -74,13 +74,11 @@ let wrapWebContents = function(webContents) { webContents.setMaxListeners(0); // WebContents::send(channel, args..) - webContents.send = function() { - var args = 2 <= arguments.length ? slice.call(arguments, 1) : []; - var channel = arguments[0]; + webContents.send = function(channel, ...args) { if (channel == null) { throw new Error('Missing required channel argument'); } - return this._send(channel, slice.call(args)); + return this._send(channel, args); }; // The navigation controller. @@ -99,8 +97,7 @@ let wrapWebContents = function(webContents) { // Mapping webFrame methods. for (let method of webFrameMethods) { - webContents[method] = function() { - let args = Array.prototype.slice.call(arguments); + webContents[method] = function(...args) { this.send('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', method, args); }; } @@ -152,30 +149,26 @@ let wrapWebContents = function(webContents) { }); // This error occurs when host could not be found. - webContents.on('did-fail-provisional-load', function() { - var args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - + webContents.on('did-fail-provisional-load', function(...args) { // Calling loadURL during this event might cause crash, so delay the event // until next tick. setImmediate(() => { - this.emit.apply(this, ['did-fail-load'].concat(slice.call(args))); + this.emit.apply(this, ['did-fail-load'].concat(args)); }); }); // Delays the page-title-updated event to next tick. - webContents.on('-page-title-updated', function() { - var args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + webContents.on('-page-title-updated', function(...args) { setImmediate(() => { - this.emit.apply(this, ['page-title-updated'].concat(slice.call(args))); + this.emit.apply(this, ['page-title-updated'].concat(args)); }); }); // Deprecated. deprecate.rename(webContents, 'loadUrl', 'loadURL'); deprecate.rename(webContents, 'getUrl', 'getURL'); - deprecate.event(webContents, 'page-title-set', 'page-title-updated', function() { - var args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return this.emit.apply(this, ['page-title-set'].concat(slice.call(args))); + deprecate.event(webContents, 'page-title-set', 'page-title-updated', function(...args) { + return this.emit.apply(this, ['page-title-set'].concat(args)); }); return webContents.printToPDF = function(options, callback) { var printingSetting; diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 574207dd5b1..b19fc5cc858 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -1,3 +1,5 @@ +'use strict'; + const ipcMain = require('electron').ipcMain; const webContents = require('electron').webContents; @@ -136,9 +138,8 @@ var createGuest = function(embedder, params) { // Dispatch events to embedder. fn = function(event) { - return guest.on(event, function() { - var args = 2 <= arguments.length ? slice.call(arguments, 1) : []; - return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + guest.viewInstanceId, event].concat(slice.call(args))); + return guest.on(event, function(_, ...args) { + return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + guest.viewInstanceId, event].concat(args)); }); }; for (j = 0, len1 = supportedWebViewEvents.length; j < len1; j++) { @@ -154,9 +155,8 @@ var createGuest = function(embedder, params) { }); // Autosize. - guest.on('size-changed', function() { - var args = 2 <= arguments.length ? slice.call(arguments, 1) : []; - return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-" + guest.viewInstanceId].concat(slice.call(args))); + guest.on('size-changed', function(_, ...args) { + return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-" + guest.viewInstanceId].concat(args)); }); return id; }; diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index bdd32af7a61..a8712ea9f80 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -1,8 +1,9 @@ +'use strict'; + const ipcMain = require('electron').ipcMain; const BrowserWindow = require('electron').BrowserWindow; var hasProp = {}.hasOwnProperty; -var slice = [].slice; var frameToGuest = {}; // Copy attribute of |parent| to |child| if it is not defined in |child|. @@ -81,9 +82,8 @@ var createGuest = function(embedder, url, frameName, options) { }; // Routed window.open messages. -ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function() { - var args, event, frameName, options, url; - event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; +ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function(event, ...args) { + var frameName, options, url; url = args[0], frameName = args[1], options = args[2]; options = mergeBrowserWindowOptions(event.sender, options); event.sender.emit('new-window', event, url, frameName, 'new-window', options); @@ -99,9 +99,8 @@ ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', function(event, guest return (ref1 = BrowserWindow.fromId(guestId)) != null ? ref1.destroy() : void 0; }); -ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', function() { - var args, guestId, method, ref1; - event = arguments[0], guestId = arguments[1], method = arguments[2], args = 4 <= arguments.length ? slice.call(arguments, 3) : []; +ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', function(event, guestId, method, ...args) { + var ref1; return event.returnValue = (ref1 = BrowserWindow.fromId(guestId)) != null ? ref1[method].apply(ref1, args) : void 0; }); @@ -117,8 +116,7 @@ ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', function(event, } }); -ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', function() { - var args, guestId, method, ref1, ref2; - guestId = arguments[1], method = arguments[2], args = 4 <= arguments.length ? slice.call(arguments, 3) : []; +ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', function(event, guestId, method, ...args) { + var ref1, ref2; return (ref1 = BrowserWindow.fromId(guestId)) != null ? (ref2 = ref1.webContents) != null ? ref2[method].apply(ref2, args) : void 0 : void 0; }); diff --git a/lib/browser/init.js b/lib/browser/init.js index 471cc3a5a0a..68ca6fff273 100644 --- a/lib/browser/init.js +++ b/lib/browser/init.js @@ -1,11 +1,11 @@ +'use strict'; + const fs = require('fs'); const path = require('path'); const util = require('util'); const Module = require('module'); const v8 = require('v8'); -var slice = [].slice; - // We modified the original process.argv to let node.js load the atom.js, // we need to restore it here. process.argv.splice(1, 1); @@ -28,9 +28,7 @@ globalPaths.push(path.join(__dirname, 'api', 'exports')); if (process.platform === 'win32') { // Redirect node's console to use our own implementations, since node can not // handle console output when running as GUI program. - var consoleLog = function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + var consoleLog = function(...args) { return process.log(util.format.apply(util, args) + "\n"); }; var streamWrite = function(chunk, encoding, callback) { diff --git a/lib/common/api/callbacks-registry.js b/lib/common/api/callbacks-registry.js index 5b528aa3a6c..d5cfd2da839 100644 --- a/lib/common/api/callbacks-registry.js +++ b/lib/common/api/callbacks-registry.js @@ -1,7 +1,5 @@ 'use strict'; -var slice = [].slice; - const v8Util = process.atomBinding('v8_util'); class CallbacksRegistry { @@ -46,16 +44,14 @@ class CallbacksRegistry { return (ref = this.callbacks[id]) != null ? ref : function() {}; } - call() { - var args, id, ref; - id = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; - return (ref = this.get(id)).call.apply(ref, [global].concat(slice.call(args))); + call(id, ...args) { + var ref; + return (ref = this.get(id)).call.apply(ref, [global].concat(args)); } - apply() { - var args, id, ref; - id = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; - return (ref = this.get(id)).apply.apply(ref, [global].concat(slice.call(args))); + apply(id, ...args) { + var ref; + return (ref = this.get(id)).apply.apply(ref, [global].concat(args)); } remove(id) { diff --git a/lib/common/api/deprecate.js b/lib/common/api/deprecate.js index 852d544deea..16bf71b3f80 100644 --- a/lib/common/api/deprecate.js +++ b/lib/common/api/deprecate.js @@ -1,8 +1,5 @@ // Deprecate a method. -var deprecate, - slice = [].slice; - -deprecate = function(oldName, newName, fn) { +const deprecate = function(oldName, newName, fn) { var warned; warned = false; return function() { @@ -64,10 +61,7 @@ deprecate.property = function(object, property, method) { deprecate.event = function(emitter, oldName, newName, fn) { var warned; warned = false; - return emitter.on(newName, function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - + return emitter.on(newName, function(...args) { // there is listeners for old API. if (this.listenerCount(oldName) > 0) { if (!(warned || process.noDeprecation)) { @@ -77,7 +71,7 @@ deprecate.event = function(emitter, oldName, newName, fn) { if (fn != null) { return fn.apply(this, arguments); } else { - return this.emit.apply(this, [oldName].concat(slice.call(args))); + return this.emit.apply(this, [oldName].concat(args)); } } }); diff --git a/lib/renderer/api/ipc-renderer.js b/lib/renderer/api/ipc-renderer.js index e946dc7a4c0..03fef36bec7 100644 --- a/lib/renderer/api/ipc-renderer.js +++ b/lib/renderer/api/ipc-renderer.js @@ -1,27 +1,21 @@ +'use strict'; + const binding = process.atomBinding('ipc'); const v8Util = process.atomBinding('v8_util'); -var slice = [].slice; - // Created by init.js. const ipcRenderer = v8Util.getHiddenValue(global, 'ipc'); -ipcRenderer.send = function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return binding.send('ipc-message', slice.call(args)); +ipcRenderer.send = function(...args) { + return binding.send('ipc-message', args); }; -ipcRenderer.sendSync = function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return JSON.parse(binding.sendSync('ipc-message-sync', slice.call(args))); +ipcRenderer.sendSync = function(...args) { + return JSON.parse(binding.sendSync('ipc-message-sync', args)); }; -ipcRenderer.sendToHost = function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return binding.send('ipc-message-host', slice.call(args)); +ipcRenderer.sendToHost = function(...args) { + return binding.send('ipc-message-host', args); }; module.exports = ipcRenderer; diff --git a/lib/renderer/api/ipc.js b/lib/renderer/api/ipc.js index a4bab33af81..ee07c791dc8 100644 --- a/lib/renderer/api/ipc.js +++ b/lib/renderer/api/ipc.js @@ -2,17 +2,13 @@ const ipcRenderer = require('electron').ipcRenderer; const deprecate = require('electron').deprecate; const EventEmitter = require('events').EventEmitter; -var slice = [].slice; - // This module is deprecated, we mirror everything from ipcRenderer. deprecate.warn('ipc module', 'require("electron").ipcRenderer'); // Routes events of ipcRenderer. var ipc = new EventEmitter; -ipcRenderer.emit = function() { - var channel = arguments[0]; - var args = 3 <= arguments.length ? slice.call(arguments, 2) : []; +ipcRenderer.emit = function(channel, event, ...args) { ipc.emit.apply(ipc, [channel].concat(slice.call(args))); return EventEmitter.prototype.emit.apply(ipcRenderer, arguments); }; diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 69295d1632b..93a8b76aca3 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -3,8 +3,6 @@ const ipcRenderer = require('electron').ipcRenderer; const remote = require('electron').remote; -var slice = [].slice; - // Cache browser window visibility var _isVisible = true; var _isMinimized = false; @@ -73,10 +71,8 @@ var BrowserWindowProxy = (function() { return ipcRenderer.send('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, targetOrigin, location.origin); }; - BrowserWindowProxy.prototype["eval"] = function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return ipcRenderer.send.apply(ipcRenderer, ['ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'executeJavaScript'].concat(slice.call(args))); + BrowserWindowProxy.prototype["eval"] = function(...args) { + return ipcRenderer.send.apply(ipcRenderer, ['ATOM_SHELL_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'executeJavaScript'].concat(args)); }; return BrowserWindowProxy; @@ -223,16 +219,12 @@ ipcRenderer.on('ATOM_SHELL_GUEST_WINDOW_POSTMESSAGE', function(event, sourceId, }); // Forward history operations to browser. -var sendHistoryOperation = function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return ipcRenderer.send.apply(ipcRenderer, ['ATOM_SHELL_NAVIGATION_CONTROLLER'].concat(slice.call(args))); +var sendHistoryOperation = function(...args) { + return ipcRenderer.send.apply(ipcRenderer, ['ATOM_SHELL_NAVIGATION_CONTROLLER'].concat(args)); }; -var getHistoryOperation = function() { - var args; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - return ipcRenderer.sendSync.apply(ipcRenderer, ['ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER'].concat(slice.call(args))); +var getHistoryOperation = function(...args) { + return ipcRenderer.sendSync.apply(ipcRenderer, ['ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER'].concat(args)); }; window.history.back = function() { diff --git a/lib/renderer/web-view/guest-view-internal.js b/lib/renderer/web-view/guest-view-internal.js index c6e46fab954..a4d8930d904 100644 --- a/lib/renderer/web-view/guest-view-internal.js +++ b/lib/renderer/web-view/guest-view-internal.js @@ -1,8 +1,9 @@ +'use strict'; + const ipcRenderer = require('electron').ipcRenderer; const webFrame = require('electron').webFrame; -var slice = [].slice; -var requestId = 0; +var requestId= 0; var WEB_VIEW_EVENTS = { 'load-commit': ['url', 'isMainFrame'], @@ -41,11 +42,10 @@ var DEPRECATED_EVENTS = { 'page-title-updated': 'page-title-set' }; -var dispatchEvent = function() { - var args, domEvent, eventKey, eventName, f, i, j, len, ref1, webView; - webView = arguments[0], eventName = arguments[1], eventKey = arguments[2], args = 4 <= arguments.length ? slice.call(arguments, 3) : []; +var dispatchEvent = function(webView, eventName, eventKey, ...args) { + var domEvent, f, i, j, len, ref1; if (DEPRECATED_EVENTS[eventName] != null) { - dispatchEvent.apply(null, [webView, DEPRECATED_EVENTS[eventName], eventKey].concat(slice.call(args))); + dispatchEvent.apply(null, [webView, DEPRECATED_EVENTS[eventName], eventKey].concat(args)); } domEvent = new Event(eventName); ref1 = WEB_VIEW_EVENTS[eventKey]; @@ -61,22 +61,19 @@ var dispatchEvent = function() { module.exports = { registerEvents: function(webView, viewInstanceId) { - ipcRenderer.on("ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + viewInstanceId, function() { - var eventName = arguments[1]; - var args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - return dispatchEvent.apply(null, [webView, eventName, eventName].concat(slice.call(args))); + ipcRenderer.on("ATOM_SHELL_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-" + viewInstanceId, function(event, eventName, ...args) { + return dispatchEvent.apply(null, [webView, eventName, eventName].concat(args)); }); - ipcRenderer.on("ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-" + viewInstanceId, function() { - var channel = arguments[1]; - var args = 3 <= arguments.length ? slice.call(arguments, 2) : []; + + ipcRenderer.on("ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-" + viewInstanceId, function(event, channel, ...args) { var domEvent = new Event('ipc-message'); domEvent.channel = channel; - domEvent.args = slice.call(args); + domEvent.args = args; return webView.dispatchEvent(domEvent); }); - return ipcRenderer.on("ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-" + viewInstanceId, function() { - var args, domEvent, f, i, j, len, ref1; - args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + + return ipcRenderer.on("ATOM_SHELL_GUEST_VIEW_INTERNAL_SIZE_CHANGED-" + viewInstanceId, function(event, ...args) { + var domEvent, f, i, j, len, ref1; domEvent = new Event('size-changed'); ref1 = ['oldWidth', 'oldHeight', 'newWidth', 'newHeight']; for (i = j = 0, len = ref1.length; j < len; i = ++j) { diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index 554b2f04cbe..0d85b7549ff 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -10,7 +10,6 @@ const guestViewInternal = require('./guest-view-internal'); const webViewConstants = require('./web-view-constants'); var hasProp = {}.hasOwnProperty; -var slice = [].slice; // ID generator. var nextId = 0; @@ -392,9 +391,8 @@ var registerWebViewElement = function() { // Forward proto.foo* method calls to WebViewImpl.foo*. createBlockHandler = function(m) { - return function() { - var args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - var internal = v8Util.getHiddenValue(this, 'internal'); + return function(...args) { + const internal = v8Util.getHiddenValue(this, 'internal'); if (internal.webContents) { return internal.webContents[m].apply(internal.webContents, args); } else { @@ -407,11 +405,9 @@ var registerWebViewElement = function() { proto[m] = createBlockHandler(m); } createNonBlockHandler = function(m) { - return function() { - var args, internal; - args = 1 <= arguments.length ? slice.call(arguments, 0) : []; - internal = v8Util.getHiddenValue(this, 'internal'); - return ipcRenderer.send.apply(ipcRenderer, ['ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', null, internal.guestInstanceId, m].concat(slice.call(args))); + return function(...args) { + const internal = v8Util.getHiddenValue(this, 'internal'); + return ipcRenderer.send.apply(ipcRenderer, ['ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', null, internal.guestInstanceId, m].concat(args)); }; }; for (j = 0, len1 = nonblockMethods.length; j < len1; j++) { From a53c7529c19a3403defff56d734be8e588560488 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 18 Mar 2016 11:54:34 -0700 Subject: [PATCH 543/688] Remove unneeded slice call --- lib/renderer/api/ipc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/renderer/api/ipc.js b/lib/renderer/api/ipc.js index ee07c791dc8..d3e21db2a3a 100644 --- a/lib/renderer/api/ipc.js +++ b/lib/renderer/api/ipc.js @@ -9,7 +9,7 @@ deprecate.warn('ipc module', 'require("electron").ipcRenderer'); var ipc = new EventEmitter; ipcRenderer.emit = function(channel, event, ...args) { - ipc.emit.apply(ipc, [channel].concat(slice.call(args))); + ipc.emit.apply(ipc, [channel].concat(args)); return EventEmitter.prototype.emit.apply(ipcRenderer, arguments); }; From 70baf86ce2d95aaaf683adb91afb6b46229a4b6f Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Sun, 20 Mar 2016 03:36:27 +0900 Subject: [PATCH 544/688] :memo: Correct link anchor --- docs/tutorial/debugging-main-process.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/debugging-main-process.md b/docs/tutorial/debugging-main-process.md index c7a373f0a45..67f349d9f27 100644 --- a/docs/tutorial/debugging-main-process.md +++ b/docs/tutorial/debugging-main-process.md @@ -44,7 +44,7 @@ $ node_modules/.bin/node-pre-gyp --target=0.36.11 --runtime=electron --fallback- $ node_modules/.bin/node-pre-gyp --target=0.36.11 --runtime=electron --fallback-to-build --directory node_modules/v8-profiler/ --dist-url=https://atom.io/download/atom-shell reinstall ``` -See also [How to install native modules](using-native-node-modules.md). +See also [How to install native modules][how-to-install-native-modules]. ### 5. Enable debug mode for Electron From d73dc0958b6a76d3e551c18f519f04c800205510 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Sun, 20 Mar 2016 04:04:39 +0900 Subject: [PATCH 545/688] :memo: Update Korean docs as upstream [ci skip] --- docs-translations/ko-KR/api/crash-reporter.md | 20 ++++++++++++------- docs-translations/ko-KR/api/native-image.md | 9 +++++++++ docs-translations/ko-KR/api/web-contents.md | 1 + docs-translations/ko-KR/api/web-view-tag.md | 1 + .../ko-KR/tutorial/debugging-main-process.md | 6 +++--- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/docs-translations/ko-KR/api/crash-reporter.md b/docs-translations/ko-KR/api/crash-reporter.md index 81713760a85..c1437571d3f 100644 --- a/docs-translations/ko-KR/api/crash-reporter.md +++ b/docs-translations/ko-KR/api/crash-reporter.md @@ -16,6 +16,12 @@ crashReporter.start({ }); ``` +서버가 크래시 리포트를 받을 수 있도록 설정하기 위해 다음과 같은 프로젝트를 사용할 수도 +있습니다: + +* [socorro](https://github.com/mozilla/socorro) +* [mini-breakpad-server](https://github.com/atom/mini-breakpad-server) + ## Methods `crash-reporter` 모듈은 다음과 같은 메서드를 가지고 있습니다: @@ -50,15 +56,15 @@ crashReporter.start({ ## crash-reporter 업로드 형식 -Crash Reporter는 다음과 같은 데이터를 `submitURL`에 `POST` 방식으로 전송합니다: +Crash Reporter는 다음과 같은 데이터를 `submitURL`에 `multipart/form-data` `POST` 방식으로 전송합니다: -* `ver` String - Electron의 버전 -* `platform` String - 예시 'win32' -* `process_type` String - 예시 'renderer' -* `guid` String - e.g. '5e1286fc-da97-479e-918b-6bfb0c3d1c72' -* `_version` String - `package.json`내의 `version` 필드 +* `ver` String - Electron의 버전. +* `platform` String - e.g. 'win32'. +* `process_type` String - e.g. 'renderer'. +* `guid` String - e.g. '5e1286fc-da97-479e-918b-6bfb0c3d1c72'. +* `_version` String - `package.json`내의 `version` 필드. * `_productName` String - Crash Reporter의 `options` 객체에서 정의한 제품명. * `prod` String - 기본 제품의 이름. 이 경우 Electron으로 표시됩니다. * `_companyName` String - Crash Reporter의 `options` 객체에서 정의한 회사명. -* `upload_file_minidump` File - 크래시 리포트 파일 +* `upload_file_minidump` File - `minidump` 형식의 크래시 리포트 파일. * Crash Reporter의 `options` 객체에서 정의한 `extra` 객체의 속성들. diff --git a/docs-translations/ko-KR/api/native-image.md b/docs-translations/ko-KR/api/native-image.md index 80be2beeafc..2ef35668cae 100644 --- a/docs-translations/ko-KR/api/native-image.md +++ b/docs-translations/ko-KR/api/native-image.md @@ -131,6 +131,15 @@ var image = nativeImage.createFromPath('/Users/somebody/images/icon.png'); 이미지를 data URL로 반환합니다. +### `image.getNativeHandle()` _OS X_ + +이미지의 네이티브 핸들 밑에 있는 C 포인터를 담은 [Buffer][buffer]을 반환합니다. +OS X에선, `NSImage` 인스턴스가 반환됩니다. + +참고로 반환된 포인터는 복사본이 아닌 네이티브 이미지의 밑에 있는 약한 포인터이며, +따라서 반드시 관련된 `nativeImage` 인스턴스가 확실하게 유지되고 있는지를 인지해야 +합니다. + ### `image.isEmpty()` 이미지가 비었는지 확인합니다. diff --git a/docs-translations/ko-KR/api/web-contents.md b/docs-translations/ko-KR/api/web-contents.md index 96b5eacc544..1cda4a3af5e 100644 --- a/docs-translations/ko-KR/api/web-contents.md +++ b/docs-translations/ko-KR/api/web-contents.md @@ -255,6 +255,7 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - 더 많은 응답이 따르는 경우를 표시합니다. + * `activeMatchOrdinal` Integer (optional) - 활성화 일치의 위치. * `matches` Integer (optional) - 일치하는 개수. * `selectionArea` Object (optional) - 첫 일치 부위의 좌표. diff --git a/docs-translations/ko-KR/api/web-view-tag.md b/docs-translations/ko-KR/api/web-view-tag.md index bda18b78898..69fa0c5a767 100644 --- a/docs-translations/ko-KR/api/web-view-tag.md +++ b/docs-translations/ko-KR/api/web-view-tag.md @@ -563,6 +563,7 @@ Returns: * `result` Object * `requestId` Integer * `finalUpdate` Boolean - 더 많은 응답이 따르는 경우를 표시합니다. + * `activeMatchOrdinal` Integer (optional) - 활성화 일치의 위치. * `matches` Integer (optional) - 일치하는 개수. * `selectionArea` Object (optional) - 첫 일치 부위의 좌표. diff --git a/docs-translations/ko-KR/tutorial/debugging-main-process.md b/docs-translations/ko-KR/tutorial/debugging-main-process.md index 0b69c0a165a..43b24c79b3a 100644 --- a/docs-translations/ko-KR/tutorial/debugging-main-process.md +++ b/docs-translations/ko-KR/tutorial/debugging-main-process.md @@ -40,11 +40,11 @@ $ npm install git+https://git@github.com/enlight/node-pre-gyp.git#detect-electro ### 4. Electron용 `node-inspector` `v8` 모듈을 재 컴파일 (target을 사용하는 Electron의 버전에 맞춰 변경) ```bash -$ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-debug/ --dist-url=https://atom.io/download/atom-shell reinstall -$ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-profiler/ --dist-url=https://atom.io/download/atom-shell reinstall +$ node_modules/.bin/node-pre-gyp --target=0.36.11 --runtime=electron --fallback-to-build --directory node_modules/v8-debug/ --dist-url=https://atom.io/download/atom-shell reinstall +$ node_modules/.bin/node-pre-gyp --target=0.36.11 --runtime=electron --fallback-to-build --directory node_modules/v8-profiler/ --dist-url=https://atom.io/download/atom-shell reinstall ``` -또한 [네이티브 모듈을 사용하는 방법](how-to-install-native-modules) 문서도 참고해보세요. +또한 [네이티브 모듈을 사용하는 방법][how-to-install-native-modules] 문서도 참고해보세요. ### 5. Electron 디버그 모드 활성화 From a89e79a7ed92ce267b790e7e0cd757585cb072ea Mon Sep 17 00:00:00 2001 From: chadluo Date: Sun, 20 Mar 2016 14:20:43 +1100 Subject: [PATCH 546/688] fix link --- docs-translations/zh-CN/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/zh-CN/README.md b/docs-translations/zh-CN/README.md index d7a8442ad4a..58293e38470 100644 --- a/docs-translations/zh-CN/README.md +++ b/docs-translations/zh-CN/README.md @@ -73,7 +73,7 @@ * [源码目录结构](development/source-code-directory-structure.md) * [与 NW.js(原 node-webkit)在技术上的差异](development/atom-shell-vs-node-webkit.md) * [构建系统概览](development/build-system-overview.md) -* [构建步骤(Mac)](development/build-instructions-mac.md) +* [构建步骤(OS X)](development/build-instructions-osx.md) * [构建步骤(Windows)](development/build-instructions-windows.md) * [构建步骤(Linux)](development/build-instructions-linux.md) * [在调试中使用 Symbol Server](development/setting-up-symbol-server.md) From 9f6541228d0dfcee3d5ae0da8322ee87dcc8c24f Mon Sep 17 00:00:00 2001 From: OctoHuman Date: Sun, 20 Mar 2016 02:09:30 -0500 Subject: [PATCH 547/688] Fix alert() --- lib/renderer/override.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 69295d1632b..3daea936f45 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -161,11 +161,14 @@ window.open = function(url, frameName, features) { // Use the dialog API to implement alert(). window.alert = function(message, title) { var buttons; + if (message === undefined) { + message = ''; + } if (title == null) { title = ''; } buttons = ['OK']; - message = message.toString(); + message = String(message); remote.dialog.showMessageBox(remote.getCurrentWindow(), { message: message, title: title, From 116d61185a887b50c2a214c0736e07dd6b806868 Mon Sep 17 00:00:00 2001 From: OctoHuman Date: Sun, 20 Mar 2016 03:40:12 -0500 Subject: [PATCH 548/688] Refix alert() --- lib/renderer/override.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 3daea936f45..63c7794ea59 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -161,7 +161,7 @@ window.open = function(url, frameName, features) { // Use the dialog API to implement alert(). window.alert = function(message, title) { var buttons; - if (message === undefined) { + if (arguments.length == 0) { message = ''; } if (title == null) { From f84c41f684f0c6c4bfc69d4e4984c8c7b4e8d33e Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Sun, 20 Mar 2016 18:58:25 +0100 Subject: [PATCH 549/688] Fix Menu documentation --- docs/api/menu.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index 529113509f8..7487f6597a1 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -240,7 +240,11 @@ Generally, the `template` is just an array of `options` for constructing a You can also attach other fields to the element of the `template` and they will become properties of the constructed menu items. -### `Menu.popup([browserWindow, x, y, positioningItem])` +## Instance Methods + +The `menu` object has the following instance methods: + +### `menu.popup([browserWindow, x, y, positioningItem])` * `browserWindow` BrowserWindow (optional) - Default is `null`. * `x` Number (optional) - Default is -1. @@ -253,20 +257,24 @@ Pops up this menu as a context menu in the `browserWindow`. You can optionally provide a `x, y` coordinate to place the menu at, otherwise it will be placed at the current mouse cursor position. -### `Menu.append(menuItem)` +### `menu.append(menuItem)` * `menuItem` MenuItem Appends the `menuItem` to the menu. -### `Menu.insert(pos, menuItem)` +### `menu.insert(pos, menuItem)` * `pos` Integer * `menuItem` MenuItem Inserts the `menuItem` to the `pos` position of the menu. -### `Menu.items()` +## Instance Properties + +`menu` objects also have the following properties: + +### `menu.items` Get an array containing the menu's items. From 52d09e96006e82a598d4806fb13358147ec1df14 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 21 Mar 2016 21:42:12 +0900 Subject: [PATCH 550/688] Run callback of setDestructor immediately when GC happens Fix #4733. --- atom/common/api/object_life_monitor.cc | 17 ++++++++--------- atom/common/api/object_life_monitor.h | 1 + 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom/common/api/object_life_monitor.cc b/atom/common/api/object_life_monitor.cc index 9b7c7fe6d05..916ad8a5177 100644 --- a/atom/common/api/object_life_monitor.cc +++ b/atom/common/api/object_life_monitor.cc @@ -31,16 +31,16 @@ ObjectLifeMonitor::ObjectLifeMonitor(v8::Isolate* isolate, // static void ObjectLifeMonitor::OnObjectGC( const v8::WeakCallbackInfo& data) { - // Usually FirstWeakCallback should do nothing other than reset |object_| - // and then set a second weak callback to run later. We can sidestep that, - // because posting a task to the current message loop is all but free - but - // DO NOT add any more work to this method. The only acceptable place to add - // code is RunCallback. ObjectLifeMonitor* self = data.GetParameter(); self->target_.Reset(); - base::MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(&ObjectLifeMonitor::RunCallback, - self->weak_ptr_factory_.GetWeakPtr())); + self->RunCallback(); + data.SetSecondPassCallback(Free); +} + +// static +void ObjectLifeMonitor::Free( + const v8::WeakCallbackInfo& data) { + delete data.GetParameter(); } void ObjectLifeMonitor::RunCallback() { @@ -50,7 +50,6 @@ void ObjectLifeMonitor::RunCallback() { v8::Context::Scope context_scope(context); v8::Local::New(isolate_, destructor_)->Call( context->Global(), 0, nullptr); - delete this; } } // namespace atom diff --git a/atom/common/api/object_life_monitor.h b/atom/common/api/object_life_monitor.h index 4c932b94c7b..82d923fcedb 100644 --- a/atom/common/api/object_life_monitor.h +++ b/atom/common/api/object_life_monitor.h @@ -23,6 +23,7 @@ class ObjectLifeMonitor { v8::Local destructor); static void OnObjectGC(const v8::WeakCallbackInfo& data); + static void Free(const v8::WeakCallbackInfo& data); void RunCallback(); From cbfe8b922811fcd049a49e4416d9cff4f1c30982 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 21 Mar 2016 09:12:47 -0700 Subject: [PATCH 551/688] Add minWidth and maxWidth to ints array --- lib/renderer/override.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 93a8b76aca3..3548df0dc40 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -88,7 +88,7 @@ if (process.guestInstanceId == null) { // Make the browser window or guest view emit "new-window" event. window.open = function(url, frameName, features) { - var feature, guestId, i, ints, j, len, len1, name, options, ref1, ref2, value; + var feature, guestId, i, j, len, len1, name, options, ref1, ref2, value; if (frameName == null) { frameName = ''; } @@ -98,7 +98,7 @@ window.open = function(url, frameName, features) { options = {}; // TODO remove hyphenated options in both of the following arrays for 1.0 - ints = ['x', 'y', 'width', 'height', 'min-width', 'max-width', 'min-height', 'minHeight', 'max-height', 'maxHeight', 'zoom-factor', 'zoomFactor']; + const ints = ['x', 'y', 'width', 'height', 'min-width', 'minWidth', 'max-width', 'maxWidth', 'min-height', 'minHeight', 'max-height', 'maxHeight', 'zoom-factor', 'zoomFactor']; const webPreferences = ['zoom-factor', 'zoomFactor', 'node-integration', 'nodeIntegration', 'preload']; // Make sure to get rid of excessive whitespace in the property name From 8cf4574198da33976ffc0e3c6d87d6aac6e6f48c Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Sun, 20 Mar 2016 00:20:32 +0900 Subject: [PATCH 552/688] Document `app.setName()` [ci skip] --- docs/api/app.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/api/app.md b/docs/api/app.md index 8935ed894f0..1f139e08e60 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -331,6 +331,12 @@ to the npm modules spec. You should usually also specify a `productName` field, which is your application's full capitalized name, and which will be preferred over `name` by Electron. +### `app.setName(name)` + +* `name` String + +Overrides the current application's name. + ### `app.getLocale()` Returns the current application locale. From 8fac75f4ee2eee76de179a5ae902aa7a9525dbaa Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Tue, 22 Mar 2016 13:48:14 +0900 Subject: [PATCH 553/688] :memo: Update Korean docs as upstream [ci skip] --- docs-translations/ko-KR/api/menu.md | 16 ++++++++++++---- .../ko-KR/development/build-instructions-osx.md | 4 ++-- .../ko-KR/development/build-system-overview.md | 5 +++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/docs-translations/ko-KR/api/menu.md b/docs-translations/ko-KR/api/menu.md index 1ea8289a9ce..c64aa8c4fab 100644 --- a/docs-translations/ko-KR/api/menu.md +++ b/docs-translations/ko-KR/api/menu.md @@ -237,7 +237,11 @@ OS X의 네이티브 액션에 대해 자세히 알아보려면 또한 `template`에는 다른 속성도 추가할 수 있으며 메뉴가 만들어질 때 해당 메뉴 아이템의 프로퍼티로 변환됩니다. -### `Menu.popup([browserWindow, x, y, positioningItem])` +## Instance Methods + +`menu` 객체는 다음과 같은 인스턴스 메서드를 가지고 있습니다: + +### `menu.popup([browserWindow, x, y, positioningItem])` * `browserWindow` BrowserWindow (optional) - 기본값은 `null`입니다. * `x` Number (optional) - 기본값은 -1입니다. @@ -250,20 +254,24 @@ OS X의 네이티브 액션에 대해 자세히 알아보려면 `positioningItem` 속성은 메뉴 팝업 시 마우스 커서에 바로 위치시킬 메뉴 아이템의 인덱스입니다. (OS X에서만 지원합니다) -### `Menu.append(menuItem)` +### `menu.append(menuItem)` * `menuItem` MenuItem 메뉴의 리스트 끝에 `menuItem`을 삽입합니다. -### `Menu.insert(pos, menuItem)` +### `menu.insert(pos, menuItem)` * `pos` Integer * `menuItem` MenuItem `pos` 위치에 `menuItem`을 삽입합니다. -### `Menu.items()` +## Instance Properties + +`menu` 객체는 또한 다음과 같은 속성을 가지고 있습니다: + +### `menu.items` 메뉴가 가지고 있는 메뉴 아이템들의 배열입니다. diff --git a/docs-translations/ko-KR/development/build-instructions-osx.md b/docs-translations/ko-KR/development/build-instructions-osx.md index 9e2a76d3104..142cdaca4df 100644 --- a/docs-translations/ko-KR/development/build-instructions-osx.md +++ b/docs-translations/ko-KR/development/build-instructions-osx.md @@ -21,8 +21,8 @@ $ git clone https://github.com/atom/electron.git ## 부트 스트랩 부트스트랩 스크립트는 필수적인 빌드 종속성 라이브러리들을 모두 다운로드하고 프로젝트 -파일을 생성합니다. 참고로 Electron은 `ninja`를 빌드 툴체인으로 사용하므로 Xcode -프로젝트는 생성되지 않습니다. +파일을 생성합니다. 참고로 Electron은 [ninja](https://ninja-build.org/)를 빌드 +툴체인으로 사용하므로 Xcode 프로젝트는 생성되지 않습니다. ```bash $ cd electron diff --git a/docs-translations/ko-KR/development/build-system-overview.md b/docs-translations/ko-KR/development/build-system-overview.md index 79ead32718d..044a2da0ae2 100644 --- a/docs-translations/ko-KR/development/build-system-overview.md +++ b/docs-translations/ko-KR/development/build-system-overview.md @@ -1,7 +1,8 @@ # 빌드 시스템 개요 -Electron은 프로젝트 생성을 위해 `gyp`를 사용하며 `ninja`를 이용하여 빌드합니다. -프로젝트 설정은 `.gyp` 와 `.gypi` 파일에서 볼 수 있습니다. +Electron은 프로젝트 생성을 위해 [gyp](https://gyp.gsrc.io/)를 사용하며 +[ninja](https://ninja-build.org/)를 이용하여 빌드합니다. 프로젝트 설정은 `.gyp` 와 +`.gypi` 파일에서 볼 수 있습니다. ## gyp 파일 From 4f4dc2f4d8a501494920c4d7ef92a83b8c1a791f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 21 Mar 2016 09:39:07 -0700 Subject: [PATCH 554/688] Use destructuring assigment --- lib/browser/api/web-contents.js | 11 ++--- lib/browser/guest-view-manager.js | 7 +--- lib/common/asar.js | 70 +++++++++++++++---------------- 3 files changed, 40 insertions(+), 48 deletions(-) diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index d1630ecf348..b8e58df379e 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -9,7 +9,6 @@ const Menu = require('electron').Menu; const binding = process.atomBinding('web_contents'); const debuggerBinding = process.atomBinding('debugger'); -let slice = [].slice; let nextId = 0; let getNextId = function() { @@ -126,19 +125,17 @@ let wrapWebContents = function(webContents) { // Dispatch IPC messages to the ipc module. webContents.on('ipc-message', function(event, packed) { - var args, channel; - channel = packed[0], args = 2 <= packed.length ? slice.call(packed, 1) : []; - return ipcMain.emit.apply(ipcMain, [channel, event].concat(slice.call(args))); + const [channel, ...args] = packed; + return ipcMain.emit.apply(ipcMain, [channel, event].concat(args)); }); webContents.on('ipc-message-sync', function(event, packed) { - var args, channel; - channel = packed[0], args = 2 <= packed.length ? slice.call(packed, 1) : []; + const [channel, ...args] = packed; Object.defineProperty(event, 'returnValue', { set: function(value) { return event.sendReply(JSON.stringify(value)); } }); - return ipcMain.emit.apply(ipcMain, [channel, event].concat(slice.call(args))); + return ipcMain.emit.apply(ipcMain, [channel, event].concat(args)); }); // Handle context menu action request from pepper plugin. diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index b19fc5cc858..2fcd3f987f1 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -3,8 +3,6 @@ const ipcMain = require('electron').ipcMain; const webContents = require('electron').webContents; -var slice = [].slice; - // Doesn't exist in early initialization. var webViewManager = null; @@ -149,9 +147,8 @@ var createGuest = function(embedder, params) { // Dispatch guest's IPC messages to embedder. guest.on('ipc-message-host', function(_, packed) { - var args, channel; - channel = packed[0], args = 2 <= packed.length ? slice.call(packed, 1) : []; - return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-" + guest.viewInstanceId, channel].concat(slice.call(args))); + const [channel, ...args] = packed; + return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-" + guest.viewInstanceId, channel].concat(args)); }); // Autosize. diff --git a/lib/common/asar.js b/lib/common/asar.js index aeff18916a1..e3996a193ac 100644 --- a/lib/common/asar.js +++ b/lib/common/asar.js @@ -150,9 +150,9 @@ } old = module[name]; return module[name] = function() { - var archive, asarPath, filePath, isAsar, newPath, p, ref; + var archive, newPath, p; p = arguments[arg]; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return old.apply(this, arguments); } @@ -176,9 +176,9 @@ } old = module[name]; return module[name] = function() { - var archive, asarPath, callback, filePath, isAsar, newPath, p, ref; + var archive, callback, newPath, p; p = arguments[arg]; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return old.apply(this, arguments); } @@ -221,8 +221,8 @@ lstatSync = fs.lstatSync; fs.lstatSync = function(p) { - var archive, asarPath, filePath, isAsar, ref, stats; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive, stats; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return lstatSync(p); } @@ -238,8 +238,8 @@ }; lstat = fs.lstat; fs.lstat = function(p, callback) { - var archive, asarPath, filePath, isAsar, ref, stats; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive, stats; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return lstat(p, callback); } @@ -257,7 +257,7 @@ }; statSync = fs.statSync; fs.statSync = function(p) { - var isAsar = splitPath(p)[0]; + const [isAsar] = splitPath(p); if (!isAsar) { return statSync(p); } @@ -267,7 +267,7 @@ }; stat = fs.stat; fs.stat = function(p, callback) { - var isAsar = splitPath(p)[0]; + const [isAsar] = splitPath(p); if (!isAsar) { return stat(p, callback); } @@ -279,8 +279,8 @@ }; statSyncNoException = fs.statSyncNoException; fs.statSyncNoException = function(p) { - var archive, asarPath, filePath, isAsar, ref, stats; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive, stats; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return statSyncNoException(p); } @@ -296,8 +296,8 @@ }; realpathSync = fs.realpathSync; fs.realpathSync = function(p) { - var archive, asarPath, filePath, isAsar, real, ref; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive, real; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return realpathSync.apply(this, arguments); } @@ -313,8 +313,8 @@ }; realpath = fs.realpath; fs.realpath = function(p, cache, callback) { - var archive, asarPath, filePath, isAsar, real, ref; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive, real; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return realpath.apply(this, arguments); } @@ -339,8 +339,8 @@ }; exists = fs.exists; fs.exists = function(p, callback) { - var archive, asarPath, filePath, isAsar, ref; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return exists(p, callback); } @@ -354,8 +354,8 @@ }; existsSync = fs.existsSync; fs.existsSync = function(p) { - var archive, asarPath, filePath, isAsar, ref; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return existsSync(p); } @@ -367,8 +367,8 @@ }; readFile = fs.readFile; fs.readFile = function(p, options, callback) { - var archive, asarPath, buffer, encoding, fd, filePath, info, isAsar, realPath, ref; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive, buffer, encoding, fd, info, realPath; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return readFile.apply(this, arguments); } @@ -418,9 +418,9 @@ readFileSync = fs.readFileSync; fs.readFileSync = function(p, opts) { // this allows v8 to optimize this function - var archive, asarPath, buffer, encoding, fd, filePath, info, isAsar, options, realPath, ref; + var archive, buffer, encoding, fd, info, options, realPath; options = opts; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return readFileSync.apply(this, arguments); } @@ -470,8 +470,8 @@ }; readdir = fs.readdir; fs.readdir = function(p, callback) { - var archive, asarPath, filePath, files, isAsar, ref; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive, files; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return readdir.apply(this, arguments); } @@ -489,8 +489,8 @@ }; readdirSync = fs.readdirSync; fs.readdirSync = function(p) { - var archive, asarPath, filePath, files, isAsar, ref; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive, files; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return readdirSync.apply(this, arguments); } @@ -506,8 +506,8 @@ }; internalModuleReadFile = process.binding('fs').internalModuleReadFile; process.binding('fs').internalModuleReadFile = function(p) { - var archive, asarPath, buffer, fd, filePath, info, isAsar, realPath, ref; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive, buffer, fd, info, realPath; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return internalModuleReadFile(p); } @@ -539,8 +539,8 @@ }; internalModuleStat = process.binding('fs').internalModuleStat; process.binding('fs').internalModuleStat = function(p) { - var archive, asarPath, filePath, isAsar, ref, stats; - ref = splitPath(p), isAsar = ref[0], asarPath = ref[1], filePath = ref[2]; + var archive, stats; + const [isAsar, asarPath, filePath] = splitPath(p); if (!isAsar) { return internalModuleStat(p); } @@ -570,11 +570,10 @@ if (process.platform === 'win32') { mkdir = fs.mkdir; fs.mkdir = function(p, mode, callback) { - var filePath, isAsar, ref; if (typeof mode === 'function') { callback = mode; } - ref = splitPath(p), isAsar = ref[0], filePath = ref[2]; + const [isAsar, , filePath] = splitPath(p); if (isAsar && filePath.length) { return notDirError(callback); } @@ -582,8 +581,7 @@ }; mkdirSync = fs.mkdirSync; fs.mkdirSync = function(p, mode) { - var filePath, isAsar, ref; - ref = splitPath(p), isAsar = ref[0], filePath = ref[2]; + const [isAsar, , filePath] = splitPath(p); if (isAsar && filePath.length) { notDirError(); } From 43746727aa4ad020c109a306c10718b096bd0bb6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 21 Mar 2016 09:50:11 -0700 Subject: [PATCH 555/688] Use direct params instead of rest params --- lib/browser/api/dialog.js | 12 ++++++------ lib/browser/api/menu.js | 4 ++-- lib/browser/guest-window-manager.js | 4 +--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 8eb24aa1bbb..414cd60d223 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -43,9 +43,9 @@ var checkAppInitialized = function() { module.exports = { showOpenDialog: function(...args) { - var callback, options, prop, properties, ref1, value, window, wrappedCallback; + var prop, properties, value, wrappedCallback; checkAppInitialized(); - ref1 = parseArgs.apply(null, args), window = ref1[0], options = ref1[1], callback = ref1[2]; + let [window, options, callback] = parseArgs.apply(null, args); if (options == null) { options = { title: 'Open', @@ -81,9 +81,9 @@ module.exports = { }, showSaveDialog: function(...args) { - var callback, options, ref1, window, wrappedCallback; + var wrappedCallback; checkAppInitialized(); - ref1 = parseArgs.apply(null, args), window = ref1[0], options = ref1[1], callback = ref1[2]; + let [window, options, callback] = parseArgs.apply(null, args); if (options == null) { options = { title: 'Save' @@ -105,9 +105,9 @@ module.exports = { }, showMessageBox: function(...args) { - var callback, flags, i, j, len, messageBoxType, options, ref1, ref2, ref3, text, window; + var flags, i, j, len, messageBoxType, ref2, ref3, text; checkAppInitialized(); - ref1 = parseArgs.apply(null, args), window = ref1[0], options = ref1[1], callback = ref1[2]; + let [window, options, callback] = parseArgs.apply(null, args); if (options == null) { options = { type: 'none' diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index 4effa10238e..c0a0e078db6 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -51,11 +51,11 @@ var indexOfItemById = function(items, id) { // Returns the index of where to insert the item according to |position|. var indexToInsertByPosition = function(items, position) { - var id, insertIndex, query, ref1; + var insertIndex; if (!position) { return items.length; } - ref1 = position.split('='), query = ref1[0], id = ref1[1]; + const [query, id] = position.split('='); insertIndex = indexOfItemById(items, id); if (insertIndex === -1 && query !== 'endof') { console.warn("Item with id '" + id + "' is not found"); diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index a8712ea9f80..daeba15457c 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -82,9 +82,7 @@ var createGuest = function(embedder, url, frameName, options) { }; // Routed window.open messages. -ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function(event, ...args) { - var frameName, options, url; - url = args[0], frameName = args[1], options = args[2]; +ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function(event, url, frameName, options) { options = mergeBrowserWindowOptions(event.sender, options); event.sender.emit('new-window', event, url, frameName, 'new-window', options); if ((event.sender.isGuest() && !event.sender.allowPopups) || event.defaultPrevented) { From 4127b524d577059716f9f4b12cd5c8bc6ed60474 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 21 Mar 2016 11:03:18 -0700 Subject: [PATCH 556/688] Destructure params directly --- lib/browser/api/web-contents.js | 6 ++---- lib/browser/guest-view-manager.js | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index b8e58df379e..1e0e83f7b05 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -124,12 +124,10 @@ let wrapWebContents = function(webContents) { }; // Dispatch IPC messages to the ipc module. - webContents.on('ipc-message', function(event, packed) { - const [channel, ...args] = packed; + webContents.on('ipc-message', function(event, [channel, ...args]) { return ipcMain.emit.apply(ipcMain, [channel, event].concat(args)); }); - webContents.on('ipc-message-sync', function(event, packed) { - const [channel, ...args] = packed; + webContents.on('ipc-message-sync', function(event, [channel, ...args]) { Object.defineProperty(event, 'returnValue', { set: function(value) { return event.sendReply(JSON.stringify(value)); diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 2fcd3f987f1..1c1d6f9cfd0 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -146,8 +146,7 @@ var createGuest = function(embedder, params) { } // Dispatch guest's IPC messages to embedder. - guest.on('ipc-message-host', function(_, packed) { - const [channel, ...args] = packed; + guest.on('ipc-message-host', function(_, [channel, ...args]) { return embedder.send.apply(embedder, ["ATOM_SHELL_GUEST_VIEW_INTERNAL_IPC_MESSAGE-" + guest.viewInstanceId, channel].concat(args)); }); From 2d32956903fcd610f0d31e4500b5153729665998 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 21 Mar 2016 11:09:29 -0700 Subject: [PATCH 557/688] Destructure objects --- lib/browser/desktop-capturer.js | 6 ++++-- lib/renderer/api/remote.js | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/browser/desktop-capturer.js b/lib/browser/desktop-capturer.js index a4154f0c5b1..c13c6d2e2ec 100644 --- a/lib/browser/desktop-capturer.js +++ b/lib/browser/desktop-capturer.js @@ -1,3 +1,5 @@ +'use strict'; + const ipcMain = require('electron').ipcMain; const desktopCapturer = process.atomBinding('desktop_capturer').desktopCapturer; @@ -33,7 +35,7 @@ ipcMain.on('ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', function(event, captureW desktopCapturer.emit = function(event, name, sources) { // Receiving sources result from main process, now send them back to renderer. - var captureScreen, captureWindow, handledRequest, i, len, ref, ref1, ref2, request, result, source, thumbnailSize, unhandledRequestsQueue; + var handledRequest, i, len, ref, ref1, request, result, source, unhandledRequestsQueue; handledRequest = requestsQueue.shift(0); result = (function() { var i, len, results; @@ -69,7 +71,7 @@ desktopCapturer.emit = function(event, name, sources) { // If the requestsQueue is not empty, start a new request handling. if (requestsQueue.length > 0) { - ref2 = requestsQueue[0].options, captureWindow = ref2.captureWindow, captureScreen = ref2.captureScreen, thumbnailSize = ref2.thumbnailSize; + const {captureWindow, captureScreen, thumbnailSize} = requestsQueue[0].options; return desktopCapturer.startHandling(captureWindow, captureScreen, thumbnailSize); } }; diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index d3d490d053c..6bf7b4229ee 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -216,7 +216,7 @@ let metaToValue = function(meta) { // Construct a plain object from the meta. var metaToPlainObject = function(meta) { - var i, len, name, obj, ref1, ref2, value; + var i, len, obj, ref1; obj = (function() { switch (meta.type) { case 'error': @@ -227,7 +227,7 @@ var metaToPlainObject = function(meta) { })(); ref1 = meta.members; for (i = 0, len = ref1.length; i < len; i++) { - ref2 = ref1[i], name = ref2.name, value = ref2.value; + let {name, value} = ref1[i]; obj[name] = value; } return obj; From 951bd745aa2d1bf8ce899603c4728570a9069dac Mon Sep 17 00:00:00 2001 From: Arek Sredzki Date: Tue, 22 Mar 2016 16:35:03 -0700 Subject: [PATCH 558/688] Added electron-release-server link to the docs By request from a couple users, I've added a link to the electron-release-server, that makes using the auto-updater much easier. --- docs/api/auto-updater.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index 0a5ca2d2d3d..f82520518c8 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -2,6 +2,8 @@ This module provides an interface for the `Squirrel` auto-updater framework. +You can quickly launch a multi-platform release server for distributing your application by forking [electron-release-server](https://github.com/ArekSredzki/electron-release-server). + ## Platform notices Though `autoUpdater` provides a uniform API for different platforms, there are From c0f13103a49abcb23fe3bf1e4fbdfc59c9b39a6c Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 23 Mar 2016 09:39:03 +0900 Subject: [PATCH 559/688] :memo: Update Korean docs as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 7c18f181742..0924e284c31 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -342,6 +342,12 @@ npm 모듈 규칙에 따라 대부분의 경우 `package.json`의 `name` 필드 반드시 이 필드도 같이 지정해야 합니다. 이 필드는 맨 앞글자가 대문자인 어플리케이션 전체 이름을 지정해야 합니다. +### `app.setName(name)` + +* `name` String + +현재 어플리케이션의 이름을 덮어씌웁니다. + ### `app.getLocale()` 현재 어플리케이션의 [로케일](https://ko.wikipedia.org/wiki/%EB%A1%9C%EC%BC%80%EC%9D%BC)을 From 8939c6ac12a1b43a66b94c60a2ec7790af98a1f6 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 23 Mar 2016 09:42:14 +0900 Subject: [PATCH 560/688] :memo: Update Korean readme as upstream [ci skip] --- README-ko.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README-ko.md b/README-ko.md index 28bb02a1637..5bef003966d 100644 --- a/README-ko.md +++ b/README-ko.md @@ -1,6 +1,7 @@ [![Electron Logo](http://electron.atom.io/images/electron-logo.svg)](http://electron.atom.io/) [![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron) +[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/qtmod45u0cc1ouov/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/electron) [![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies) [![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/) From 7f787818004dfbc6ad8ca7fec47b237bcab61a80 Mon Sep 17 00:00:00 2001 From: Sergey Bekrin Date: Wed, 23 Mar 2016 10:44:11 +0300 Subject: [PATCH 561/688] Improve error reporting when using invalid argument types for dialog API methods --- lib/browser/api/dialog.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 414cd60d223..3a9d1200627 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -67,9 +67,13 @@ module.exports = { } if (options.title == null) { options.title = ''; + } else if (typeof options.title !== 'string') { + throw new TypeError('Title need to be string'); } if (options.defaultPath == null) { options.defaultPath = ''; + } else if (typeof options.defaultPath !== 'string') { + throw new TypeError('Default path need to be string'); } if (options.filters == null) { options.filters = []; @@ -91,9 +95,13 @@ module.exports = { } if (options.title == null) { options.title = ''; + } else if (typeof options.title !== 'string') { + throw new TypeError('Title need to be string'); } if (options.defaultPath == null) { options.defaultPath = ''; + } else if (typeof options.defaultPath !== 'string') { + throw new TypeError('Default path need to be string'); } if (options.filters == null) { options.filters = []; @@ -125,12 +133,18 @@ module.exports = { } if (options.title == null) { options.title = ''; + } else if (typeof options.title !== 'string') { + throw new TypeError('Title need to be string'); } if (options.message == null) { options.message = ''; + } else if (typeof options.message !== 'string') { + throw new TypeError('Message need to be string'); } if (options.detail == null) { options.detail = ''; + } else if (typeof options.detail !== 'string') { + throw new TypeError('Detail need to be string'); } if (options.icon == null) { options.icon = null; From 0bd45c7d757ab394d6f14406582f2d59e7b0e943 Mon Sep 17 00:00:00 2001 From: heyunjiang <598119677@qq.com> Date: Wed, 23 Mar 2016 16:11:23 +0800 Subject: [PATCH 562/688] modify 2016.3.23 --- docs-translations/zh-CN/api/app.md | 6 ++++++ docs-translations/zh-CN/api/crash-reporter.md | 9 +++++++-- docs-translations/zh-CN/api/menu.md | 12 ++++++++---- docs-translations/zh-CN/api/native-image.md | 6 ++++++ .../zh-CN/development/build-instructions-osx.md | 2 +- .../zh-CN/development/build-system-overview.md | 2 +- .../zh-CN/tutorial/debugging-main-process.md | 2 ++ 7 files changed, 31 insertions(+), 8 deletions(-) diff --git a/docs-translations/zh-CN/api/app.md b/docs-translations/zh-CN/api/app.md index dd8d6bcfdf6..21c73cf836a 100644 --- a/docs-translations/zh-CN/api/app.md +++ b/docs-translations/zh-CN/api/app.md @@ -295,6 +295,12 @@ app.on('login', function(event, webContents, request, authInfo, callback) { 由于 npm 的命名规则,通常 `name` 字段是一个短的小写字符串。但是应用名的完整名称通常是首字母大写的,你应该单独使用一个 `productName` 字段,用于表示你的应用程序的完整名称。Electron 会优先使用这个字段作为应用名。 +### `app.setName(name)` + +* `name` String + +重写当前应用的名字 + ### `app.getLocale()` 返回当前应用程序的语言。 diff --git a/docs-translations/zh-CN/api/crash-reporter.md b/docs-translations/zh-CN/api/crash-reporter.md index a4646401ad8..6f2de5e8459 100644 --- a/docs-translations/zh-CN/api/crash-reporter.md +++ b/docs-translations/zh-CN/api/crash-reporter.md @@ -15,6 +15,11 @@ crashReporter.start({ }); ``` +可以使用下面的项目来创建一个服务器,用来接收和处理崩溃报告 : + +* [socorro](https://github.com/mozilla/socorro) +* [mini-breakpad-server](https://github.com/atom/mini-breakpad-server) + ## 方法 `crash-reporter` 模块有如下方法: @@ -44,7 +49,7 @@ crashReporter.start({ ## crash-reporter Payload -崩溃报告将发送下面的数据给 `POST` 型的 `提交 URL` : +崩溃报告将发送下面 `multipart/form-data` `POST` 型的数据给 `submitURL` : * `ver` String - Electron 版本. * `platform` String - 例如 'win32'. @@ -56,6 +61,6 @@ crashReporter.start({ * `prod` String - 基础产品名字. 这种情况为 Electron. * `_companyName` String - `crashReporter` `options` 对象中的公司名字. -* `upload_file_minidump` File - 崩溃报告为文件. +* `upload_file_minidump` File - 崩溃报告按照 `minidump` 的格式. * `crashReporter` 中的 `extra` 对象的所有等级和一个属性. `options` object \ No newline at end of file diff --git a/docs-translations/zh-CN/api/menu.md b/docs-translations/zh-CN/api/menu.md index 3a4e7e5c24e..d0cfeeb33eb 100644 --- a/docs-translations/zh-CN/api/menu.md +++ b/docs-translations/zh-CN/api/menu.md @@ -230,7 +230,11 @@ Menu.setApplicationMenu(menu); 你也可以向 `template` 元素添加其它东西,并且他们会变成已经有的菜单项的属性. -### `Menu.popup([browserWindow, x, y, positioningItem])` +##实例方法 + +`menu` 对象有如下实例方法 + +### `menu.popup([browserWindow, x, y, positioningItem])` * `browserWindow` BrowserWindow (可选) - 默认为 `null`. * `x` Number (可选) - 默认为 -1. @@ -240,20 +244,20 @@ Menu.setApplicationMenu(menu); 在 `browserWindow` 中弹出 context menu .你可以选择性地提供指定的 `x, y` 来设置菜单应该放在哪里,否则它将默认地放在当前鼠标的位置. -### `Menu.append(menuItem)` +### `menu.append(menuItem)` * `menuItem` MenuItem 添加菜单项. -### `Menu.insert(pos, menuItem)` +### `menu.insert(pos, menuItem)` * `pos` Integer * `menuItem` MenuItem 在制定位置添加菜单项. -### `Menu.items()` +### `menu.items()` 获取一个菜单项数组. diff --git a/docs-translations/zh-CN/api/native-image.md b/docs-translations/zh-CN/api/native-image.md index cb2569922b2..3644ff0b8bc 100644 --- a/docs-translations/zh-CN/api/native-image.md +++ b/docs-translations/zh-CN/api/native-image.md @@ -121,6 +121,12 @@ var image = nativeImage.createFromPath('/Users/somebody/images/icon.png'); 返回图片数据的 URL. +### `image.getNativeHandle()` _OS X_ + +返回一个保存了 c 指针的 [Buffer][buffer] 来潜在处理原始图像.在OS X, 将会返回一个 `NSImage` 指针实例. + +注意那返回的指针是潜在原始图像的弱指针,而不是一个复制,你_必须_ 确保与 `nativeImage` 的关联不间断 . + ### `image.isEmpty()` 返回一个 boolean ,标识图片是否为空. diff --git a/docs-translations/zh-CN/development/build-instructions-osx.md b/docs-translations/zh-CN/development/build-instructions-osx.md index 18074a3085a..15485e57acc 100644 --- a/docs-translations/zh-CN/development/build-instructions-osx.md +++ b/docs-translations/zh-CN/development/build-instructions-osx.md @@ -20,7 +20,7 @@ $ git clone https://github.com/atom/electron.git ## Bootstrapping -bootstrap 脚本也是必要下载的构建依赖,来创建项目文件.注意我们使用的是 `ninja` 来构建 Electron,所以没有生成 Xcode 项目. +bootstrap 脚本也是必要下载的构建依赖,来创建项目文件.注意我们使用的是 [ninja](https://ninja-build.org/) 来构建 Electron,所以没有生成 Xcode 项目. ```bash $ cd electron diff --git a/docs-translations/zh-CN/development/build-system-overview.md b/docs-translations/zh-CN/development/build-system-overview.md index 95aea7fb1f5..6bd1452b816 100644 --- a/docs-translations/zh-CN/development/build-system-overview.md +++ b/docs-translations/zh-CN/development/build-system-overview.md @@ -1,6 +1,6 @@ # Build System Overview -Electron 使用 `gyp` 来生成项目 ,使用 `ninja` 来构建项目. 项目配置可以在 `.gyp` 和 `.gypi` 文件中找到. +Electron 使用 [gyp](https://gyp.gsrc.io/) 来生成项目 ,使用 [ninja](https://ninja-build.org/) 来构建项目. 项目配置可以在 `.gyp` 和 `.gypi` 文件中找到. ## Gyp 文件 diff --git a/docs-translations/zh-CN/tutorial/debugging-main-process.md b/docs-translations/zh-CN/tutorial/debugging-main-process.md index e3eec0c5b39..361d7c2d57e 100644 --- a/docs-translations/zh-CN/tutorial/debugging-main-process.md +++ b/docs-translations/zh-CN/tutorial/debugging-main-process.md @@ -42,6 +42,8 @@ $ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-t $ node_modules/.bin/node-pre-gyp --target=0.36.2 --runtime=electron --fallback-to-build --directory node_modules/v8-profiler/ --dist-url=https://atom.io/download/atom-shell reinstall ``` +[How to install native modules][how-to-install-native-modules]. + ### 5. 打开 Electron 的调试模式 你也可以用调试参数来运行 Electron : From 8482109dea8f0c3f506e435d2e0e0269a16ff83c Mon Sep 17 00:00:00 2001 From: James Wheare Date: Wed, 23 Mar 2016 15:20:11 +0000 Subject: [PATCH 563/688] Switch to a single OS X swipe event with a direction argument --- atom/browser/api/atom_api_window.cc | 16 ++-------------- atom/browser/api/atom_api_window.h | 5 +---- atom/browser/native_window.cc | 19 ++----------------- atom/browser/native_window.h | 5 +---- atom/browser/native_window_mac.mm | 18 +++++++++--------- atom/browser/native_window_observer.h | 5 +---- docs/api/browser-window.md | 17 +++++------------ 7 files changed, 21 insertions(+), 64 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index c99f80876b8..9a57c98e626 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -243,20 +243,8 @@ void Window::OnWindowScrollTouchEnd() { Emit("scroll-touch-end"); } -void Window::OnWindowSwipeUp() { - Emit("swipe-up"); -} - -void Window::OnWindowSwipeRight() { - Emit("swipe-right"); -} - -void Window::OnWindowSwipeDown() { - Emit("swipe-down"); -} - -void Window::OnWindowSwipeLeft() { - Emit("swipe-left"); +void Window::OnWindowSwipe(const std::string& direction) { + Emit("swipe", direction); } void Window::OnWindowEnterHtmlFullScreen() { diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 33bf479b8f9..d26ff5b3674 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -69,10 +69,7 @@ class Window : public mate::TrackableObject, void OnWindowMoved() override; void OnWindowScrollTouchBegin() override; void OnWindowScrollTouchEnd() override; - void OnWindowSwipeUp() override; - void OnWindowSwipeRight() override; - void OnWindowSwipeDown() override; - void OnWindowSwipeLeft() override; + void OnWindowSwipe(const std::string& direction) override; void OnWindowEnterFullScreen() override; void OnWindowLeaveFullScreen() override; void OnWindowEnterHtmlFullScreen() override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index d95c2346642..2627c704d21 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -480,24 +480,9 @@ void NativeWindow::NotifyWindowScrollTouchEnd() { OnWindowScrollTouchEnd()); } -void NativeWindow::NotifyWindowSwipeUp() { +void NativeWindow::NotifyWindowSwipe(const std::string& direction) { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, - OnWindowSwipeUp()); -} - -void NativeWindow::NotifyWindowSwipeRight() { - FOR_EACH_OBSERVER(NativeWindowObserver, observers_, - OnWindowSwipeRight()); -} - -void NativeWindow::NotifyWindowSwipeDown() { - FOR_EACH_OBSERVER(NativeWindowObserver, observers_, - OnWindowSwipeDown()); -} - -void NativeWindow::NotifyWindowSwipeLeft() { - FOR_EACH_OBSERVER(NativeWindowObserver, observers_, - OnWindowSwipeLeft()); + OnWindowSwipe(direction)); } void NativeWindow::NotifyWindowLeaveFullScreen() { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 27bb4fa5de8..49e1e71d5df 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -221,10 +221,7 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowMoved(); void NotifyWindowScrollTouchBegin(); void NotifyWindowScrollTouchEnd(); - void NotifyWindowSwipeUp(); - void NotifyWindowSwipeRight(); - void NotifyWindowSwipeDown(); - void NotifyWindowSwipeLeft(); + void NotifyWindowSwipe(const std::string& direction); void NotifyWindowEnterFullScreen(); void NotifyWindowLeaveFullScreen(); void NotifyWindowEnterHtmlFullScreen(); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index b0f2df4aaec..2044ee7d718 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -268,15 +268,15 @@ bool ScopedDisableResize::disable_resize_ = false; // NSWindow overrides. - (void)swipeWithEvent:(NSEvent *)event { - if (event.deltaY == 1.0) { - shell_->NotifyWindowSwipeUp(); - } else if (event.deltaX == -1.0) { - shell_->NotifyWindowSwipeRight(); - } else if (event.deltaY == -1.0) { - shell_->NotifyWindowSwipeDown(); - } else if (event.deltaX == 1.0) { - shell_->NotifyWindowSwipeLeft(); - } + if (event.deltaY == 1.0) { + shell_->NotifyWindowSwipe("up"); + } else if (event.deltaX == -1.0) { + shell_->NotifyWindowSwipe("right"); + } else if (event.deltaY == -1.0) { + shell_->NotifyWindowSwipe("down"); + } else if (event.deltaX == 1.0) { + shell_->NotifyWindowSwipe("left"); + } } - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen { diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index e88a77af41a..cfbae95bda1 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -58,10 +58,7 @@ class NativeWindowObserver { virtual void OnWindowMoved() {} virtual void OnWindowScrollTouchBegin() {} virtual void OnWindowScrollTouchEnd() {} - virtual void OnWindowSwipeUp() {} - virtual void OnWindowSwipeRight() {} - virtual void OnWindowSwipeDown() {} - virtual void OnWindowSwipeLeft() {} + virtual void OnWindowSwipe(const std::string& direction) {} virtual void OnWindowEnterFullScreen() {} virtual void OnWindowLeaveFullScreen() {} virtual void OnWindowEnterHtmlFullScreen() {} diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 3ccbb6fe9ad..76343f967b1 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -322,21 +322,14 @@ Emitted when scroll wheel event phase has begun. Emitted when scroll wheel event phase has ended. -### Event: 'swipe-up' _OS X_ +### Event: 'swipe' _OS X_ -Emitted on 3-finger swipe up. +Returns: -### Event: 'swipe-right' _OS X_ +* `event` Event +* `direction` String -Emitted on 3-finger swipe right. - -### Event: 'swipe-down' _OS X_ - -Emitted on 3-finger swipe down. - -### Event: 'swipe-left' _OS X_ - -Emitted on 3-finger swipe left. +Emitted on 3-finger swipe. Possible directions are `up`, `right`, `down`, `left`. ## Methods From 5fccbfc7c6ab64447fc6bebedb93a4c34c32bda1 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 24 Mar 2016 01:24:01 +0530 Subject: [PATCH 564/688] common: use v8::private symbols as identifiers for object properties --- atom/common/api/atom_api_v8_util.cc | 32 ++++++++++++++++++---- atom/renderer/atom_render_view_observer.cc | 6 +++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/atom/common/api/atom_api_v8_util.cc b/atom/common/api/atom_api_v8_util.cc index f50d3485eba..0ebd939398f 100644 --- a/atom/common/api/atom_api_v8_util.cc +++ b/atom/common/api/atom_api_v8_util.cc @@ -11,20 +11,40 @@ namespace { -v8::Local GetHiddenValue(v8::Local object, +v8::Local GetHiddenValue(v8::Isolate* isolate, + v8::Local object, v8::Local key) { - return object->GetHiddenValue(key); + v8::Local context = isolate->GetCurrentContext(); + v8::Local privateKey = v8::Private::ForApi(isolate, key); + v8::Local value; + v8::Maybe result = object->HasPrivate(context, privateKey); + if (!(result.IsJust() && result.FromJust())) + return v8::Local(); + if (object->GetPrivate(context, privateKey).ToLocal(&value)) + return value; + return v8::Local(); } -void SetHiddenValue(v8::Local object, +void SetHiddenValue(v8::Isolate* isolate, + v8::Local object, v8::Local key, v8::Local value) { - object->SetHiddenValue(key, value); + if (value.IsEmpty()) + return; + v8::Local context = isolate->GetCurrentContext(); + v8::Local privateKey = v8::Private::ForApi(isolate, key); + object->SetPrivate(context, privateKey, value); } -void DeleteHiddenValue(v8::Local object, +void DeleteHiddenValue(v8::Isolate* isolate, + v8::Local object, v8::Local key) { - object->DeleteHiddenValue(key); + v8::Local context = isolate->GetCurrentContext(); + v8::Local privateKey = v8::Private::ForApi(isolate, key); + // Actually deleting the value would make force the object into + // dictionary mode which is unnecessarily slow. Instead, we replace + // the hidden value with "undefined". + object->SetPrivate(context, privateKey, v8::Undefined(isolate)); } int32_t GetObjectHash(v8::Local object) { diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index cdbdb3d7c3c..bbaea351378 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -39,7 +39,11 @@ bool GetIPCObject(v8::Isolate* isolate, v8::Local context, v8::Local* ipc) { v8::Local key = mate::StringToV8(isolate, "ipc"); - v8::Local value = context->Global()->GetHiddenValue(key); + v8::Local privateKey = v8::Private::ForApi(isolate, key); + v8::Local global_object = context->Global(); + v8::Local value; + if (!global_object->GetPrivate(context, privateKey).ToLocal(&value)) + return false; if (value.IsEmpty() || !value->IsObject()) return false; *ipc = value->ToObject(); From d2567b038101c4f5af96bf8d2fa21ea7647c1a5c Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Mon, 21 Mar 2016 11:24:25 -0700 Subject: [PATCH 565/688] :zap: Add API: SetASDefaultProtocolHandler This PR adds an API enabling Electron to set itself as the default protocol handler for a custom porotocl on both oS X and Windows. For details, please see `docs/app.md`. Closes #4857 --- atom/browser/api/atom_api_app.cc | 2 ++ atom/browser/browser.h | 3 ++ atom/browser/browser_linux.cc | 4 +++ atom/browser/browser_mac.mm | 16 ++++++++++ atom/browser/browser_win.cc | 54 ++++++++++++++++++++++++++++++++ docs/api/app.md | 20 ++++++++++++ 6 files changed, 99 insertions(+) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index d728d9dd546..00edcf70b23 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -370,6 +370,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( base::Bind(&Browser::ClearRecentDocuments, browser)) .SetMethod("setAppUserModelId", base::Bind(&Browser::SetAppUserModelID, browser)) + .SetMethod("setAsDefaultProtocolClient", + base::Bind(&Browser::SetAsDefaultProtocolClient, browser)) #if defined(OS_MACOSX) .SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("show", base::Bind(&Browser::Show, browser)) diff --git a/atom/browser/browser.h b/atom/browser/browser.h index d976fae675c..38899c11eae 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -76,6 +76,9 @@ class Browser : public WindowListObserver { // Set the application user model ID. void SetAppUserModelID(const base::string16& name); + // Set as default handler for a protocol. + bool SetAsDefaultProtocolClient(const std::string& protocol); + #if defined(OS_MACOSX) // Hide the application. void Hide(); diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index 25cb9a0a238..586ec717a03 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -34,6 +34,10 @@ void Browser::ClearRecentDocuments() { void Browser::SetAppUserModelID(const base::string16& name) { } +bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { + return false; +} + std::string Browser::GetExecutableFileVersion() const { return brightray::GetApplicationVersion(); } diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 5988e662043..c61a9bddf92 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -8,6 +8,7 @@ #include "atom/browser/mac/atom_application_delegate.h" #include "atom/browser/native_window.h" #include "atom/browser/window_list.h" +#include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" #include "base/strings/sys_string_conversions.h" #include "brightray/common/application_info.h" @@ -45,6 +46,21 @@ void Browser::ClearRecentDocuments() { [[NSDocumentController sharedDocumentController] clearRecentDocuments:nil]; } +bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { + if (protocol.empty()) + return false; + + NSString* identifier = [base::mac::MainBundle() bundleIdentifier]; + if (!identifier) + return false; + + NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()]; + OSStatus return_code = + LSSetDefaultHandlerForURLScheme(base::mac::NSToCFCast(protocol_ns), + base::mac::NSToCFCast(identifier)); + return return_code == noErr; +} + void Browser::SetAppUserModelID(const base::string16& name) { } diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index fdf4bd8c3bb..0b9fe545d5d 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -19,6 +19,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/win/win_util.h" +#include "base/win/registry.h" #include "base/win/windows_version.h" #include "atom/common/atom_version.h" @@ -125,6 +126,59 @@ void Browser::SetUserTasks(const std::vector& tasks) { destinations->CommitList(); } +bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { + // HKEY_CLASSES_ROOT + // $PROTOCOL + // (Default) = "URL:$NAME" + // URL Protocol = "" + // shell + // open + // command + // (Default) = "$COMMAND" "%1" + // + // However, the "HKEY_CLASSES_ROOT" key can only be written by the + // Administrator user. So, we instead write to "HKEY_CURRENT_USER\ + // Software\Classes", which is inherited by "HKEY_CLASSES_ROOT" + // anyway, and can be written by unprivileged users. + + if (protocol.empty()) + return false; + + base::FilePath path; + if (!PathService::Get(base::FILE_EXE, &path)) { + LOG(ERROR) << "Error getting app exe path"; + return false; + } + + // Main Registry Key + HKEY root = HKEY_CURRENT_USER; + std::string keyPathStr = "Software\\Classes\\" + protocol; + std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end()); + std::string urlDeclStr = "URL:" + protocol; + std::wstring urlDecl = std::wstring(urlDeclStr.begin(), urlDeclStr.end()); + + // Command Key + std::string cmdPathStr = keyPathStr + "\\shell\\open\\command"; + std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end()); + + // Executable Path + std::wstring exePath(path.value()); + std::wstring exe = L"\"" + exePath + L"\" \"%1\""; + + // Write information to registry + base::win::RegKey key(root, keyPath.c_str(), KEY_ALL_ACCESS); + if (FAILED(key.WriteValue(L"URL Protocol", L"")) || + FAILED(key.WriteValue(L"", urlDecl.c_str()))) + return false; + + base::win::RegKey commandKey(root, cmdPath.c_str(), KEY_ALL_ACCESS); + if (FAILED(commandKey.WriteValue(L"", exe.c_str()))) + return false; + + VLOG(1) << "Chrome registered as default handler for " << protocol << "."; + return true; +} + PCWSTR Browser::GetAppUserModelID() { if (app_user_model_id_.empty()) { SetAppUserModelID(base::ReplaceStringPlaceholders( diff --git a/docs/api/app.md b/docs/api/app.md index 8935ed894f0..e9bd1066a33 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -348,6 +348,25 @@ bar, and on OS X you can visit it from dock menu. Clears the recent documents list. +### `app.setAsDefaultProtocolClient(protocol)` _OS X_ _Windows_ + + * `protocol` String - The name of your protocol, without `://`. If you want your + app to handle `electron://` links, call this method with `electron` as the + parameter. + +This method sets the current executable as the default handler for a protocol +(aka URI scheme). It allows you to integrate your app deeper into the operating +system. Once registered, all links with `your-protocol://` will be openend with +the current executable. The whole link, including protocol, will be passed to +your application as a parameter. + +**Note:** On OS X, you can only register protocols that have been added to +your app's `info.plist`, which can not be modified at runtime. You can however +change the file with a simple text editor or script during build time. +Please refer to [Apple's documentation][CFBundleURLTypes] for details. + +The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally. + ### `app.setUserTasks(tasks)` _Windows_ * `tasks` Array - Array of `Task` objects @@ -541,3 +560,4 @@ Sets the `image` associated with this dock icon. [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx +[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115 \ No newline at end of file From f7a82987f43fcaf4ba01abb6c409646dfe69b7bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E5=A5=94=E5=A5=94?= Date: Thu, 24 Mar 2016 15:30:46 +0800 Subject: [PATCH 566/688] fix translation --- docs-translations/zh-CN/api/chrome-command-line-switches.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs-translations/zh-CN/api/chrome-command-line-switches.md b/docs-translations/zh-CN/api/chrome-command-line-switches.md index e197626302b..78b84b77276 100644 --- a/docs-translations/zh-CN/api/chrome-command-line-switches.md +++ b/docs-translations/zh-CN/api/chrome-command-line-switches.md @@ -22,7 +22,7 @@ app.on('ready', function() { ## --disable-http-cache -禁用 HTTP 请求. +禁止请求 HTTP 时使用磁盘缓存. ## --remote-debugging-port=`port` @@ -137,4 +137,4 @@ app.commandLine.appendSwitch('proxy-bypass-list', ';*.google.com;*foo.com [app]: app.md [append-switch]: app.md#appcommandlineappendswitchswitch-value [ready]: app.md#event-ready -[play-silent-audio]: https://github.com/atom/atom/pull/9485/files \ No newline at end of file +[play-silent-audio]: https://github.com/atom/atom/pull/9485/files From 8839cc51c247a3ec739e0f8975acbc1134e9aa0f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 24 Mar 2016 14:47:31 -0700 Subject: [PATCH 567/688] Update source tree docs for new layout --- .../source-code-directory-structure.md | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/docs/development/source-code-directory-structure.md b/docs/development/source-code-directory-structure.md index 146edae822d..998280a3705 100644 --- a/docs/development/source-code-directory-structure.md +++ b/docs/development/source-code-directory-structure.md @@ -11,35 +11,36 @@ to understand the source code better. ``` Electron -├──atom - Source code of Electron. -| ├── app - System entry code. -| ├── browser - The frontend including the main window, UI, and all of the -| | main process things. This talks to the renderer to manage web pages. -| |   ├── lib - Javascript part of the main process initialization code. -| | ├── ui - Implementation of UI stuff for different platforms. -| | | ├── cocoa - Cocoa specific source code. -| | | ├── gtk - GTK+ specific source code. -| | | └── win - Windows GUI specific source code. -| | ├── default_app - The default page to show when Electron is started -| | | without providing an app. -| | ├── api - The implementation of the main process APIs. -| | | └── lib - Javascript part of the API implementation. -| | ├── net - Network related code. -| | ├── mac - Mac specific Objective-C source code. -| | └── resources - Icons, platform-dependent files, etc. -| ├── renderer - Code that runs in renderer process. -| | ├── lib - Javascript part of renderer initialization code. -| | └── api - The implementation of renderer process APIs. -| | └── lib - Javascript part of the API implementation. -| └── common - Code that used by both the main and renderer processes, -| including some utility functions and code to integrate node's message -| loop into Chromium's message loop. -| ├── lib - Common Javascript initialization code. -| └── api - The implementation of common APIs, and foundations of -| Electron's built-in modules. -| └── lib - Javascript part of the API implementation. +├── atom - C++ source code. +| ├── app - System entry code. +| ├── browser - The frontend including the main window, UI, and all of the +| | main process things. This talks to the renderer to manage web pages. +| | ├── ui - Implementation of UI stuff for different platforms. +| | | ├── cocoa - Cocoa specific source code. +| | | ├── gtk - GTK+ specific source code. +| | | └── win - Windows GUI specific source code. +| | ├── api - The implementation of the main process APIs. +| | ├── net - Network related code. +| | ├── mac - Mac specific Objective-C source code. +| | └── resources - Icons, platform-dependent files, etc. +| ├── renderer - Code that runs in renderer process. +| | └── api - The implementation of renderer process APIs. +| └── common - Code that used by both the main and renderer processes, +| including some utility functions and code to integrate node's message +| loop into Chromium's message loop. +| └── api - The implementation of common APIs, and foundations of +| Electron's built-in modules. ├── chromium_src - Source code that copied from Chromium. +├── default_app - The default page to show when Electron is started without +| providing an app. ├── docs - Documentations. +├── lib - JavaScript source code. +| ├── browser - Javascript main process initialization code. +| | └── api - Javascript API implementation. +| ├── common - JavaScript used by both the main and renderer processes +| | └── api - Javascript API implementation. +| └── renderer - Javascript renderer process initialization code. +| └── api - Javascript API implementation. ├── spec - Automatic tests. ├── atom.gyp - Building rules of Electron. └── common.gypi - Compiler specific settings and building rules for other From 8feb0f044078f22222a849bb618ffb7e42971f9a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 24 Mar 2016 15:15:46 -0700 Subject: [PATCH 568/688] Put link on same line as name --- docs/api/menu.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/api/menu.md b/docs/api/menu.md index 7487f6597a1..d7f32c787fd 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -387,5 +387,4 @@ Menu: ``` [AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html -[setMenu]: -https://github.com/atom/electron/blob/master/docs/api/browser-window.md#winsetmenumenu-linux-windows +[setMenu]: https://github.com/atom/electron/blob/master/docs/api/browser-window.md#winsetmenumenu-linux-windows From 0066833887aba619fd2f91e6462a9b001c54fa47 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 22 Mar 2016 13:22:39 -0700 Subject: [PATCH 569/688] Add repl CLI option --- default_app/main.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/default_app/main.js b/default_app/main.js index 6ff26e9ea67..e0e41235eaa 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -6,6 +6,7 @@ const Menu = electron.Menu; const fs = require('fs'); const path = require('path'); +const repl = require('repl'); const url = require('url'); // Quit when all windows are closed and no other one is listening to this. @@ -27,6 +28,8 @@ for (var i = 0; i < argv.length; i++) { } else if (argv[i] == '--help' || argv[i] == '-h') { option.help = true; break; + } else if (argv[i] == '--interactive' || argv[i] == '-i') { + option.interactive = true; } else if (argv[i] == '--test-type=webdriver') { option.webdriver = true; } else if (argv[i] == '--require' || argv[i] == '-r') { @@ -307,6 +310,8 @@ if (option.file && !option.webdriver) { helpMessage += " -v, --version Print the version."; console.log(helpMessage); process.exit(0); +} else if (option.interactive) { + repl.start('> '); } else { loadApplicationByUrl('file://' + __dirname + '/index.html'); } From e49eae40473ddaa6531300590875d28d08006d21 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 22 Mar 2016 13:24:41 -0700 Subject: [PATCH 570/688] Document -i/--interactive option --- default_app/main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/default_app/main.js b/default_app/main.js index e0e41235eaa..18e39544ab8 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -305,8 +305,9 @@ if (option.file && !option.webdriver) { helpMessage += " - .html/.htm file.\n"; helpMessage += " - http://, https://, or file:// URL.\n"; helpMessage += "\nOptions:\n"; - helpMessage += " -r, --require Module to preload (option can be repeated)\n"; helpMessage += " -h, --help Print this usage message.\n"; + helpMessage += " -i, --interactive Open a REPL to the main process.\n"; + helpMessage += " -r, --require Module to preload (option can be repeated)\n"; helpMessage += " -v, --version Print the version."; console.log(helpMessage); process.exit(0); From 8685f8e6c8f7f95b2833ee7643afa83d9050aadf Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 22 Mar 2016 13:26:05 -0700 Subject: [PATCH 571/688] Add repl run script --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 21ac10cff25..9f097c167df 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "build": "python ./script/build.py -c D", "lint": "python ./script/eslint.py && python ./script/cpplint.py", "preinstall": "node -e 'process.exit(0)'", + "repl": "python ./script/start.py --interactive", "start": "python ./script/start.py", "test": "python ./script/test.py" } From 832ac970885b2ea7bfacf621e1448d25c336b7bf Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 22 Mar 2016 13:34:46 -0700 Subject: [PATCH 572/688] Exit process when repl exits --- default_app/main.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/default_app/main.js b/default_app/main.js index 18e39544ab8..683dccaf3e1 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -278,6 +278,12 @@ function loadApplicationByUrl(appUrl) { require('./default_app').load(appUrl); } +function startRepl() { + repl.start('> ').on('exit', function() { + process.exit(0); + }); +} + // Start the specified app if there is one specified in command line, otherwise // start the default app. if (option.file && !option.webdriver) { @@ -312,7 +318,7 @@ if (option.file && !option.webdriver) { console.log(helpMessage); process.exit(0); } else if (option.interactive) { - repl.start('> '); + startRepl(); } else { loadApplicationByUrl('file://' + __dirname + '/index.html'); } From 09710d6c4766415d9030b1b2532f1de153a103e0 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 22 Mar 2016 13:37:57 -0700 Subject: [PATCH 573/688] Don't quit on window-all-closed when in repl mode --- default_app/main.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/default_app/main.js b/default_app/main.js index 683dccaf3e1..c46d1fc3bd6 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -9,12 +9,6 @@ const path = require('path'); const repl = require('repl'); const url = require('url'); -// Quit when all windows are closed and no other one is listening to this. -app.on('window-all-closed', function() { - if (app.listeners('window-all-closed').length == 1) - app.quit(); -}); - // Parse command line options. var argv = process.argv.slice(1); var option = { file: null, help: null, version: null, webdriver: null, modules: [] }; @@ -43,6 +37,12 @@ for (var i = 0; i < argv.length; i++) { } } +// Quit when all windows are closed and no other one is listening to this. +app.on('window-all-closed', function() { + if (app.listeners('window-all-closed').length == 1 && !option.interactive) + app.quit(); +}); + // Create default menu. app.once('ready', function() { if (Menu.getApplicationMenu()) From a3f30ca8227f63da8ad527c6a224c2bc83937329 Mon Sep 17 00:00:00 2001 From: Pier Bover Date: Fri, 25 Mar 2016 16:26:14 -0600 Subject: [PATCH 574/688] Update desktop-environment-integration.md --- docs/tutorial/desktop-environment-integration.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index c35eea944be..53fdf606d49 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -15,6 +15,8 @@ to the user. Electron conveniently allows developers to send notifications with the [HTML5 Notification API](https://notifications.spec.whatwg.org/), using the currently running operating system's native notification APIs to display it. +Note: since this is an HTML5 API it is only avaialable in the renderer process. + ```javascript var myNotification = new Notification('Title', { body: 'Lorem Ipsum Dolor Sit Amet' From c4128e6b4b64a8abadf2631c8eb141879ef91998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Ram=C3=ADrez=20Norambuena?= Date: Fri, 25 Mar 2016 23:47:47 -0300 Subject: [PATCH 575/688] add curl package into Ubuntu section missing for the build --- docs/development/build-instructions-linux.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/build-instructions-linux.md b/docs/development/build-instructions-linux.md index 9ddeed9809b..df0943050f7 100644 --- a/docs/development/build-instructions-linux.md +++ b/docs/development/build-instructions-linux.md @@ -19,7 +19,7 @@ On Ubuntu, install the following libraries: $ sudo apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \ libnotify-dev libgnome-keyring-dev libgconf2-dev \ libasound2-dev libcap-dev libcups2-dev libxtst-dev \ - libxss1 libnss3-dev gcc-multilib g++-multilib + libxss1 libnss3-dev gcc-multilib g++-multilib curl ``` On Fedora, install the following libraries: From 75f09420577fde62a5c28a5d8fc6c2419c709f9f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 27 Mar 2016 12:16:12 +0900 Subject: [PATCH 576/688] Bump v0.37.3 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom.gyp b/atom.gyp index df7ec4ed329..bfcfb39bab1 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.37.2', + 'version%': '0.37.3', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 06405d836b4..f7bd068e8f4 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.37.2 + 0.37.3 CFBundleShortVersionString - 0.37.2 + 0.37.3 LSApplicationCategoryType public.app-category.developer-tools LSMinimumSystemVersion diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index be2e5666bbf..15252346669 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,37,2,0 - PRODUCTVERSION 0,37,2,0 + FILEVERSION 0,37,3,0 + PRODUCTVERSION 0,37,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.37.2" + VALUE "FileVersion", "0.37.3" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.37.2" + VALUE "ProductVersion", "0.37.3" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 8821ec4e159..cb470529340 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 37 -#define ATOM_PATCH_VERSION 2 +#define ATOM_PATCH_VERSION 3 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/package.json b/package.json index 9f097c167df..ce7c44145d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.37.2", + "version": "0.37.3", "devDependencies": { "asar": "^0.10.0", "eslint": "^2.1.0", From 2ffe891cc8172ccf2fc205863fe610430b89f61a Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Sun, 27 Mar 2016 18:07:58 +0900 Subject: [PATCH 577/688] :memo: Update Korean docs as upstream [ci skip] --- docs-translations/ko-KR/api/menu.md | 2 +- .../source-code-directory-structure.md | 53 ++++++++++--------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/docs-translations/ko-KR/api/menu.md b/docs-translations/ko-KR/api/menu.md index c64aa8c4fab..44fe461bcc2 100644 --- a/docs-translations/ko-KR/api/menu.md +++ b/docs-translations/ko-KR/api/menu.md @@ -382,4 +382,4 @@ OS X에선 지정한 어플리케이션 메뉴에 상관없이 메뉴의 첫번 ``` [AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html -[setMenu]: https://github.com/atom/electron/blob/master/docs/api/browser-window.md#winsetmenumenu-linux-windows +[setMenu]: https://github.com/atom/electron/blob/master/docs-translations/ko-KR/api/browser-window.md#winsetmenumenu-linux-windows diff --git a/docs-translations/ko-KR/development/source-code-directory-structure.md b/docs-translations/ko-KR/development/source-code-directory-structure.md index e0e172d18b4..7450b3b3e9e 100644 --- a/docs-translations/ko-KR/development/source-code-directory-structure.md +++ b/docs-translations/ko-KR/development/source-code-directory-structure.md @@ -10,33 +10,34 @@ Electron의 소스 코드는 몇 개의 파트로 분리되어 있습니다. 그 ``` Electron -├──atom - Electron의 소스코드. -| ├── app - 시스템 엔트리 코드. -| ├── browser - 주 윈도우를 포함한 프론트엔드, UI, 그리고 메인 프로세스에 관련된 것과 -| | 랜더러와 웹 페이지 관리 관련 코드. -| | ├── lib - 메인 프로세스 초기화 코드의 자바스크립트 파트. -| | ├── ui - 크로스 플랫폼에 대응하는 UI 구현. -| | | ├── cocoa - 코코아 특정 소스 코드. -| | | ├── gtk - GTK+ 특정 소스 코드. -| | | └── win - Windows GUI 특정 소스 코드. -| | ├── default_app - 어플리케이션이 제공되지 않으면 기본으로 사용되는 페이지. -| | ├── api - 메인 프로세스 API의 구현. -| | | └── lib - API 구현의 자바스크립트 파트. -| | ├── net - 네트워크 관련 코드. -| | ├── mac - Mac 특정 Objective-C 소스 코드. -| | └── resources - 아이콘들, 플랫폼 종속성 파일들, 기타 등등. -| ├── renderer - 랜더러 프로세스에서 작동하는 코드들. -| | ├── lib - 랜더러 프로세스 초기화 코드의 자바스크립트 파트. -| | └── api - 랜더러 프로세스 API들의 구현. -| | └── lib - API 구현의 자바스크립트 파트. -| └── common - 메인 프로세스와 랜더러 프로세스에서 공유하는 코드. 유틸리티 함수와 -| node 메시지 루프를 Chromium의 메시지 루프에 통합시킨 코드도 포함. -| ├── lib - 공통 자바스크립트 초기화 코드. -| └── api - 공통 API들의 구현, Electron의 빌트인 모듈 기초 코드들. -| └── lib - API 구현의 자바스크립트 파트. -├── chromium_src - 복사된 Chromium 소스 코드. +├── atom - C++ 소스 코드. +| ├── app - 시스템 엔트리 코드. +| ├── browser - 주 윈도우를 포함한 프론트엔드, UI, 그리고 메인 프로세스에 관련된 +| | 코드와 랜더러 및 웹 페이지 관리 관련 코드. +| | ├── ui - 서로 다른 플랫폼에 대한 UI 관련 구현 코드. +| | | ├── cocoa - Cocoa 특정 소스 코드. +| | | ├── gtk - GTK+ 특정 소스 코드. +| | | └── win - Windows GUI 특정 소스 코드. +| | ├── api - 메인 프로세스 API의 구현. +| | ├── net - 네트워킹 관련 코드. +| | ├── mac - Mac 특정 Objective-C 소스 코드. +| | └── resources - 아이콘들, 플랫폼 종속성 파일들, 기타 등등.. +| ├── renderer - 랜더러 프로세스에서 작동하는 코드. +| | └── api - 랜더러 프로세스 API의 구현. +| └── common - 메인과 랜더러 프로세스에서 모두 사용하는 코드, 몇가지 유틸리티 +| 함수들이 포함되어 있고 node의 메시지 루프와 Chromium의 메시지 루프를 통합. +| └── api - 공통 API 구현들, 기초 Electron 빌트-인 모듈들. +├── chromium_src - Chromium에서 복사하여 가져온 소스코드. +├── default_app - Electron에 앱이 제공되지 않았을 때 보여지는 기본 페이지. ├── docs - 참조 문서. -├── spec - 자동화된 테스트. +├── lib - JavaScript 소스 코드. +| ├── browser - Javascript 메인 프로세스 초기화 코드. +| | └── api - Javascript API 구현 코드. +| ├── common - 메인과 랜더러 프로세스에서 모두 사용하는 JavaScript +| | └── api - Javascript API 구현 코드. +| └── renderer - Javascript 랜더러 프로세스 초기화 코드. +| └── api - Javascript API 구현 코드. +├── spec - 자동화 테스트. ├── atom.gyp - Electron의 빌드 규칙. └── common.gypi - 컴파일러 설정 및 `node` 와 `breakpad` 등의 구성요소를 위한 빌드 규칙. From f23729acdb83f16fb6b7ca6b73d1d514124ebba9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 27 Mar 2016 14:47:01 +0900 Subject: [PATCH 578/688] Upgrade to node v5.9.1 --- vendor/node | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/node b/vendor/node index a507a3c3816..12524cebe23 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit a507a3c3816d6ac085ed46250c489a3d76ab8b3c +Subproject commit 12524cebe23226df1f621ffc12e44a62582ae352 From d83cb53997e8e3a4fdf856df770a2c2e8fd296b7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 27 Mar 2016 14:54:26 +0900 Subject: [PATCH 579/688] Type of native array has changed --- atom/common/api/atom_api_asar.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/atom/common/api/atom_api_asar.cc b/atom/common/api/atom_api_asar.cc index 8f5190fecaa..4bfb0ed4c1b 100644 --- a/atom/common/api/atom_api_asar.cc +++ b/atom/common/api/atom_api_asar.cc @@ -129,9 +129,11 @@ void InitAsarSupport(v8::Isolate* isolate, v8::Local process, v8::Local require) { // Evaluate asar_init.coffee. + const char* asar_init_native = reinterpret_cast( + static_cast(node::asar_init_native)); v8::Local asar_init = v8::Script::Compile(v8::String::NewFromUtf8( isolate, - node::asar_init_native, + asar_init_native, v8::String::kNormalString, sizeof(node::asar_init_native) -1)); v8::Local result = asar_init->Run(); @@ -141,9 +143,11 @@ void InitAsarSupport(v8::Isolate* isolate, v8::Local, std::string)> init; if (mate::ConvertFromV8(isolate, result, &init)) { + const char* asar_native = reinterpret_cast( + static_cast(node::asar_native)); init.Run(process, require, - std::string(node::asar_native, sizeof(node::asar_native) - 1)); + std::string(asar_native, sizeof(node::asar_native) - 1)); } } From 70f9cb098ff24cd6a06b65843471a0231a66206c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 27 Mar 2016 15:03:53 +0900 Subject: [PATCH 580/688] Use Environment::KickNextTick --- atom/common/api/atom_bindings.cc | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/atom/common/api/atom_bindings.cc b/atom/common/api/atom_bindings.cc index a000f6fc743..fe53d8793f2 100644 --- a/atom/common/api/atom_bindings.cc +++ b/atom/common/api/atom_bindings.cc @@ -98,24 +98,8 @@ void AtomBindings::OnCallNextTick(uv_async_t* handle) { self->pending_next_ticks_.begin(); it != self->pending_next_ticks_.end(); ++it) { node::Environment* env = *it; - node::Environment::TickInfo* tick_info = env->tick_info(); - - v8::Context::Scope context_scope(env->context()); - if (tick_info->in_tick()) - continue; - - if (tick_info->length() == 0) { - env->isolate()->RunMicrotasks(); - } - - if (tick_info->length() == 0) { - tick_info->set_index(0); - continue; - } - - tick_info->set_in_tick(true); - env->tick_callback_function()->Call(env->process_object(), 0, NULL); - tick_info->set_in_tick(false); + node::Environment::AsyncCallbackScope callback_scope(env); + env->KickNextTick(&callback_scope); } self->pending_next_ticks_.clear(); From 896ea7b79dab9e698b8fc916f8f51e79b5e0e6d5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 27 Mar 2016 18:09:21 +0900 Subject: [PATCH 581/688] Do not create dummy node environment There is a bug in V8 that using Private in a dummy environment would result in crash. --- atom/renderer/atom_renderer_client.cc | 30 +++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 50ff109a2fc..99696cc8282 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -90,18 +90,6 @@ void AtomRendererClient::WebKitInitialized() { blink::WebCustomElement::addEmbedderCustomElementName("browserplugin"); OverrideNodeArrayBuffer(); - - node_bindings_->Initialize(); - node_bindings_->PrepareMessageLoop(); - - DCHECK(!global_env); - - // Create a default empty environment which would be used when we need to - // run V8 code out of a window context (like running a uv callback). - v8::Isolate* isolate = blink::mainThreadIsolate(); - v8::HandleScope handle_scope(isolate); - v8::Local context = v8::Context::New(isolate); - global_env = node::Environment::New(context, uv_default_loop()); } void AtomRendererClient::RenderThreadStarted() { @@ -160,8 +148,14 @@ bool AtomRendererClient::OverrideCreatePlugin( void AtomRendererClient::DidCreateScriptContext( v8::Handle context) { - // Give the node loop a run to make sure everything is ready. - node_bindings_->RunMessageLoop(); + // Whether the node binding has been initialized. + bool first_time = node_bindings_->uv_env() == nullptr; + + // Prepare the node bindings. + if (first_time) { + node_bindings_->Initialize(); + node_bindings_->PrepareMessageLoop(); + } // Setup node environment for each window. node::Environment* env = node_bindings_->CreateEnvironment(context); @@ -169,10 +163,14 @@ void AtomRendererClient::DidCreateScriptContext( // Add atom-shell extended APIs. atom_bindings_->BindTo(env->isolate(), env->process_object()); - // Make uv loop being wrapped by window context. - if (node_bindings_->uv_env() == nullptr) + if (first_time) { + // Make uv loop being wrapped by window context. node_bindings_->set_uv_env(env); + // Give the node loop a run to make sure everything is ready. + node_bindings_->RunMessageLoop(); + } + // Load everything. node_bindings_->LoadEnvironment(env); } From e5886dda9b3ae8a857a069a9c65737f8e66f2c5c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 27 Mar 2016 19:13:15 +0900 Subject: [PATCH 582/688] Avoid re-evaluating internal modules --- lib/common/asar_init.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/common/asar_init.js b/lib/common/asar_init.js index 49b57907c8f..85bb828583b 100644 --- a/lib/common/asar_init.js +++ b/lib/common/asar_init.js @@ -9,6 +9,12 @@ // Make graceful-fs work with asar. var source = process.binding('natives'); source['original-fs'] = source.fs; - return source['fs'] = "var src = '(function (exports, require, module, __filename, __dirname) { ' +\n process.binding('natives')['original-fs'] +\n ' });';\nvar vm = require('vm');\nvar fn = vm.runInThisContext(src, { filename: 'fs.js' });\nfn(exports, require, module);\nvar asar = require('ATOM_SHELL_ASAR');\nasar.wrapFsWithAsar(exports);"; + return source['fs'] = ` +var nativeModule = new process.NativeModule('original-fs'); +nativeModule.cache(); +nativeModule.compile(); +var asar = require('ATOM_SHELL_ASAR'); +asar.wrapFsWithAsar(nativeModule.exports); +module.exports = nativeModule.exports`; }; })(); From e401335ebb2fed1bd224a4be8f305e593f8a2c8c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 27 Mar 2016 19:21:12 +0900 Subject: [PATCH 583/688] Get rid of the global_env --- atom/browser/atom_browser_main_parts.cc | 12 ++++++++---- atom/common/node_bindings.cc | 8 ++------ atom/common/node_includes.h | 7 ------- atom/renderer/atom_renderer_client.cc | 6 +++--- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index a711c1c8d2b..f45f6492a84 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -106,17 +106,21 @@ void AtomBrowserMainParts::PostEarlyInitialization() { node_debugger_.reset(new NodeDebugger(js_env_->isolate())); // Create the global environment. - global_env = node_bindings_->CreateEnvironment(js_env_->context()); + node::Environment* env = + node_bindings_->CreateEnvironment(js_env_->context()); // Make sure node can get correct environment when debugging. if (node_debugger_->IsRunning()) - global_env->AssignToContext(v8::Debug::GetDebugContext()); + env->AssignToContext(v8::Debug::GetDebugContext()); // Add atom-shell extended APIs. - atom_bindings_->BindTo(js_env_->isolate(), global_env->process_object()); + atom_bindings_->BindTo(js_env_->isolate(), env->process_object()); // Load everything. - node_bindings_->LoadEnvironment(global_env); + node_bindings_->LoadEnvironment(env); + + // Wrap the uv loop with global env. + node_bindings_->set_uv_env(env); } void AtomBrowserMainParts::PreMainMessageLoopRun() { diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 950a2cd786a..b0b4148c7ba 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -106,8 +106,6 @@ base::FilePath GetResourcesPath(bool is_browser) { } // namespace -node::Environment* global_env = nullptr; - NodeBindings::NodeBindings(bool is_browser) : is_browser_(is_browser), message_loop_(nullptr), @@ -214,10 +212,8 @@ void NodeBindings::RunMessageLoop() { void NodeBindings::UvRunOnce() { DCHECK(!is_browser_ || BrowserThread::CurrentlyOn(BrowserThread::UI)); - // By default the global env would be used unless user specified another one - // (this happens for renderer process, which wraps the uv loop with web page - // context). - node::Environment* env = uv_env() ? uv_env() : global_env; + node::Environment* env = uv_env(); + CHECK(env); // Use Locker in browser process. mate::Locker locker(env->isolate()); diff --git a/atom/common/node_includes.h b/atom/common/node_includes.h index 3876d862291..bb76afb54db 100644 --- a/atom/common/node_includes.h +++ b/atom/common/node_includes.h @@ -28,11 +28,4 @@ #include "vendor/node/src/node_buffer.h" #include "vendor/node/src/node_internals.h" -namespace atom { -// Defined in node_bindings.cc. -// For renderer it's created in atom_renderer_client.cc. -// For browser it's created in atom_browser_main_parts.cc. -extern node::Environment* global_env; -} - #endif // ATOM_COMMON_NODE_INCLUDES_H_ diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 99696cc8282..7746ce123e4 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -163,6 +163,9 @@ void AtomRendererClient::DidCreateScriptContext( // Add atom-shell extended APIs. atom_bindings_->BindTo(env->isolate(), env->process_object()); + // Load everything. + node_bindings_->LoadEnvironment(env); + if (first_time) { // Make uv loop being wrapped by window context. node_bindings_->set_uv_env(env); @@ -170,9 +173,6 @@ void AtomRendererClient::DidCreateScriptContext( // Give the node loop a run to make sure everything is ready. node_bindings_->RunMessageLoop(); } - - // Load everything. - node_bindings_->LoadEnvironment(env); } void AtomRendererClient::WillReleaseScriptContext( From a4d2dd9b4d65f923f508f5b1509b3da40dad47c0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 27 Mar 2016 19:50:34 +0900 Subject: [PATCH 584/688] Export symbols of node::Environment --- common.gypi | 1 + vendor/node | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/common.gypi b/common.gypi index 6eacdc93a02..a9f067bcc54 100644 --- a/common.gypi +++ b/common.gypi @@ -230,6 +230,7 @@ 'msvs_cygwin_shell': 0, # Strangely setting it to 1 would make building under cygwin fail. 'msvs_disabled_warnings': [ 4005, # (node.h) macro redefinition + 4091, # (node_extern.h) '__declspec(dllimport)' : ignored on left of 'node::Environment' when no variable is declared 4189, # local variable is initialized but not referenced 4201, # (uv.h) nameless struct/union 4267, # conversion from 'size_t' to 'int', possible loss of data diff --git a/vendor/node b/vendor/node index 12524cebe23..d8e7d3e76cb 160000 --- a/vendor/node +++ b/vendor/node @@ -1 +1 @@ -Subproject commit 12524cebe23226df1f621ffc12e44a62582ae352 +Subproject commit d8e7d3e76cb3c6e709449d181ddc2af8c4859303 From 73201e419d9985fb8a4de55d4d33cc922030af84 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 28 Mar 2016 02:09:56 +0530 Subject: [PATCH 585/688] protocol: return status of ReadRawData instead of relying on SetStatus --- atom/browser/net/url_request_fetch_job.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/atom/browser/net/url_request_fetch_job.cc b/atom/browser/net/url_request_fetch_job.cc index d58ea3fe9fb..2f907314cad 100644 --- a/atom/browser/net/url_request_fetch_job.cc +++ b/atom/browser/net/url_request_fetch_job.cc @@ -167,8 +167,6 @@ void URLRequestFetchJob::HeadersCompleted() { } int URLRequestFetchJob::DataAvailable(net::IOBuffer* buffer, int num_bytes) { - // Clear the IO_PENDING status. - SetStatus(net::URLRequestStatus()); // Do nothing if pending_buffer_ is empty, i.e. there's no ReadRawData() // operation waiting for IO completion. if (!pending_buffer_.get()) @@ -176,7 +174,6 @@ int URLRequestFetchJob::DataAvailable(net::IOBuffer* buffer, int num_bytes) { // pending_buffer_ is set to the IOBuffer instance provided to ReadRawData() // by URLRequestJob. - int bytes_read = std::min(num_bytes, pending_buffer_size_); memcpy(pending_buffer_->data(), buffer->data(), bytes_read); @@ -197,12 +194,11 @@ void URLRequestFetchJob::Kill() { int URLRequestFetchJob::ReadRawData(net::IOBuffer* dest, int dest_size) { if (GetResponseCode() == 204) { request()->set_received_response_content_length(prefilter_bytes_read()); - return 0; + return net::OK; } pending_buffer_ = dest; pending_buffer_size_ = dest_size; - SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); - return dest_size; + return net::ERR_IO_PENDING; } bool URLRequestFetchJob::GetMimeType(std::string* mime_type) const { From ab685ac335a834759239eb2cd245d93ab33ddfcf Mon Sep 17 00:00:00 2001 From: Alejandro Gonzalez Sole Date: Sat, 26 Mar 2016 22:07:24 -0400 Subject: [PATCH 586/688] Update power-monitor.md Updated docs in power-monitor to reflect windows only events --- docs/api/power-monitor.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/power-monitor.md b/docs/api/power-monitor.md index 5313aad9c97..49929a78c90 100644 --- a/docs/api/power-monitor.md +++ b/docs/api/power-monitor.md @@ -26,10 +26,10 @@ Emitted when the system is suspending. Emitted when system is resuming. -### Event: 'on-ac' +### Event: 'on-ac' *Windows* Emitted when the system changes to AC power. -### Event: 'on-battery' +### Event: 'on-battery' *Windows* Emitted when system changes to battery power. From 116aa2f48330417c1e0adaef6188c950e849df2c Mon Sep 17 00:00:00 2001 From: Pier Bover Date: Mon, 28 Mar 2016 11:41:16 -0600 Subject: [PATCH 587/688] Update desktop-environment-integration.md --- docs/tutorial/desktop-environment-integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 53fdf606d49..bd4839cd6b1 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -15,7 +15,7 @@ to the user. Electron conveniently allows developers to send notifications with the [HTML5 Notification API](https://notifications.spec.whatwg.org/), using the currently running operating system's native notification APIs to display it. -Note: since this is an HTML5 API it is only avaialable in the renderer process. +Note: since this is an HTML5 API it is only available in the renderer process. ```javascript var myNotification = new Notification('Title', { From 1231360b2ff2ae94068c897ad856d1d7b8b6df9f Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 24 Mar 2016 10:55:09 -0700 Subject: [PATCH 588/688] :zap: Add API: RemoveAsDefaultProtocolHandler --- atom/browser/api/atom_api_app.cc | 2 ++ atom/browser/browser.h | 3 ++ atom/browser/browser_linux.cc | 4 +++ atom/browser/browser_mac.mm | 4 +++ atom/browser/browser_win.cc | 48 +++++++++++++++++++++++++++++++- docs/api/app.md | 10 +++++++ 6 files changed, 70 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 00edcf70b23..ad5b7214ccd 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -372,6 +372,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( base::Bind(&Browser::SetAppUserModelID, browser)) .SetMethod("setAsDefaultProtocolClient", base::Bind(&Browser::SetAsDefaultProtocolClient, browser)) + .SetMethod("removeAsDefaultProtocolClient", + base::Bind(&Browser::RemoveAsDefaultProtocolClient, browser)) #if defined(OS_MACOSX) .SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("show", base::Bind(&Browser::Show, browser)) diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 38899c11eae..634e14e6026 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -76,6 +76,9 @@ class Browser : public WindowListObserver { // Set the application user model ID. void SetAppUserModelID(const base::string16& name); + // Remove the default protocol handler registry key + bool RemoveAsDefaultProtocolClient(const std::string& protocol); + // Set as default handler for a protocol. bool SetAsDefaultProtocolClient(const std::string& protocol); diff --git a/atom/browser/browser_linux.cc b/atom/browser/browser_linux.cc index 586ec717a03..6c7d4abaf64 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -34,6 +34,10 @@ void Browser::ClearRecentDocuments() { void Browser::SetAppUserModelID(const base::string16& name) { } +bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { + return false; +} + bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { return false; } diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index c61a9bddf92..0294894fcd6 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -46,6 +46,10 @@ void Browser::ClearRecentDocuments() { [[NSDocumentController sharedDocumentController] clearRecentDocuments:nil]; } +bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { + return false; +} + bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { if (protocol.empty()) return false; diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index 0b9fe545d5d..9531406f8cd 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -126,6 +126,53 @@ void Browser::SetUserTasks(const std::vector& tasks) { destinations->CommitList(); } +bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { + if (protocol.empty()) + return false; + + base::FilePath path; + if (!PathService::Get(base::FILE_EXE, &path)) { + LOG(ERROR) << "Error getting app exe path"; + return false; + } + + // Main Registry Key + HKEY root = HKEY_CURRENT_USER; + std::string keyPathStr = "Software\\Classes\\" + protocol; + std::wstring keyPath = std::wstring(keyPathStr.begin(), keyPathStr.end()); + + // Command Key + std::string cmdPathStr = keyPathStr + "\\shell\\open\\command"; + std::wstring cmdPath = std::wstring(cmdPathStr.begin(), cmdPathStr.end()); + + base::win::RegKey key; + base::win::RegKey commandKey; + if (FAILED(key.Open(root, keyPath.c_str(), KEY_ALL_ACCESS))) + // Key doesn't even exist, we can confirm that it is not set + return true; + + if (FAILED(commandKey.Open(root, cmdPath.c_str(), KEY_ALL_ACCESS))) + // Key doesn't even exist, we can confirm that it is not set + return true; + + std::wstring keyVal; + if (FAILED(commandKey.ReadValue(L"", &keyVal))) + // Default value not set, we can confirm that it is not set + return true; + + std::wstring exePath(path.value()); + std::wstring exe = L"\"" + exePath + L"\" \"%1\""; + if (keyVal == exe) { + // Let's kill the key + if (FAILED(key.DeleteKey(L"shell"))) + return false; + + return true; + } else { + return true; + } +} + bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { // HKEY_CLASSES_ROOT // $PROTOCOL @@ -175,7 +222,6 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { if (FAILED(commandKey.WriteValue(L"", exe.c_str()))) return false; - VLOG(1) << "Chrome registered as default handler for " << protocol << "."; return true; } diff --git a/docs/api/app.md b/docs/api/app.md index e9bd1066a33..94fb28304dd 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -367,6 +367,16 @@ Please refer to [Apple's documentation][CFBundleURLTypes] for details. The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally. +### `app.removeAsDefaultProtocolClient(protocol)` _Windows_ + + * `protocol` String - The name of your protocol, without `://`. + +This method checks if the current executable as the default handler for a protocol +(aka URI scheme). If so, it will remove the app as the default handler. + +**Note:** On OS X, removing the app will automatically remove the app as the +default protocol handler. + ### `app.setUserTasks(tasks)` _Windows_ * `tasks` Array - Array of `Task` objects From ff2d0050587c3fb0a81f8b48aebca00725080988 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Tue, 29 Mar 2016 10:47:31 -0700 Subject: [PATCH 589/688] Add "black background?" to FAQ Closes #4937 --- docs/faq/electron-faq.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index 41b301d7198..77d1fca66e9 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -144,6 +144,17 @@ is very likely you are using the module in the wrong process. For example `electron.app` can only be used in the main process, while `electron.webFrame` is only available in renderer processes. +## Why is my app's background transparent? +Since Electron `0.37.3`, the default user-agent background color is `transparent`. Simply specify a background color in HTML; + +```html + +``` + [memory-management]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx [electron-module]: https://www.npmjs.com/package/electron From edbb2b4a26f25ad50c428700ac7dbf7eac01bf11 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 30 Mar 2016 10:42:59 +0900 Subject: [PATCH 590/688] :memo: Update Korean docs as upstream [ci skip] --- docs-translations/ko-KR/api/power-monitor.md | 4 ++-- .../ko-KR/development/build-instructions-linux.md | 2 +- docs-translations/ko-KR/faq/electron-faq.md | 13 +++++++++++++ .../tutorial/desktop-environment-integration.md | 2 ++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs-translations/ko-KR/api/power-monitor.md b/docs-translations/ko-KR/api/power-monitor.md index 29a3aabc84a..63d5959fe20 100644 --- a/docs-translations/ko-KR/api/power-monitor.md +++ b/docs-translations/ko-KR/api/power-monitor.md @@ -29,10 +29,10 @@ app.on('ready', function() { 시스템의 절전모드가 해제될 때 발생하는 이벤트입니다. -## Event: `on-ac` +## Event: `on-ac` _Windows_ 시스템이 AC 어뎁터 충전기를 사용하기 시작할 때 발생하는 이벤트입니다. -## Event: `on-battery` +## Event: `on-battery` _Windows_ 시스템이 배터리를 사용하기 시작할 때 발생하는 이벤트입니다. diff --git a/docs-translations/ko-KR/development/build-instructions-linux.md b/docs-translations/ko-KR/development/build-instructions-linux.md index c4f161fa56a..377a7977a85 100644 --- a/docs-translations/ko-KR/development/build-instructions-linux.md +++ b/docs-translations/ko-KR/development/build-instructions-linux.md @@ -21,7 +21,7 @@ Ubuntu를 사용하고 있다면 다음과 같이 라이브러리를 설치해 $ sudo apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \ libnotify-dev libgnome-keyring-dev libgconf2-dev \ libasound2-dev libcap-dev libcups2-dev libxtst-dev \ - libxss1 libnss3-dev gcc-multilib g++-multilib + libxss1 libnss3-dev gcc-multilib g++-multilib curl ``` Fedora를 사용하고 있다면 다음과 같이 라이브러리를 설치해야 합니다: diff --git a/docs-translations/ko-KR/faq/electron-faq.md b/docs-translations/ko-KR/faq/electron-faq.md index ea9953fcd4c..40d10f293f4 100644 --- a/docs-translations/ko-KR/faq/electron-faq.md +++ b/docs-translations/ko-KR/faq/electron-faq.md @@ -144,6 +144,19 @@ npm uninstall -g electron 모듈이며, 반면 `electron.webFrame` 모듈은 랜더러 프로세스에서만 사용할 수 있는 모듈입니다. +## 왜 저의 앱 배경이 투명하죠? + +Electron `0.37.3` 부터, 기본 클라이언트 배경색이 `투명색`으로 변경되었습니다. +간단히 HTML에서 배경색을 지정합니다: + +```html + +``` + [memory-management]: https://developer.mozilla.org/ko/docs/Web/JavaScript/Memory_Management [variable-scope]: https://msdn.microsoft.com/library/bzt2dkta(v=vs.94).aspx [electron-module]: https://www.npmjs.com/package/electron diff --git a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md index c72af78a278..ddeadc04e91 100644 --- a/docs-translations/ko-KR/tutorial/desktop-environment-integration.md +++ b/docs-translations/ko-KR/tutorial/desktop-environment-integration.md @@ -14,6 +14,8 @@ Windows, Linux, OS X 운영체제 모두 기본적으로 어플리케이션에 통해 개발자가 편리하게 데스크톱 알림을 사용할 수 있는 기능을 제공합니다. 데스크톱 알림은 운영체제의 네이티브 알림 API를 사용하여 표시합니다. +__참고:__ 이 API는 HTML5 API이기 때문에 랜더러 프로세스에서만 사용할 수 있습니다. + ```javascript var myNotification = new Notification('Title', { body: 'Lorem Ipsum Dolor Sit Amet' From c4a2329665e52e27480d309d74cafb425a4988d8 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Wed, 30 Mar 2016 10:55:50 +0900 Subject: [PATCH 591/688] :memo: Update docs styles * Adjust line length to `80` * Change platform marker `*` to `_` * Enhance a note section [ci skip] --- docs/api/power-monitor.md | 4 ++-- docs/faq/electron-faq.md | 4 +++- docs/tutorial/desktop-environment-integration.md | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/api/power-monitor.md b/docs/api/power-monitor.md index 49929a78c90..4465b253a75 100644 --- a/docs/api/power-monitor.md +++ b/docs/api/power-monitor.md @@ -26,10 +26,10 @@ Emitted when the system is suspending. Emitted when system is resuming. -### Event: 'on-ac' *Windows* +### Event: 'on-ac' _Windows_ Emitted when the system changes to AC power. -### Event: 'on-battery' *Windows* +### Event: 'on-battery' _Windows_ Emitted when system changes to battery power. diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index 77d1fca66e9..1782d387310 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -145,7 +145,9 @@ is very likely you are using the module in the wrong process. For example is only available in renderer processes. ## Why is my app's background transparent? -Since Electron `0.37.3`, the default user-agent background color is `transparent`. Simply specify a background color in HTML; + +Since Electron `0.37.3`, the default user-agent background color is `transparent`. +Simply specify a background color in HTML: ```html '; - this.setupWebViewAttributes(); - this.setupFocusPropagation(); - this.viewInstanceId = getNextId(); - shadowRoot.appendChild(this.browserPluginNode); + this.on = {} + this.browserPluginNode = this.createBrowserPluginNode() + shadowRoot = this.webviewNode.createShadowRoot() + shadowRoot.innerHTML = '' + this.setupWebViewAttributes() + this.setupFocusPropagation() + this.viewInstanceId = getNextId() + shadowRoot.appendChild(this.browserPluginNode) // Subscribe to host's zoom level changes. this.onZoomLevelChanged = (zoomLevel) => { - this.webviewNode.setZoomLevel(zoomLevel); - }; - webFrame.on('zoom-level-changed', this.onZoomLevelChanged); + this.webviewNode.setZoomLevel(zoomLevel) + } + webFrame.on('zoom-level-changed', this.onZoomLevelChanged) } - WebViewImpl.prototype.createBrowserPluginNode = function() { + WebViewImpl.prototype.createBrowserPluginNode = function () { // We create BrowserPlugin as a custom element in order to observe changes // to attributes synchronously. - var browserPluginNode; - browserPluginNode = new WebViewImpl.BrowserPlugin(); - v8Util.setHiddenValue(browserPluginNode, 'internal', this); - return browserPluginNode; - }; + var browserPluginNode + browserPluginNode = new WebViewImpl.BrowserPlugin() + v8Util.setHiddenValue(browserPluginNode, 'internal', this) + return browserPluginNode + } // Resets some state upon reattaching element to the DOM. - WebViewImpl.prototype.reset = function() { + WebViewImpl.prototype.reset = function () { // Unlisten the zoom-level-changed event. - webFrame.removeListener('zoom-level-changed', this.onZoomLevelChanged); + webFrame.removeListener('zoom-level-changed', this.onZoomLevelChanged) // If guestInstanceId is defined then the has navigated and has // already picked up a partition ID. Thus, we need to reset the initialization @@ -66,174 +66,172 @@ var WebViewImpl = (function() { // heard back from createGuest yet. We will not reset the flag in this case so // that we don't end up allocating a second guest. if (this.guestInstanceId) { - guestViewInternal.destroyGuest(this.guestInstanceId); - this.webContents = null; - this.guestInstanceId = void 0; - this.beforeFirstNavigation = true; - this.attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId = true; + guestViewInternal.destroyGuest(this.guestInstanceId) + this.webContents = null + this.guestInstanceId = void 0 + this.beforeFirstNavigation = true + this.attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId = true } - return this.internalInstanceId = 0; - }; + return this.internalInstanceId = 0 + } // Sets the .request property. - WebViewImpl.prototype.setRequestPropertyOnWebViewNode = function(request) { + WebViewImpl.prototype.setRequestPropertyOnWebViewNode = function (request) { return Object.defineProperty(this.webviewNode, 'request', { value: request, enumerable: true - }); - }; + }) + } - WebViewImpl.prototype.setupFocusPropagation = function() { + WebViewImpl.prototype.setupFocusPropagation = function () { if (!this.webviewNode.hasAttribute('tabIndex')) { // needs a tabIndex in order to be focusable. // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute // to allow to be focusable. // See http://crbug.com/231664. - this.webviewNode.setAttribute('tabIndex', -1); + this.webviewNode.setAttribute('tabIndex', -1) } // Focus the BrowserPlugin when the takes focus. this.webviewNode.addEventListener('focus', () => { - this.browserPluginNode.focus(); - }); + this.browserPluginNode.focus() + }) // Blur the BrowserPlugin when the loses focus. this.webviewNode.addEventListener('blur', () => { - this.browserPluginNode.blur(); - }); - }; - + this.browserPluginNode.blur() + }) + } // This observer monitors mutations to attributes of the and // updates the BrowserPlugin properties accordingly. In turn, updating // a BrowserPlugin property will update the corresponding BrowserPlugin // attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more // details. - WebViewImpl.prototype.handleWebviewAttributeMutation = function(attributeName, oldValue, newValue) { + WebViewImpl.prototype.handleWebviewAttributeMutation = function (attributeName, oldValue, newValue) { if (!this.attributes[attributeName] || this.attributes[attributeName].ignoreMutation) { - return; + return } - // Let the changed attribute handle its own mutation; - return this.attributes[attributeName].handleMutation(oldValue, newValue); - }; + // Let the changed attribute handle its own mutation + return this.attributes[attributeName].handleMutation(oldValue, newValue) + } - WebViewImpl.prototype.handleBrowserPluginAttributeMutation = function(attributeName, oldValue, newValue) { + WebViewImpl.prototype.handleBrowserPluginAttributeMutation = function (attributeName, oldValue, newValue) { if (attributeName === webViewConstants.ATTRIBUTE_INTERNALINSTANCEID && !oldValue && !!newValue) { - this.browserPluginNode.removeAttribute(webViewConstants.ATTRIBUTE_INTERNALINSTANCEID); - this.internalInstanceId = parseInt(newValue); + this.browserPluginNode.removeAttribute(webViewConstants.ATTRIBUTE_INTERNALINSTANCEID) + this.internalInstanceId = parseInt(newValue) // Track when the element resizes using the element resize callback. - webFrame.registerElementResizeCallback(this.internalInstanceId, this.onElementResize.bind(this)); + webFrame.registerElementResizeCallback(this.internalInstanceId, this.onElementResize.bind(this)) if (!this.guestInstanceId) { - return; + return } - return guestViewInternal.attachGuest(this.internalInstanceId, this.guestInstanceId, this.buildParams()); + return guestViewInternal.attachGuest(this.internalInstanceId, this.guestInstanceId, this.buildParams()) } - }; + } - WebViewImpl.prototype.onSizeChanged = function(webViewEvent) { - var maxHeight, maxWidth, minHeight, minWidth, newHeight, newWidth, node, width; - newWidth = webViewEvent.newWidth; - newHeight = webViewEvent.newHeight; - node = this.webviewNode; - width = node.offsetWidth; + WebViewImpl.prototype.onSizeChanged = function (webViewEvent) { + var maxHeight, maxWidth, minHeight, minWidth, newHeight, newWidth, node, width + newWidth = webViewEvent.newWidth + newHeight = webViewEvent.newHeight + node = this.webviewNode + width = node.offsetWidth // Check the current bounds to make sure we do not resize // outside of current constraints. - maxWidth = this.attributes[webViewConstants.ATTRIBUTE_MAXWIDTH].getValue() | width; - maxHeight = this.attributes[webViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() | width; - minWidth = this.attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() | width; - minHeight = this.attributes[webViewConstants.ATTRIBUTE_MINHEIGHT].getValue() | width; - minWidth = Math.min(minWidth, maxWidth); - minHeight = Math.min(minHeight, maxHeight); + maxWidth = this.attributes[webViewConstants.ATTRIBUTE_MAXWIDTH].getValue() | width + maxHeight = this.attributes[webViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() | width + minWidth = this.attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() | width + minHeight = this.attributes[webViewConstants.ATTRIBUTE_MINHEIGHT].getValue() | width + minWidth = Math.min(minWidth, maxWidth) + minHeight = Math.min(minHeight, maxHeight) if (!this.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue() || (newWidth >= minWidth && newWidth <= maxWidth && newHeight >= minHeight && newHeight <= maxHeight)) { - node.style.width = newWidth + 'px'; - node.style.height = newHeight + 'px'; + node.style.width = newWidth + 'px' + node.style.height = newHeight + 'px' // Only fire the DOM event if the size of the has actually // changed. - return this.dispatchEvent(webViewEvent); + return this.dispatchEvent(webViewEvent) } - }; + } - WebViewImpl.prototype.onElementResize = function(newSize) { + WebViewImpl.prototype.onElementResize = function (newSize) { // Dispatch the 'resize' event. - var resizeEvent; + var resizeEvent resizeEvent = new Event('resize', { bubbles: true - }); - resizeEvent.newWidth = newSize.width; - resizeEvent.newHeight = newSize.height; - this.dispatchEvent(resizeEvent); + }) + resizeEvent.newWidth = newSize.width + resizeEvent.newHeight = newSize.height + this.dispatchEvent(resizeEvent) if (this.guestInstanceId) { return guestViewInternal.setSize(this.guestInstanceId, { normal: newSize - }); + }) } - }; + } - WebViewImpl.prototype.createGuest = function() { + WebViewImpl.prototype.createGuest = function () { return guestViewInternal.createGuest(this.buildParams(), (event, guestInstanceId) => { - this.attachWindow(guestInstanceId); - }); - }; + this.attachWindow(guestInstanceId) + }) + } - WebViewImpl.prototype.dispatchEvent = function(webViewEvent) { - return this.webviewNode.dispatchEvent(webViewEvent); - }; + WebViewImpl.prototype.dispatchEvent = function (webViewEvent) { + return this.webviewNode.dispatchEvent(webViewEvent) + } // Adds an 'on' property on the webview, which can be used to set/unset // an event handler. - WebViewImpl.prototype.setupEventProperty = function(eventName) { - var propertyName; - propertyName = 'on' + eventName.toLowerCase(); + WebViewImpl.prototype.setupEventProperty = function (eventName) { + var propertyName + propertyName = 'on' + eventName.toLowerCase() return Object.defineProperty(this.webviewNode, propertyName, { get: () => { - return this.on[propertyName]; + return this.on[propertyName] }, set: (value) => { if (this.on[propertyName]) { - this.webviewNode.removeEventListener(eventName, this.on[propertyName]); + this.webviewNode.removeEventListener(eventName, this.on[propertyName]) } - this.on[propertyName] = value; + this.on[propertyName] = value if (value) { - return this.webviewNode.addEventListener(eventName, value); + return this.webviewNode.addEventListener(eventName, value) } }, enumerable: true - }); - }; + }) + } // Updates state upon loadcommit. - WebViewImpl.prototype.onLoadCommit = function(webViewEvent) { - var newValue, oldValue; - oldValue = this.webviewNode.getAttribute(webViewConstants.ATTRIBUTE_SRC); - newValue = webViewEvent.url; + WebViewImpl.prototype.onLoadCommit = function (webViewEvent) { + var newValue, oldValue + oldValue = this.webviewNode.getAttribute(webViewConstants.ATTRIBUTE_SRC) + newValue = webViewEvent.url if (webViewEvent.isMainFrame && (oldValue !== newValue)) { - // Touching the src attribute triggers a navigation. To avoid // triggering a page reload on every guest-initiated navigation, // we do not handle this mutation. - return this.attributes[webViewConstants.ATTRIBUTE_SRC].setValueIgnoreMutation(newValue); + return this.attributes[webViewConstants.ATTRIBUTE_SRC].setValueIgnoreMutation(newValue) } - }; + } - WebViewImpl.prototype.onAttach = function(storagePartitionId) { - return this.attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue(storagePartitionId); - }; + WebViewImpl.prototype.onAttach = function (storagePartitionId) { + return this.attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue(storagePartitionId) + } - WebViewImpl.prototype.buildParams = function() { - var attribute, attributeName, css, elementRect, params, ref1; + WebViewImpl.prototype.buildParams = function () { + var attribute, attributeName, css, elementRect, params, ref1 params = { instanceId: this.viewInstanceId, userAgentOverride: this.userAgentOverride - }; - ref1 = this.attributes; + } + ref1 = this.attributes for (attributeName in ref1) { - if (!hasProp.call(ref1, attributeName)) continue; - attribute = ref1[attributeName]; - params[attributeName] = attribute.getValue(); + if (!hasProp.call(ref1, attributeName)) continue + attribute = ref1[attributeName] + params[attributeName] = attribute.getValue() } // When the WebView is not participating in layout (display:none) @@ -241,96 +239,95 @@ var WebViewImpl = (function() { // However, in the case where the WebView has a fixed size we can // use that value to initially size the guest so as to avoid a relayout of // the on display:block. - css = window.getComputedStyle(this.webviewNode, null); - elementRect = this.webviewNode.getBoundingClientRect(); - params.elementWidth = parseInt(elementRect.width) || parseInt(css.getPropertyValue('width')); - params.elementHeight = parseInt(elementRect.height) || parseInt(css.getPropertyValue('height')); - return params; - }; + css = window.getComputedStyle(this.webviewNode, null) + elementRect = this.webviewNode.getBoundingClientRect() + params.elementWidth = parseInt(elementRect.width) || parseInt(css.getPropertyValue('width')) + params.elementHeight = parseInt(elementRect.height) || parseInt(css.getPropertyValue('height')) + return params + } - WebViewImpl.prototype.attachWindow = function(guestInstanceId) { - this.guestInstanceId = guestInstanceId; - this.webContents = remote.getGuestWebContents(this.guestInstanceId); + WebViewImpl.prototype.attachWindow = function (guestInstanceId) { + this.guestInstanceId = guestInstanceId + this.webContents = remote.getGuestWebContents(this.guestInstanceId) if (!this.internalInstanceId) { - return true; + return true } - return guestViewInternal.attachGuest(this.internalInstanceId, this.guestInstanceId, this.buildParams()); - }; + return guestViewInternal.attachGuest(this.internalInstanceId, this.guestInstanceId, this.buildParams()) + } - return WebViewImpl; - -})(); + return WebViewImpl +})() // Registers browser plugin custom element. -var registerBrowserPluginElement = function() { - var proto; - proto = Object.create(HTMLObjectElement.prototype); - proto.createdCallback = function() { - this.setAttribute('type', 'application/browser-plugin'); - this.setAttribute('id', 'browser-plugin-' + getNextId()); +var registerBrowserPluginElement = function () { + var proto + proto = Object.create(HTMLObjectElement.prototype) + proto.createdCallback = function () { + this.setAttribute('type', 'application/browser-plugin') + this.setAttribute('id', 'browser-plugin-' + getNextId()) // The node fills in the container. - return this.style.flex = '1 1 auto'; - }; - proto.attributeChangedCallback = function(name, oldValue, newValue) { - var internal; - internal = v8Util.getHiddenValue(this, 'internal'); + return this.style.flex = '1 1 auto' + } + proto.attributeChangedCallback = function (name, oldValue, newValue) { + var internal + internal = v8Util.getHiddenValue(this, 'internal') if (!internal) { - return; + return } - return internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue); - }; - proto.attachedCallback = function() { + return internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue) + } + proto.attachedCallback = function () { // Load the plugin immediately. - return this.nonExistentAttribute; - }; + return this.nonExistentAttribute + } WebViewImpl.BrowserPlugin = webFrame.registerEmbedderCustomElement('browserplugin', { - "extends": 'object', + 'extends': 'object', prototype: proto - }); - delete proto.createdCallback; - delete proto.attachedCallback; - delete proto.detachedCallback; - return delete proto.attributeChangedCallback; -}; + }) + delete proto.createdCallback + delete proto.attachedCallback + delete proto.detachedCallback + return delete proto.attributeChangedCallback +} // Registers custom element. -var registerWebViewElement = function() { - var createBlockHandler, createNonBlockHandler, i, j, len, len1, m, methods, nonblockMethods, proto; - proto = Object.create(HTMLObjectElement.prototype); - proto.createdCallback = function() { - return new WebViewImpl(this); - }; - proto.attributeChangedCallback = function(name, oldValue, newValue) { - var internal; - internal = v8Util.getHiddenValue(this, 'internal'); +var registerWebViewElement = function () { + var createBlockHandler, createNonBlockHandler, i, j, len, len1, m, methods, nonblockMethods, proto + proto = Object.create(HTMLObjectElement.prototype) + proto.createdCallback = function () { + return new WebViewImpl(this) + } + proto.attributeChangedCallback = function (name, oldValue, newValue) { + var internal + internal = v8Util.getHiddenValue(this, 'internal') if (!internal) { - return; + return } - return internal.handleWebviewAttributeMutation(name, oldValue, newValue); - }; - proto.detachedCallback = function() { - var internal; - internal = v8Util.getHiddenValue(this, 'internal'); + return internal.handleWebviewAttributeMutation(name, oldValue, newValue) + } + proto.detachedCallback = function () { + var internal + internal = v8Util.getHiddenValue(this, 'internal') if (!internal) { - return; + return } - guestViewInternal.deregisterEvents(internal.viewInstanceId); - internal.elementAttached = false; - return internal.reset(); - }; - proto.attachedCallback = function() { - var internal; - internal = v8Util.getHiddenValue(this, 'internal'); + guestViewInternal.deregisterEvents(internal.viewInstanceId) + internal.elementAttached = false + return internal.reset() + } + proto.attachedCallback = function () { + var internal + internal = v8Util.getHiddenValue(this, 'internal') if (!internal) { - return; + return } if (!internal.elementAttached) { - guestViewInternal.registerEvents(internal, internal.viewInstanceId); - internal.elementAttached = true; - return internal.attributes[webViewConstants.ATTRIBUTE_SRC].parse(); + guestViewInternal.registerEvents(internal, internal.viewInstanceId) + internal.elementAttached = true + return internal.attributes[webViewConstants.ATTRIBUTE_SRC].parse() } - }; + } // Public-facing API methods. methods = [ @@ -378,7 +375,7 @@ var registerWebViewElement = function() { 'inspectServiceWorker', 'print', 'printToPDF', - ]; + ] nonblockMethods = [ 'insertCSS', 'insertText', @@ -387,79 +384,79 @@ var registerWebViewElement = function() { 'setZoomFactor', 'setZoomLevel', 'setZoomLevelLimits', - ]; + ] // Forward proto.foo* method calls to WebViewImpl.foo*. - createBlockHandler = function(m) { - return function(...args) { - const internal = v8Util.getHiddenValue(this, 'internal'); + createBlockHandler = function (m) { + return function (...args) { + const internal = v8Util.getHiddenValue(this, 'internal') if (internal.webContents) { - return internal.webContents[m].apply(internal.webContents, args); + return internal.webContents[m].apply(internal.webContents, args) } else { - throw new Error(`Cannot call ${m} because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.`); + throw new Error(`Cannot call ${m} because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.`) } - }; - }; - for (i = 0, len = methods.length; i < len; i++) { - m = methods[i]; - proto[m] = createBlockHandler(m); + } + } + for (i = 0, len = methods.length; i < len; i++) { + m = methods[i] + proto[m] = createBlockHandler(m) + } + createNonBlockHandler = function (m) { + return function (...args) { + const internal = v8Util.getHiddenValue(this, 'internal') + return ipcRenderer.send.apply(ipcRenderer, ['ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', null, internal.guestInstanceId, m].concat(args)) + } } - createNonBlockHandler = function(m) { - return function(...args) { - const internal = v8Util.getHiddenValue(this, 'internal'); - return ipcRenderer.send.apply(ipcRenderer, ['ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', null, internal.guestInstanceId, m].concat(args)); - }; - }; for (j = 0, len1 = nonblockMethods.length; j < len1; j++) { - m = nonblockMethods[j]; - proto[m] = createNonBlockHandler(m); + m = nonblockMethods[j] + proto[m] = createNonBlockHandler(m) } - proto.executeJavaScript = function(code, hasUserGesture, callback) { - var internal = v8Util.getHiddenValue(this, 'internal'); - if (typeof hasUserGesture === "function") { - callback = hasUserGesture; - hasUserGesture = false; + proto.executeJavaScript = function (code, hasUserGesture, callback) { + var internal = v8Util.getHiddenValue(this, 'internal') + if (typeof hasUserGesture === 'function') { + callback = hasUserGesture + hasUserGesture = false } - let requestId = getNextId(); - ipcRenderer.send('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', requestId, internal.guestInstanceId, "executeJavaScript", code, hasUserGesture); - ipcRenderer.once(`ATOM_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, function(event, result) { + let requestId = getNextId() + ipcRenderer.send('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', requestId, internal.guestInstanceId, 'executeJavaScript', code, hasUserGesture) + ipcRenderer.once(`ATOM_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, function (event, result) { if (callback) - callback(result); - }); - }; + callback(result) + }) + } // WebContents associated with this webview. - proto.getWebContents = function() { - var internal = v8Util.getHiddenValue(this, 'internal'); - return internal.webContents; - }; + proto.getWebContents = function () { + var internal = v8Util.getHiddenValue(this, 'internal') + return internal.webContents + } // Deprecated. - deprecate.rename(proto, 'getUrl', 'getURL'); + deprecate.rename(proto, 'getUrl', 'getURL') window.WebView = webFrame.registerEmbedderCustomElement('webview', { prototype: proto - }); + }) // Delete the callbacks so developers cannot call them and produce unexpected // behavior. - delete proto.createdCallback; - delete proto.attachedCallback; - delete proto.detachedCallback; - return delete proto.attributeChangedCallback; -}; + delete proto.createdCallback + delete proto.attachedCallback + delete proto.detachedCallback + return delete proto.attributeChangedCallback +} -var useCapture = true; +var useCapture = true -var listener = function(event) { +var listener = function (event) { if (document.readyState === 'loading') { - return; + return } - registerBrowserPluginElement(); - registerWebViewElement(); - return window.removeEventListener(event.type, listener, useCapture); -}; + registerBrowserPluginElement() + registerWebViewElement() + return window.removeEventListener(event.type, listener, useCapture) +} -window.addEventListener('readystatechange', listener, true); +window.addEventListener('readystatechange', listener, true) -module.exports = WebViewImpl; +module.exports = WebViewImpl diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 1b12f6f733c..2a5417b9c50 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -1,135 +1,135 @@ -const assert = require('assert'); -const ChildProcess = require('child_process'); -const path = require('path'); -const remote = require('electron').remote; +const assert = require('assert') +const ChildProcess = require('child_process') +const path = require('path') +const remote = require('electron').remote -const app = remote.require('electron').app; -const BrowserWindow = remote.require('electron').BrowserWindow; +const app = remote.require('electron').app +const BrowserWindow = remote.require('electron').BrowserWindow -describe('electron module', function() { - it('allows old style require by default', function() { - require('shell'); - }); +describe('electron module', function () { + it('allows old style require by default', function () { + require('shell') + }) - it('can prevent exposing internal modules to require', function(done) { - const electron = require('electron'); - const clipboard = require('clipboard'); - assert.equal(typeof clipboard, 'object'); - electron.hideInternalModules(); + it('can prevent exposing internal modules to require', function (done) { + const electron = require('electron') + const clipboard = require('clipboard') + assert.equal(typeof clipboard, 'object') + electron.hideInternalModules() try { - require('clipboard'); + require('clipboard') } catch(err) { - assert.equal(err.message, 'Cannot find module \'clipboard\''); - done(); + assert.equal(err.message, "Cannot find module 'clipboard'") + done() } - }); -}); + }) +}) -describe('app module', function() { - describe('app.getVersion()', function() { - it('returns the version field of package.json', function() { - assert.equal(app.getVersion(), '0.1.0'); - }); - }); +describe('app module', function () { + describe('app.getVersion()', function () { + it('returns the version field of package.json', function () { + assert.equal(app.getVersion(), '0.1.0') + }) + }) - describe('app.setVersion(version)', function() { - it('overrides the version', function() { - assert.equal(app.getVersion(), '0.1.0'); - app.setVersion('test-version'); - assert.equal(app.getVersion(), 'test-version'); - app.setVersion('0.1.0'); - }); - }); + describe('app.setVersion(version)', function () { + it('overrides the version', function () { + assert.equal(app.getVersion(), '0.1.0') + app.setVersion('test-version') + assert.equal(app.getVersion(), 'test-version') + app.setVersion('0.1.0') + }) + }) - describe('app.getName()', function() { - it('returns the name field of package.json', function() { - assert.equal(app.getName(), 'Electron Test'); - }); - }); + describe('app.getName()', function () { + it('returns the name field of package.json', function () { + assert.equal(app.getName(), 'Electron Test') + }) + }) - describe('app.setName(name)', function() { - it('overrides the name', function() { - assert.equal(app.getName(), 'Electron Test'); - app.setName('test-name'); - assert.equal(app.getName(), 'test-name'); - app.setName('Electron Test'); - }); - }); + describe('app.setName(name)', function () { + it('overrides the name', function () { + assert.equal(app.getName(), 'Electron Test') + app.setName('test-name') + assert.equal(app.getName(), 'test-name') + app.setName('Electron Test') + }) + }) - describe('app.getLocale()', function() { - it('should not be empty', function() { - assert.notEqual(app.getLocale(), ''); - }); - }); + describe('app.getLocale()', function () { + it('should not be empty', function () { + assert.notEqual(app.getLocale(), '') + }) + }) - describe('app.exit(exitCode)', function() { - var appProcess = null; + describe('app.exit(exitCode)', function () { + var appProcess = null - afterEach(function() { - appProcess != null ? appProcess.kill() : void 0; - }); + afterEach(function () { + appProcess != null ? appProcess.kill() : void 0 + }) - it('emits a process exit event with the code', function(done) { - var appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app'); - var electronPath = remote.getGlobal('process').execPath; - var output = ''; - appProcess = ChildProcess.spawn(electronPath, [appPath]); - appProcess.stdout.on('data', function(data) { - output += data; - }); - appProcess.on('close', function(code) { + it('emits a process exit event with the code', function (done) { + var appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app') + var electronPath = remote.getGlobal('process').execPath + var output = '' + appProcess = ChildProcess.spawn(electronPath, [appPath]) + appProcess.stdout.on('data', function (data) { + output += data + }) + appProcess.on('close', function (code) { if (process.platform !== 'win32') { - assert.notEqual(output.indexOf('Exit event with code: 123'), -1); + assert.notEqual(output.indexOf('Exit event with code: 123'), -1) } - assert.equal(code, 123); - done(); - }); - }); - }); + assert.equal(code, 123) + done() + }) + }) + }) - describe('BrowserWindow events', function() { - var w = null; + describe('BrowserWindow events', function () { + var w = null - afterEach(function() { + afterEach(function () { if (w != null) { - w.destroy(); + w.destroy() } - w = null; - }); + w = null + }) - it('should emit browser-window-focus event when window is focused', function(done) { - app.once('browser-window-focus', function(e, window) { - assert.equal(w.id, window.id); - done(); - }); + it('should emit browser-window-focus event when window is focused', function (done) { + app.once('browser-window-focus', function (e, window) { + assert.equal(w.id, window.id) + done() + }) w = new BrowserWindow({ show: false - }); - w.emit('focus'); - }); + }) + w.emit('focus') + }) - it('should emit browser-window-blur event when window is blured', function(done) { - app.once('browser-window-blur', function(e, window) { - assert.equal(w.id, window.id); - done(); - }); + it('should emit browser-window-blur event when window is blured', function (done) { + app.once('browser-window-blur', function (e, window) { + assert.equal(w.id, window.id) + done() + }) w = new BrowserWindow({ show: false - }); - w.emit('blur'); - }); + }) + w.emit('blur') + }) - it('should emit browser-window-created event when window is created', function(done) { - app.once('browser-window-created', function(e, window) { - setImmediate(function() { - assert.equal(w.id, window.id); - done(); - }); - }); + it('should emit browser-window-created event when window is created', function (done) { + app.once('browser-window-created', function (e, window) { + setImmediate(function () { + assert.equal(w.id, window.id) + done() + }) + }) w = new BrowserWindow({ show: false - }); - w.emit('blur'); - }); - }); -}); + }) + w.emit('blur') + }) + }) +}) From bd9b0b8ed3e9483deb0fee528737d4af189f7201 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 25 Mar 2016 12:57:49 -0700 Subject: [PATCH 605/688] wrap conditional, because return can only be used in a function --- spec/api-auto-updater-spec.js | 65 +++++++++++++++++------------------ 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/spec/api-auto-updater-spec.js b/spec/api-auto-updater-spec.js index efd3afe3882..6335f335943 100644 --- a/spec/api-auto-updater-spec.js +++ b/spec/api-auto-updater-spec.js @@ -1,38 +1,37 @@ -const assert = require('assert'); -const autoUpdater = require('electron').remote.autoUpdater; -const ipcRenderer = require('electron').ipcRenderer; +const assert = require('assert') +const autoUpdater = require('electron').remote.autoUpdater +const ipcRenderer = require('electron').ipcRenderer // Skip autoUpdater tests in MAS build. -if (process.mas) - return; +if (!process.mas) { + describe('autoUpdater module', function () { + describe('checkForUpdates', function () { + it('emits an error on Windows when called the feed URL is not set', function (done) { + if (process.platform !== 'win32') { + return done() + } -describe('autoUpdater module', function() { - describe('checkForUpdates', function() { - it('emits an error on Windows when called the feed URL is not set', function (done) { - if (process.platform !== 'win32') { - return done(); - } + ipcRenderer.once('auto-updater-error', function (event, message) { + assert.equal(message, 'Update URL is not set') + done() + }) + autoUpdater.setFeedURL('') + autoUpdater.checkForUpdates() + }) + }) - ipcRenderer.once('auto-updater-error', function(event, message) { - assert.equal(message, 'Update URL is not set'); - done(); - }); - autoUpdater.setFeedURL(''); - autoUpdater.checkForUpdates(); - }); - }); + describe('setFeedURL', function () { + it('emits an error on Mac OS X when the application is unsigned', function (done) { + if (process.platform !== 'darwin') { + return done() + } - describe('setFeedURL', function() { - it('emits an error on Mac OS X when the application is unsigned', function (done) { - if (process.platform !== 'darwin') { - return done(); - } - - ipcRenderer.once('auto-updater-error', function(event, message) { - assert.equal(message, 'Could not get code signature for running application'); - done(); - }); - autoUpdater.setFeedURL(''); - }); - }); -}); + ipcRenderer.once('auto-updater-error', function (event, message) { + assert.equal(message, 'Could not get code signature for running application') + done() + }) + autoUpdater.setFeedURL('') + }) + }) + }) +} From 06b556c34c5d01db15279c1b7a94c82225e8dace Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 25 Mar 2016 12:58:04 -0700 Subject: [PATCH 606/688] ignore more files that are confusing standard-format --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index ced3ab8ae99..9f22ef2ae07 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ }, "standard": { "ignore": [ - "/lib/browser/rpc-server.js" + "/lib/browser/rpc-server.js", + "/lib/common/asar.js" ] }, "private": true, From f35f3622721d917716f3de5527bb170fb99b17c4 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 25 Mar 2016 13:03:49 -0700 Subject: [PATCH 607/688] autoformat more files --- spec/api-browser-window-spec.js | 1194 +++++++------- spec/api-clipboard-spec.js | 104 +- spec/api-crash-reporter-spec.js | 130 +- spec/api-debugger-spec.js | 180 +-- spec/api-deprecations-spec.js | 40 +- spec/api-desktop-capturer-spec.js | 42 +- spec/api-ipc-spec.js | 336 ++-- spec/api-menu-spec.js | 302 ++-- spec/api-native-image-spec.js | 68 +- spec/api-protocol-spec.js | 1202 +++++++-------- spec/api-screen-spec.js | 38 +- spec/api-session-spec.js | 368 ++--- spec/api-web-frame-spec.js | 36 +- spec/api-web-request-spec.js | 579 ++++--- spec/asar-spec.js | 1368 ++++++++--------- spec/chromium-spec.js | 682 ++++---- spec/fixtures/api/quit-app/main.js | 12 +- spec/fixtures/module/asar.js | 8 +- spec/fixtures/module/call.js | 12 +- spec/fixtures/module/class.js | 20 +- spec/fixtures/module/create_socket.js | 8 +- spec/fixtures/module/fork_ping.js | 24 +- spec/fixtures/module/function.js | 2 +- spec/fixtures/module/id.js | 2 +- spec/fixtures/module/locale-compare.js | 4 +- spec/fixtures/module/original-fs.js | 4 +- spec/fixtures/module/ping.js | 8 +- spec/fixtures/module/preload-ipc.js | 8 +- spec/fixtures/module/preload-node-off.js | 8 +- spec/fixtures/module/preload.js | 2 +- spec/fixtures/module/print_name.js | 12 +- spec/fixtures/module/process_args.js | 8 +- spec/fixtures/module/promise.js | 6 +- spec/fixtures/module/property.js | 2 +- spec/fixtures/module/runas.js | 10 +- spec/fixtures/module/send-later.js | 8 +- spec/fixtures/module/set-global.js | 2 +- spec/fixtures/module/set-immediate.js | 20 +- .../pages/service-worker/service-worker.js | 12 +- spec/fixtures/workers/shared_worker.js | 14 +- spec/fixtures/workers/worker.js | 6 +- spec/modules-spec.js | 76 +- spec/node-spec.js | 374 ++--- spec/static/main.js | 172 +-- spec/webview-spec.js | 1300 ++++++++-------- tools/dump-version-info.js | 84 +- tools/win/register_msdia80_dll.js | 20 +- 47 files changed, 4458 insertions(+), 4459 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index beb84a8d748..77e8b004bfe 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -1,782 +1,782 @@ -'use strict'; +'use strict' -const assert = require('assert'); -const fs = require('fs'); -const path = require('path'); -const os = require('os'); +const assert = require('assert') +const fs = require('fs') +const path = require('path') +const os = require('os') -const remote = require('electron').remote; -const screen = require('electron').screen; +const remote = require('electron').remote +const screen = require('electron').screen -const app = remote.require('electron').app; -const ipcMain = remote.require('electron').ipcMain; -const ipcRenderer = require('electron').ipcRenderer; -const BrowserWindow = remote.require('electron').BrowserWindow; +const app = remote.require('electron').app +const ipcMain = remote.require('electron').ipcMain +const ipcRenderer = require('electron').ipcRenderer +const BrowserWindow = remote.require('electron').BrowserWindow -const isCI = remote.getGlobal('isCi'); +const isCI = remote.getGlobal('isCi') -describe('browser-window module', function() { - var fixtures = path.resolve(__dirname, 'fixtures'); - var w = null; +describe('browser-window module', function () { + var fixtures = path.resolve(__dirname, 'fixtures') + var w = null - beforeEach(function() { + beforeEach(function () { if (w != null) { - w.destroy(); + w.destroy() } w = new BrowserWindow({ show: false, width: 400, height: 400 - }); - }); + }) + }) - afterEach(function() { + afterEach(function () { if (w != null) { - w.destroy(); + w.destroy() } - w = null; - }); + w = null + }) - describe('BrowserWindow.close()', function() { - it('should emit unload handler', function(done) { - w.webContents.on('did-finish-load', function() { - w.close(); - }); - w.on('closed', function() { - var test = path.join(fixtures, 'api', 'unload'); - var content = fs.readFileSync(test); - fs.unlinkSync(test); - assert.equal(String(content), 'unload'); - done(); - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'unload.html')); - }); + describe('BrowserWindow.close()', function () { + it('should emit unload handler', function (done) { + w.webContents.on('did-finish-load', function () { + w.close() + }) + w.on('closed', function () { + var test = path.join(fixtures, 'api', 'unload') + var content = fs.readFileSync(test) + fs.unlinkSync(test) + assert.equal(String(content), 'unload') + done() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'unload.html')) + }) - it('should emit beforeunload handler', function(done) { - w.on('onbeforeunload', function() { - done(); - }); - w.webContents.on('did-finish-load', function() { - w.close(); - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'beforeunload-false.html')); - }); - }); + it('should emit beforeunload handler', function (done) { + w.on('onbeforeunload', function () { + done() + }) + w.webContents.on('did-finish-load', function () { + w.close() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'beforeunload-false.html')) + }) + }) - describe('window.close()', function() { - it('should emit unload handler', function(done) { - w.on('closed', function() { - var test = path.join(fixtures, 'api', 'close'); - var content = fs.readFileSync(test); - fs.unlinkSync(test); - assert.equal(String(content), 'close'); - done(); - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'close.html')); - }); + describe('window.close()', function () { + it('should emit unload handler', function (done) { + w.on('closed', function () { + var test = path.join(fixtures, 'api', 'close') + var content = fs.readFileSync(test) + fs.unlinkSync(test) + assert.equal(String(content), 'close') + done() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'close.html')) + }) - it('should emit beforeunload handler', function(done) { - w.on('onbeforeunload', function() { - done(); - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html')); - }); - }); + it('should emit beforeunload handler', function (done) { + w.on('onbeforeunload', function () { + done() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html')) + }) + }) - describe('BrowserWindow.destroy()', function() { - it('prevents users to access methods of webContents', function() { - var webContents = w.webContents; - w.destroy(); - assert.throws((function() { - webContents.getId(); - }), /Object has been destroyed/); - }); - }); + describe('BrowserWindow.destroy()', function () { + it('prevents users to access methods of webContents', function () { + var webContents = w.webContents + w.destroy() + assert.throws((function () { + webContents.getId() + }), /Object has been destroyed/) + }) + }) - describe('BrowserWindow.loadURL(url)', function() { - it('should emit did-start-loading event', function(done) { - w.webContents.on('did-start-loading', function() { - done(); - }); - w.loadURL('about:blank'); - }); + describe('BrowserWindow.loadURL(url)', function () { + it('should emit did-start-loading event', function (done) { + w.webContents.on('did-start-loading', function () { + done() + }) + w.loadURL('about:blank') + }) - it('should emit did-fail-load event for files that do not exist', function(done) { - w.webContents.on('did-fail-load', function(event, code) { - assert.equal(code, -6); - done(); - }); - w.loadURL('file://a.txt'); - }); + it('should emit did-fail-load event for files that do not exist', function (done) { + w.webContents.on('did-fail-load', function (event, code) { + assert.equal(code, -6) + done() + }) + w.loadURL('file://a.txt') + }) - it('should emit did-fail-load event for invalid URL', function(done) { - w.webContents.on('did-fail-load', function(event, code, desc) { - assert.equal(desc, 'ERR_INVALID_URL'); - assert.equal(code, -300); - done(); - }); - w.loadURL('http://example:port'); - }); - }); + it('should emit did-fail-load event for invalid URL', function (done) { + w.webContents.on('did-fail-load', function (event, code, desc) { + assert.equal(desc, 'ERR_INVALID_URL') + assert.equal(code, -300) + done() + }) + w.loadURL('http://example:port') + }) + }) - describe('BrowserWindow.show()', function() { + describe('BrowserWindow.show()', function () { if (isCI) { - return; + return } - it('should focus on window', function() { - w.show(); - assert(w.isFocused()); - }); + it('should focus on window', function () { + w.show() + assert(w.isFocused()) + }) - it('should make the window visible', function() { - w.show(); - assert(w.isVisible()); - }); + it('should make the window visible', function () { + w.show() + assert(w.isVisible()) + }) - it('emits when window is shown', function(done) { - this.timeout(10000); - w.once('show', function() { - assert.equal(w.isVisible(), true); - done(); - }); - w.show(); - }); - }); + it('emits when window is shown', function (done) { + this.timeout(10000) + w.once('show', function () { + assert.equal(w.isVisible(), true) + done() + }) + w.show() + }) + }) - describe('BrowserWindow.hide()', function() { + describe('BrowserWindow.hide()', function () { if (isCI) { - return; + return } - it('should defocus on window', function() { - w.hide(); - assert(!w.isFocused()); - }); + it('should defocus on window', function () { + w.hide() + assert(!w.isFocused()) + }) - it('should make the window not visible', function() { - w.show(); - w.hide(); - assert(!w.isVisible()); - }); + it('should make the window not visible', function () { + w.show() + w.hide() + assert(!w.isVisible()) + }) - it('emits when window is hidden', function(done) { - this.timeout(10000); - w.show(); - w.once('hide', function() { - assert.equal(w.isVisible(), false); - done(); - }); - w.hide(); - }); - }); + it('emits when window is hidden', function (done) { + this.timeout(10000) + w.show() + w.once('hide', function () { + assert.equal(w.isVisible(), false) + done() + }) + w.hide() + }) + }) - describe('BrowserWindow.showInactive()', function() { - it('should not focus on window', function() { - w.showInactive(); - assert(!w.isFocused()); - }); - }); + describe('BrowserWindow.showInactive()', function () { + it('should not focus on window', function () { + w.showInactive() + assert(!w.isFocused()) + }) + }) - describe('BrowserWindow.focus()', function() { - it('does not make the window become visible', function() { - assert.equal(w.isVisible(), false); - w.focus(); - assert.equal(w.isVisible(), false); - }); - }); + describe('BrowserWindow.focus()', function () { + it('does not make the window become visible', function () { + assert.equal(w.isVisible(), false) + w.focus() + assert.equal(w.isVisible(), false) + }) + }) - describe('BrowserWindow.blur()', function() { - it('removes focus from window', function() { - w.blur(); - assert(!w.isFocused()); - }); - }); + describe('BrowserWindow.blur()', function () { + it('removes focus from window', function () { + w.blur() + assert(!w.isFocused()) + }) + }) - describe('BrowserWindow.capturePage(rect, callback)', function() { - it('calls the callback with a Buffer', function(done) { + describe('BrowserWindow.capturePage(rect, callback)', function () { + it('calls the callback with a Buffer', function (done) { w.capturePage({ x: 0, y: 0, width: 100, height: 100 - }, function(image) { - assert.equal(image.isEmpty(), true); - done(); - }); - }); - }); + }, function (image) { + assert.equal(image.isEmpty(), true) + done() + }) + }) + }) - describe('BrowserWindow.setSize(width, height)', function() { - it('sets the window size', function(done) { - var size = [300, 400]; - w.once('resize', function() { - var newSize = w.getSize(); - assert.equal(newSize[0], size[0]); - assert.equal(newSize[1], size[1]); - done(); - }); - w.setSize(size[0], size[1]); - }); - }); + describe('BrowserWindow.setSize(width, height)', function () { + it('sets the window size', function (done) { + var size = [300, 400] + w.once('resize', function () { + var newSize = w.getSize() + assert.equal(newSize[0], size[0]) + assert.equal(newSize[1], size[1]) + done() + }) + w.setSize(size[0], size[1]) + }) + }) - describe('BrowserWindow.setPosition(x, y)', function() { - it('sets the window position', function(done) { - var pos = [10, 10]; - w.once('move', function() { - var newPos = w.getPosition(); - assert.equal(newPos[0], pos[0]); - assert.equal(newPos[1], pos[1]); - done(); - }); - w.setPosition(pos[0], pos[1]); - }); - }); + describe('BrowserWindow.setPosition(x, y)', function () { + it('sets the window position', function (done) { + var pos = [10, 10] + w.once('move', function () { + var newPos = w.getPosition() + assert.equal(newPos[0], pos[0]) + assert.equal(newPos[1], pos[1]) + done() + }) + w.setPosition(pos[0], pos[1]) + }) + }) - describe('BrowserWindow.setContentSize(width, height)', function() { - it('sets the content size', function() { - var size = [400, 400]; - w.setContentSize(size[0], size[1]); - var after = w.getContentSize(); - assert.equal(after[0], size[0]); - assert.equal(after[1], size[1]); - }); + describe('BrowserWindow.setContentSize(width, height)', function () { + it('sets the content size', function () { + var size = [400, 400] + w.setContentSize(size[0], size[1]) + var after = w.getContentSize() + assert.equal(after[0], size[0]) + assert.equal(after[1], size[1]) + }) - it('works for framless window', function() { - w.destroy(); + it('works for framless window', function () { + w.destroy() w = new BrowserWindow({ show: false, frame: false, width: 400, height: 400 - }); - var size = [400, 400]; - w.setContentSize(size[0], size[1]); - var after = w.getContentSize(); - assert.equal(after[0], size[0]); - assert.equal(after[1], size[1]); - }); - }); + }) + var size = [400, 400] + w.setContentSize(size[0], size[1]) + var after = w.getContentSize() + assert.equal(after[0], size[0]) + assert.equal(after[1], size[1]) + }) + }) - describe('BrowserWindow.fromId(id)', function() { - it('returns the window with id', function() { - assert.equal(w.id, BrowserWindow.fromId(w.id).id); - }); - }); + describe('BrowserWindow.fromId(id)', function () { + it('returns the window with id', function () { + assert.equal(w.id, BrowserWindow.fromId(w.id).id) + }) + }) - describe('"useContentSize" option', function() { - it('make window created with content size when used', function() { - w.destroy(); + describe('"useContentSize" option', function () { + it('make window created with content size when used', function () { + w.destroy() w = new BrowserWindow({ show: false, width: 400, height: 400, useContentSize: true - }); - var contentSize = w.getContentSize(); - assert.equal(contentSize[0], 400); - assert.equal(contentSize[1], 400); - }); + }) + var contentSize = w.getContentSize() + assert.equal(contentSize[0], 400) + assert.equal(contentSize[1], 400) + }) - it('make window created with window size when not used', function() { - var size = w.getSize(); - assert.equal(size[0], 400); - assert.equal(size[1], 400); - }); + it('make window created with window size when not used', function () { + var size = w.getSize() + assert.equal(size[0], 400) + assert.equal(size[1], 400) + }) - it('works for framless window', function() { - w.destroy(); + it('works for framless window', function () { + w.destroy() w = new BrowserWindow({ show: false, frame: false, width: 400, height: 400, useContentSize: true - }); - var contentSize = w.getContentSize(); - assert.equal(contentSize[0], 400); - assert.equal(contentSize[1], 400); - var size = w.getSize(); - assert.equal(size[0], 400); - assert.equal(size[1], 400); - }); - }); + }) + var contentSize = w.getContentSize() + assert.equal(contentSize[0], 400) + assert.equal(contentSize[1], 400) + var size = w.getSize() + assert.equal(size[0], 400) + assert.equal(size[1], 400) + }) + }) - describe('"title-bar-style" option', function() { + describe('"title-bar-style" option', function () { if (process.platform !== 'darwin') { - return; + return } if (parseInt(os.release().split('.')[0]) < 14) { - return; + return } - it('creates browser window with hidden title bar', function() { - w.destroy(); + it('creates browser window with hidden title bar', function () { + w.destroy() w = new BrowserWindow({ show: false, width: 400, height: 400, titleBarStyle: 'hidden' - }); - var contentSize = w.getContentSize(); - assert.equal(contentSize[1], 400); - }); + }) + var contentSize = w.getContentSize() + assert.equal(contentSize[1], 400) + }) - it('creates browser window with hidden inset title bar', function() { - w.destroy(); + it('creates browser window with hidden inset title bar', function () { + w.destroy() w = new BrowserWindow({ show: false, width: 400, height: 400, titleBarStyle: 'hidden-inset' - }); - var contentSize = w.getContentSize(); - assert.equal(contentSize[1], 400); - }); - }); + }) + var contentSize = w.getContentSize() + assert.equal(contentSize[1], 400) + }) + }) - describe('"enableLargerThanScreen" option', function() { + describe('"enableLargerThanScreen" option', function () { if (process.platform === 'linux') { - return; + return } - beforeEach(function() { - w.destroy(); + beforeEach(function () { + w.destroy() w = new BrowserWindow({ show: true, width: 400, height: 400, enableLargerThanScreen: true - }); - }); + }) + }) - it('can move the window out of screen', function() { - w.setPosition(-10, -10); - var after = w.getPosition(); - assert.equal(after[0], -10); - assert.equal(after[1], -10); - }); + it('can move the window out of screen', function () { + w.setPosition(-10, -10) + var after = w.getPosition() + assert.equal(after[0], -10) + assert.equal(after[1], -10) + }) - it('can set the window larger than screen', function() { - var size = screen.getPrimaryDisplay().size; - size.width += 100; - size.height += 100; - w.setSize(size.width, size.height); - var after = w.getSize(); - assert.equal(after[0], size.width); - assert.equal(after[1], size.height); - }); - }); + it('can set the window larger than screen', function () { + var size = screen.getPrimaryDisplay().size + size.width += 100 + size.height += 100 + w.setSize(size.width, size.height) + var after = w.getSize() + assert.equal(after[0], size.width) + assert.equal(after[1], size.height) + }) + }) - describe('"web-preferences" option', function() { - afterEach(function() { - ipcMain.removeAllListeners('answer'); - }); + describe('"web-preferences" option', function () { + afterEach(function () { + ipcMain.removeAllListeners('answer') + }) - describe('"preload" option', function() { - it('loads the script before other scripts in window', function(done) { - var preload = path.join(fixtures, 'module', 'set-global.js'); - ipcMain.once('answer', function(event, test) { - assert.equal(test, 'preload'); - done(); - }); - w.destroy(); + describe('"preload" option', function () { + it('loads the script before other scripts in window', function (done) { + var preload = path.join(fixtures, 'module', 'set-global.js') + ipcMain.once('answer', function (event, test) { + assert.equal(test, 'preload') + done() + }) + w.destroy() w = new BrowserWindow({ show: false, webPreferences: { preload: preload } - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'preload.html')); - }); - }); + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'preload.html')) + }) + }) - describe('"node-integration" option', function() { - it('disables node integration when specified to false', function(done) { - var preload = path.join(fixtures, 'module', 'send-later.js'); - ipcMain.once('answer', function(event, test) { - assert.equal(test, 'undefined'); - done(); - }); - w.destroy(); + describe('"node-integration" option', function () { + it('disables node integration when specified to false', function (done) { + var preload = path.join(fixtures, 'module', 'send-later.js') + ipcMain.once('answer', function (event, test) { + assert.equal(test, 'undefined') + done() + }) + w.destroy() w = new BrowserWindow({ show: false, webPreferences: { preload: preload, nodeIntegration: false } - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'blank.html')); - }); - }); - }); + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'blank.html')) + }) + }) + }) - describe('beforeunload handler', function() { - it('returning true would not prevent close', function(done) { - w.on('closed', function() { - done(); - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-true.html')); - }); + describe('beforeunload handler', function () { + it('returning true would not prevent close', function (done) { + w.on('closed', function () { + done() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-true.html')) + }) - it('returning non-empty string would not prevent close', function(done) { - w.on('closed', function() { - done(); - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-string.html')); - }); + it('returning non-empty string would not prevent close', function (done) { + w.on('closed', function () { + done() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-string.html')) + }) - it('returning false would prevent close', function(done) { - w.on('onbeforeunload', function() { - done(); - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html')); - }); + it('returning false would prevent close', function (done) { + w.on('onbeforeunload', function () { + done() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-false.html')) + }) - it('returning empty string would prevent close', function(done) { - w.on('onbeforeunload', function() { - done(); - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-empty-string.html')); - }); - }); + it('returning empty string would prevent close', function (done) { + w.on('onbeforeunload', function () { + done() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'close-beforeunload-empty-string.html')) + }) + }) - describe('new-window event', function() { + describe('new-window event', function () { if (isCI && process.platform === 'darwin') { - return; + return } - it('emits when window.open is called', function(done) { - w.webContents.once('new-window', function(e, url, frameName) { - e.preventDefault(); - assert.equal(url, 'http://host/'); - assert.equal(frameName, 'host'); - done(); - }); - w.loadURL("file://" + fixtures + "/pages/window-open.html"); - }); + it('emits when window.open is called', function (done) { + w.webContents.once('new-window', function (e, url, frameName) { + e.preventDefault() + assert.equal(url, 'http://host/') + assert.equal(frameName, 'host') + done() + }) + w.loadURL('file://' + fixtures + '/pages/window-open.html') + }) - it('emits when link with target is called', function(done) { - this.timeout(10000); - w.webContents.once('new-window', function(e, url, frameName) { - e.preventDefault(); - assert.equal(url, 'http://host/'); - assert.equal(frameName, 'target'); - done(); - }); - w.loadURL("file://" + fixtures + "/pages/target-name.html"); - }); - }); + it('emits when link with target is called', function (done) { + this.timeout(10000) + w.webContents.once('new-window', function (e, url, frameName) { + e.preventDefault() + assert.equal(url, 'http://host/') + assert.equal(frameName, 'target') + done() + }) + w.loadURL('file://' + fixtures + '/pages/target-name.html') + }) + }) - describe('maximize event', function() { + describe('maximize event', function () { if (isCI) { - return; + return } - it('emits when window is maximized', function(done) { - this.timeout(10000); - w.once('maximize', function() { - done(); - }); - w.show(); - w.maximize(); - }); - }); + it('emits when window is maximized', function (done) { + this.timeout(10000) + w.once('maximize', function () { + done() + }) + w.show() + w.maximize() + }) + }) - describe('unmaximize event', function() { + describe('unmaximize event', function () { if (isCI) { - return; + return } - it('emits when window is unmaximized', function(done) { - this.timeout(10000); - w.once('unmaximize', function() { - done(); - }); - w.show(); - w.maximize(); - w.unmaximize(); - }); - }); + it('emits when window is unmaximized', function (done) { + this.timeout(10000) + w.once('unmaximize', function () { + done() + }) + w.show() + w.maximize() + w.unmaximize() + }) + }) - describe('minimize event', function() { + describe('minimize event', function () { if (isCI) { - return; + return } - it('emits when window is minimized', function(done) { - this.timeout(10000); - w.once('minimize', function() { - done(); - }); - w.show(); - w.minimize(); - }); - }); + it('emits when window is minimized', function (done) { + this.timeout(10000) + w.once('minimize', function () { + done() + }) + w.show() + w.minimize() + }) + }) - describe('beginFrameSubscription method', function() { - this.timeout(20000); + describe('beginFrameSubscription method', function () { + this.timeout(20000) - it('subscribes frame updates', function(done) { - let called = false; - w.loadURL("file://" + fixtures + "/api/blank.html"); - w.webContents.beginFrameSubscription(function(data) { + it('subscribes frame updates', function (done) { + let called = false + w.loadURL('file://' + fixtures + '/api/blank.html') + w.webContents.beginFrameSubscription(function (data) { // This callback might be called twice. if (called) - return; - called = true; + return + called = true - assert.notEqual(data.length, 0); - w.webContents.endFrameSubscription(); - done(); - }); - }); - }); + assert.notEqual(data.length, 0) + w.webContents.endFrameSubscription() + done() + }) + }) + }) - describe('savePage method', function() { - const savePageDir = path.join(fixtures, 'save_page'); - const savePageHtmlPath = path.join(savePageDir, 'save_page.html'); - const savePageJsPath = path.join(savePageDir, 'save_page_files', 'test.js'); - const savePageCssPath = path.join(savePageDir, 'save_page_files', 'test.css'); + describe('savePage method', function () { + const savePageDir = path.join(fixtures, 'save_page') + const savePageHtmlPath = path.join(savePageDir, 'save_page.html') + const savePageJsPath = path.join(savePageDir, 'save_page_files', 'test.js') + const savePageCssPath = path.join(savePageDir, 'save_page_files', 'test.css') - after(function() { + after(function () { try { - fs.unlinkSync(savePageCssPath); - fs.unlinkSync(savePageJsPath); - fs.unlinkSync(savePageHtmlPath); - fs.rmdirSync(path.join(savePageDir, 'save_page_files')); - fs.rmdirSync(savePageDir); + fs.unlinkSync(savePageCssPath) + fs.unlinkSync(savePageJsPath) + fs.unlinkSync(savePageHtmlPath) + fs.rmdirSync(path.join(savePageDir, 'save_page_files')) + fs.rmdirSync(savePageDir) } catch (e) { // Ignore error } - }); + }) - it('should save page to disk', function(done) { - w.webContents.on('did-finish-load', function() { - w.webContents.savePage(savePageHtmlPath, 'HTMLComplete', function(error) { - assert.equal(error, null); - assert(fs.existsSync(savePageHtmlPath)); - assert(fs.existsSync(savePageJsPath)); - assert(fs.existsSync(savePageCssPath)); - done(); - }); - }); - w.loadURL("file://" + fixtures + "/pages/save_page/index.html"); - }); - }); + it('should save page to disk', function (done) { + w.webContents.on('did-finish-load', function () { + w.webContents.savePage(savePageHtmlPath, 'HTMLComplete', function (error) { + assert.equal(error, null) + assert(fs.existsSync(savePageHtmlPath)) + assert(fs.existsSync(savePageJsPath)) + assert(fs.existsSync(savePageCssPath)) + done() + }) + }) + w.loadURL('file://' + fixtures + '/pages/save_page/index.html') + }) + }) - describe('BrowserWindow options argument is optional', function() { - it('should create a window with default size (800x600)', function() { - w.destroy(); - w = new BrowserWindow(); - var size = w.getSize(); - assert.equal(size[0], 800); - assert.equal(size[1], 600); - }); - }); + describe('BrowserWindow options argument is optional', function () { + it('should create a window with default size (800x600)', function () { + w.destroy() + w = new BrowserWindow() + var size = w.getSize() + assert.equal(size[0], 800) + assert.equal(size[1], 600) + }) + }) - describe('window states', function() { - describe('resizable state', function() { - it('can be changed with resizable option', function() { - w.destroy(); - w = new BrowserWindow({show: false, resizable: false}); - assert.equal(w.isResizable(), false); - }); + describe('window states', function () { + describe('resizable state', function () { + it('can be changed with resizable option', function () { + w.destroy() + w = new BrowserWindow({show: false, resizable: false}) + assert.equal(w.isResizable(), false) + }) - it('can be changed with setResizable method', function() { - assert.equal(w.isResizable(), true); - w.setResizable(false); - assert.equal(w.isResizable(), false); - w.setResizable(true); - assert.equal(w.isResizable(), true); - }); - }); - }); + it('can be changed with setResizable method', function () { + assert.equal(w.isResizable(), true) + w.setResizable(false) + assert.equal(w.isResizable(), false) + w.setResizable(true) + assert.equal(w.isResizable(), true) + }) + }) + }) - describe('window states (excluding Linux)', function() { + describe('window states (excluding Linux)', function () { // Not implemented on Linux. if (process.platform == 'linux') - return; + return - describe('movable state', function() { - it('can be changed with movable option', function() { - w.destroy(); - w = new BrowserWindow({show: false, movable: false}); - assert.equal(w.isMovable(), false); - }); + describe('movable state', function () { + it('can be changed with movable option', function () { + w.destroy() + w = new BrowserWindow({show: false, movable: false}) + assert.equal(w.isMovable(), false) + }) - it('can be changed with setMovable method', function() { - assert.equal(w.isMovable(), true); - w.setMovable(false); - assert.equal(w.isMovable(), false); - w.setMovable(true); - assert.equal(w.isMovable(), true); - }); - }); + it('can be changed with setMovable method', function () { + assert.equal(w.isMovable(), true) + w.setMovable(false) + assert.equal(w.isMovable(), false) + w.setMovable(true) + assert.equal(w.isMovable(), true) + }) + }) - describe('minimizable state', function() { - it('can be changed with minimizable option', function() { - w.destroy(); - w = new BrowserWindow({show: false, minimizable: false}); - assert.equal(w.isMinimizable(), false); - }); + describe('minimizable state', function () { + it('can be changed with minimizable option', function () { + w.destroy() + w = new BrowserWindow({show: false, minimizable: false}) + assert.equal(w.isMinimizable(), false) + }) - it('can be changed with setMinimizable method', function() { - assert.equal(w.isMinimizable(), true); - w.setMinimizable(false); - assert.equal(w.isMinimizable(), false); - w.setMinimizable(true); - assert.equal(w.isMinimizable(), true); - }); - }); + it('can be changed with setMinimizable method', function () { + assert.equal(w.isMinimizable(), true) + w.setMinimizable(false) + assert.equal(w.isMinimizable(), false) + w.setMinimizable(true) + assert.equal(w.isMinimizable(), true) + }) + }) - describe('maximizable state', function() { - it('can be changed with maximizable option', function() { - w.destroy(); - w = new BrowserWindow({show: false, maximizable: false}); - assert.equal(w.isMaximizable(), false); - }); + describe('maximizable state', function () { + it('can be changed with maximizable option', function () { + w.destroy() + w = new BrowserWindow({show: false, maximizable: false}) + assert.equal(w.isMaximizable(), false) + }) - it('can be changed with setMaximizable method', function() { - assert.equal(w.isMaximizable(), true); - w.setMaximizable(false); - assert.equal(w.isMaximizable(), false); - w.setMaximizable(true); - assert.equal(w.isMaximizable(), true); - }); + it('can be changed with setMaximizable method', function () { + assert.equal(w.isMaximizable(), true) + w.setMaximizable(false) + assert.equal(w.isMaximizable(), false) + w.setMaximizable(true) + assert.equal(w.isMaximizable(), true) + }) - it('is not affected when changing other states', function() { - w.setMaximizable(false); - assert.equal(w.isMaximizable(), false); - w.setMinimizable(false); - assert.equal(w.isMaximizable(), false); - w.setClosable(false); - assert.equal(w.isMaximizable(), false); - }); - }); + it('is not affected when changing other states', function () { + w.setMaximizable(false) + assert.equal(w.isMaximizable(), false) + w.setMinimizable(false) + assert.equal(w.isMaximizable(), false) + w.setClosable(false) + assert.equal(w.isMaximizable(), false) + }) + }) - describe('fullscreenable state', function() { + describe('fullscreenable state', function () { // Only implemented on OS X. if (process.platform != 'darwin') - return; + return - it('can be changed with fullscreenable option', function() { - w.destroy(); - w = new BrowserWindow({show: false, fullscreenable: false}); - assert.equal(w.isFullScreenable(), false); - }); + it('can be changed with fullscreenable option', function () { + w.destroy() + w = new BrowserWindow({show: false, fullscreenable: false}) + assert.equal(w.isFullScreenable(), false) + }) - it('can be changed with setFullScreenable method', function() { - assert.equal(w.isFullScreenable(), true); - w.setFullScreenable(false); - assert.equal(w.isFullScreenable(), false); - w.setFullScreenable(true); - assert.equal(w.isFullScreenable(), true); - }); - }); + it('can be changed with setFullScreenable method', function () { + assert.equal(w.isFullScreenable(), true) + w.setFullScreenable(false) + assert.equal(w.isFullScreenable(), false) + w.setFullScreenable(true) + assert.equal(w.isFullScreenable(), true) + }) + }) - describe('closable state', function() { - it('can be changed with closable option', function() { - w.destroy(); - w = new BrowserWindow({show: false, closable: false}); - assert.equal(w.isClosable(), false); - }); + describe('closable state', function () { + it('can be changed with closable option', function () { + w.destroy() + w = new BrowserWindow({show: false, closable: false}) + assert.equal(w.isClosable(), false) + }) - it('can be changed with setClosable method', function() { - assert.equal(w.isClosable(), true); - w.setClosable(false); - assert.equal(w.isClosable(), false); - w.setClosable(true); - assert.equal(w.isClosable(), true); - }); - }); + it('can be changed with setClosable method', function () { + assert.equal(w.isClosable(), true) + w.setClosable(false) + assert.equal(w.isClosable(), false) + w.setClosable(true) + assert.equal(w.isClosable(), true) + }) + }) - describe('hasShadow state', function() { + describe('hasShadow state', function () { // On Window there is no shadow by default and it can not be changed // dynamically. - it('can be changed with hasShadow option', function() { - w.destroy(); - let hasShadow = process.platform == 'darwin' ? false : true; - w = new BrowserWindow({show: false, hasShadow: hasShadow}); - assert.equal(w.hasShadow(), hasShadow); - }); + it('can be changed with hasShadow option', function () { + w.destroy() + let hasShadow = process.platform == 'darwin' ? false : true + w = new BrowserWindow({show: false, hasShadow: hasShadow}) + assert.equal(w.hasShadow(), hasShadow) + }) - it('can be changed with setHasShadow method', function() { + it('can be changed with setHasShadow method', function () { if (process.platform != 'darwin') - return; + return - assert.equal(w.hasShadow(), true); - w.setHasShadow(false); - assert.equal(w.hasShadow(), false); - w.setHasShadow(true); - assert.equal(w.hasShadow(), true); - }); - }); - }); + assert.equal(w.hasShadow(), true) + w.setHasShadow(false) + assert.equal(w.hasShadow(), false) + w.setHasShadow(true) + assert.equal(w.hasShadow(), true) + }) + }) + }) - describe('window.webContents.send(channel, args...)', function() { - it('throws an error when the channel is missing', function() { - assert.throws(function() { - w.webContents.send(); - }, 'Missing required channel argument'); + describe('window.webContents.send(channel, args...)', function () { + it('throws an error when the channel is missing', function () { + assert.throws(function () { + w.webContents.send() + }, 'Missing required channel argument') - assert.throws(function() { - w.webContents.send(null); - }, 'Missing required channel argument'); - }); - }); + assert.throws(function () { + w.webContents.send(null) + }, 'Missing required channel argument') + }) + }) describe('dev tool extensions', function () { it('serializes the registered extensions on quit', function () { - var extensionName = 'foo'; - var extensionPath = path.join(__dirname, 'fixtures', 'devtools-extensions', extensionName); - var serializedPath = path.join(app.getPath('userData'), 'DevTools Extensions'); + var extensionName = 'foo' + var extensionPath = path.join(__dirname, 'fixtures', 'devtools-extensions', extensionName) + var serializedPath = path.join(app.getPath('userData'), 'DevTools Extensions') - BrowserWindow.addDevToolsExtension(extensionPath); - app.emit('will-quit'); - assert.deepEqual(JSON.parse(fs.readFileSync(serializedPath)), [extensionPath]); + BrowserWindow.addDevToolsExtension(extensionPath) + app.emit('will-quit') + assert.deepEqual(JSON.parse(fs.readFileSync(serializedPath)), [extensionPath]) - BrowserWindow.removeDevToolsExtension(extensionName); - app.emit('will-quit'); - assert.equal(fs.existsSync(serializedPath), false); - }); - }); + BrowserWindow.removeDevToolsExtension(extensionName) + app.emit('will-quit') + assert.equal(fs.existsSync(serializedPath), false) + }) + }) - describe('window.webContents.executeJavaScript', function() { - var expected = 'hello, world!'; - var code = '(() => \"' + expected + '\")()'; + describe('window.webContents.executeJavaScript', function () { + var expected = 'hello, world!' + var code = '(() => "' + expected + '")()' - it('doesnt throw when no calback is provided', function() { - const result = ipcRenderer.sendSync('executeJavaScript', code, false); - assert.equal(result, 'success'); - }); + it('doesnt throw when no calback is provided', function () { + const result = ipcRenderer.sendSync('executeJavaScript', code, false) + assert.equal(result, 'success') + }) - it('returns result when calback is provided', function(done) { - ipcRenderer.send('executeJavaScript', code, true); - ipcRenderer.once('executeJavaScript-response', function(event, result) { - assert.equal(result, expected); - done(); - }); - }); - }); + it('returns result when calback is provided', function (done) { + ipcRenderer.send('executeJavaScript', code, true) + ipcRenderer.once('executeJavaScript-response', function (event, result) { + assert.equal(result, expected) + done() + }) + }) + }) - describe('deprecated options', function() { - it('throws a deprecation error for option keys using hyphens instead of camel case', function() { + describe('deprecated options', function () { + it('throws a deprecation error for option keys using hyphens instead of camel case', function () { assert.throws(function () { - new BrowserWindow({'min-width': 500}); - }, 'min-width is deprecated. Use minWidth instead.'); - }); + new BrowserWindow({'min-width': 500}) + }, 'min-width is deprecated. Use minWidth instead.') + }) - it('throws a deprecation error for webPreference keys using hyphens instead of camel case', function() { + it('throws a deprecation error for webPreference keys using hyphens instead of camel case', function () { assert.throws(function () { - new BrowserWindow({webPreferences: {'node-integration': false}}); - }, 'node-integration is deprecated. Use nodeIntegration instead.'); - }); + new BrowserWindow({webPreferences: {'node-integration': false}}) + }, 'node-integration is deprecated. Use nodeIntegration instead.') + }) - it('throws a deprecation error for option keys that should be set on webPreferences', function() { + it('throws a deprecation error for option keys that should be set on webPreferences', function () { assert.throws(function () { - new BrowserWindow({zoomFactor: 1}); - }, 'options.zoomFactor is deprecated. Use options.webPreferences.zoomFactor instead.'); - }); - }); -}); + new BrowserWindow({zoomFactor: 1}) + }, 'options.zoomFactor is deprecated. Use options.webPreferences.zoomFactor instead.') + }) + }) +}) diff --git a/spec/api-clipboard-spec.js b/spec/api-clipboard-spec.js index 0b4a9f9521c..63f1d907e8a 100644 --- a/spec/api-clipboard-spec.js +++ b/spec/api-clipboard-spec.js @@ -1,63 +1,63 @@ -const assert = require('assert'); -const path = require('path'); +const assert = require('assert') +const path = require('path') -const clipboard = require('electron').clipboard; -const nativeImage = require('electron').nativeImage; +const clipboard = require('electron').clipboard +const nativeImage = require('electron').nativeImage -describe('clipboard module', function() { - var fixtures = path.resolve(__dirname, 'fixtures'); +describe('clipboard module', function () { + var fixtures = path.resolve(__dirname, 'fixtures') - describe('clipboard.readImage()', function() { - it('returns NativeImage intance', function() { - var p = path.join(fixtures, 'assets', 'logo.png'); - var i = nativeImage.createFromPath(p); - clipboard.writeImage(p); - assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); - }); - }); + describe('clipboard.readImage()', function () { + it('returns NativeImage intance', function () { + var p = path.join(fixtures, 'assets', 'logo.png') + var i = nativeImage.createFromPath(p) + clipboard.writeImage(p) + assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()) + }) + }) - describe('clipboard.readText()', function() { - it('returns unicode string correctly', function() { - var text = '千江有水千江月,万里无云万里天'; - clipboard.writeText(text); - assert.equal(clipboard.readText(), text); - }); - }); + describe('clipboard.readText()', function () { + it('returns unicode string correctly', function () { + var text = '千江有水千江月,万里无云万里天' + clipboard.writeText(text) + assert.equal(clipboard.readText(), text) + }) + }) - describe('clipboard.readHtml()', function() { - it('returns markup correctly', function() { - var text = 'Hi'; - var markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; - clipboard.writeHtml(text); - assert.equal(clipboard.readHtml(), markup); - }); - }); + describe('clipboard.readHtml()', function () { + it('returns markup correctly', function () { + var text = 'Hi' + var markup = process.platform === 'darwin' ? "Hi" : process.platform === 'linux' ? 'Hi' : 'Hi' + clipboard.writeHtml(text) + assert.equal(clipboard.readHtml(), markup) + }) + }) - describe('clipboard.readRtf', function() { - it('returns rtf text correctly', function() { - var rtf = "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}"; - clipboard.writeRtf(rtf); - assert.equal(clipboard.readRtf(), rtf); - }); - }); + describe('clipboard.readRtf', function () { + it('returns rtf text correctly', function () { + var rtf = '{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}' + clipboard.writeRtf(rtf) + assert.equal(clipboard.readRtf(), rtf) + }) + }) - describe('clipboard.write()', function() { - it('returns data correctly', function() { - var text = 'test'; - var rtf = '{\\rtf1\\utf8 text}'; - var p = path.join(fixtures, 'assets', 'logo.png'); - var i = nativeImage.createFromPath(p); - var markup = process.platform === 'darwin' ? 'Hi' : process.platform === 'linux' ? 'Hi' : 'Hi'; + describe('clipboard.write()', function () { + it('returns data correctly', function () { + var text = 'test' + var rtf = '{\\rtf1\\utf8 text}' + var p = path.join(fixtures, 'assets', 'logo.png') + var i = nativeImage.createFromPath(p) + var markup = process.platform === 'darwin' ? "Hi" : process.platform === 'linux' ? 'Hi' : 'Hi' clipboard.write({ - text: "test", + text: 'test', html: 'Hi', rtf: '{\\rtf1\\utf8 text}', image: p - }); - assert.equal(clipboard.readText(), text); - assert.equal(clipboard.readHtml(), markup); - assert.equal(clipboard.readRtf(), rtf); - assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()); - }); - }); -}); + }) + assert.equal(clipboard.readText(), text) + assert.equal(clipboard.readHtml(), markup) + assert.equal(clipboard.readRtf(), rtf) + assert.equal(clipboard.readImage().toDataURL(), i.toDataURL()) + }) + }) +}) diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index 68dc1375fc3..708daeab956 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -1,93 +1,93 @@ -const assert = require('assert'); -const http = require('http'); -const multiparty = require('multiparty'); -const path = require('path'); -const url = require('url'); +const assert = require('assert') +const http = require('http') +const multiparty = require('multiparty') +const path = require('path') +const url = require('url') -const remote = require('electron').remote; -const app = remote.require('electron').app; -const crashReporter = remote.require('electron').crashReporter; -const BrowserWindow = remote.require('electron').BrowserWindow; +const remote = require('electron').remote +const app = remote.require('electron').app +const crashReporter = remote.require('electron').crashReporter +const BrowserWindow = remote.require('electron').BrowserWindow -describe('crash-reporter module', function() { - var fixtures = path.resolve(__dirname, 'fixtures'); - var w = null; +describe('crash-reporter module', function () { + var fixtures = path.resolve(__dirname, 'fixtures') + var w = null - beforeEach(function() { + beforeEach(function () { w = new BrowserWindow({ show: false - }); - }); + }) + }) - afterEach(function() { - w.destroy(); - }); + afterEach(function () { + w.destroy() + }) if (process.mas) { - return; + return } - var isCI = remote.getGlobal('isCi'); + var isCI = remote.getGlobal('isCi') if (isCI) { - return; + return } - it('should send minidump when renderer crashes', function(done) { - this.timeout(120000); + it('should send minidump when renderer crashes', function (done) { + this.timeout(120000) - var called = false; - var server = http.createServer(function(req, res) { - server.close(); - var form = new multiparty.Form(); - form.parse(req, function(error, fields) { + var called = false + var server = http.createServer(function (req, res) { + server.close() + var form = new multiparty.Form() + form.parse(req, function (error, fields) { if (called) { - return; + return } - called = true; - assert.equal(fields['prod'], 'Electron'); - assert.equal(fields['ver'], process.versions['electron']); - assert.equal(fields['process_type'], 'renderer'); - assert.equal(fields['platform'], process.platform); - assert.equal(fields['extra1'], 'extra1'); - assert.equal(fields['extra2'], 'extra2'); - assert.equal(fields['_productName'], 'Zombies'); - assert.equal(fields['_companyName'], 'Umbrella Corporation'); - assert.equal(fields['_version'], app.getVersion()); - res.end('abc-123-def'); - done(); - }); - }); - var port = remote.process.port; - server.listen(port, '127.0.0.1', function() { - port = server.address().port; - remote.process.port = port; + called = true + assert.equal(fields['prod'], 'Electron') + assert.equal(fields['ver'], process.versions['electron']) + assert.equal(fields['process_type'], 'renderer') + assert.equal(fields['platform'], process.platform) + assert.equal(fields['extra1'], 'extra1') + assert.equal(fields['extra2'], 'extra2') + assert.equal(fields['_productName'], 'Zombies') + assert.equal(fields['_companyName'], 'Umbrella Corporation') + assert.equal(fields['_version'], app.getVersion()) + res.end('abc-123-def') + done() + }) + }) + var port = remote.process.port + server.listen(port, '127.0.0.1', function () { + port = server.address().port + remote.process.port = port const crashUrl = url.format({ protocol: 'file', pathname: path.join(fixtures, 'api', 'crash.html'), - search: "?port=" + port - }); + search: '?port=' + port + }) if (process.platform === 'darwin') { crashReporter.start({ companyName: 'Umbrella Corporation', - submitURL: "http://127.0.0.1:" + port - }); + submitURL: 'http://127.0.0.1:' + port + }) } - w.loadURL(crashUrl); - }); - }); + w.loadURL(crashUrl) + }) + }) - describe(".start(options)", function() { - it('requires that the companyName and submitURL options be specified', function() { - assert.throws(function() { + describe('.start(options)', function () { + it('requires that the companyName and submitURL options be specified', function () { + assert.throws(function () { crashReporter.start({ companyName: 'Missing submitURL' - }); - }); - assert.throws(function() { + }) + }) + assert.throws(function () { crashReporter.start({ submitURL: 'Missing companyName' - }); - }); - }); - }); -}); + }) + }) + }) + }) +}) diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index 56b642e76e4..1648ac1c3cd 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -1,133 +1,133 @@ -const assert = require('assert'); -const path = require('path'); -const BrowserWindow = require('electron').remote.BrowserWindow; +const assert = require('assert') +const path = require('path') +const BrowserWindow = require('electron').remote.BrowserWindow -describe('debugger module', function() { - var fixtures = path.resolve(__dirname, 'fixtures'); - var w = null; +describe('debugger module', function () { + var fixtures = path.resolve(__dirname, 'fixtures') + var w = null - beforeEach(function() { + beforeEach(function () { if (w != null) { - w.destroy(); + w.destroy() } w = new BrowserWindow({ show: false, width: 400, height: 400 - }); - }); + }) + }) - afterEach(function() { + afterEach(function () { if (w != null) { - w.destroy(); + w.destroy() } - w = null; - }); + w = null + }) - describe('debugger.attach', function() { - it('fails when devtools is already open', function(done) { - w.webContents.on('did-finish-load', function() { - w.webContents.openDevTools(); + describe('debugger.attach', function () { + it('fails when devtools is already open', function (done) { + w.webContents.on('did-finish-load', function () { + w.webContents.openDevTools() try { - w.webContents.debugger.attach(); + w.webContents.debugger.attach() } catch(err) { - assert(w.webContents.debugger.isAttached()); - done(); + assert(w.webContents.debugger.isAttached()) + done() } - }); - w.webContents.loadURL('file://' + path.join(fixtures, 'pages', 'a.html')); - }); + }) + w.webContents.loadURL('file://' + path.join(fixtures, 'pages', 'a.html')) + }) - it('fails when protocol version is not supported', function(done) { + it('fails when protocol version is not supported', function (done) { try { - w.webContents.debugger.attach("2.0"); + w.webContents.debugger.attach('2.0') } catch(err) { - assert(!w.webContents.debugger.isAttached()); - done(); + assert(!w.webContents.debugger.isAttached()) + done() } - }); + }) - it('attaches when no protocol version is specified', function(done) { + it('attaches when no protocol version is specified', function (done) { try { - w.webContents.debugger.attach(); + w.webContents.debugger.attach() } catch(err) { - done('unexpected error : ' + err); + done('unexpected error : ' + err) } - assert(w.webContents.debugger.isAttached()); - done(); - }); - }); + assert(w.webContents.debugger.isAttached()) + done() + }) + }) - describe('debugger.detach', function() { - it('fires detach event', function(done) { - w.webContents.debugger.on('detach', function(e, reason) { - assert.equal(reason, 'target closed'); - assert(!w.webContents.debugger.isAttached()); - done(); - }); + describe('debugger.detach', function () { + it('fires detach event', function (done) { + w.webContents.debugger.on('detach', function (e, reason) { + assert.equal(reason, 'target closed') + assert(!w.webContents.debugger.isAttached()) + done() + }) try { - w.webContents.debugger.attach(); + w.webContents.debugger.attach() } catch(err) { - done('unexpected error : ' + err); + done('unexpected error : ' + err) } - w.webContents.debugger.detach(); - }); - }); + w.webContents.debugger.detach() + }) + }) - describe('debugger.sendCommand', function() { - it('retuns response', function(done) { - w.webContents.loadURL('about:blank'); + describe('debugger.sendCommand', function () { + it('retuns response', function (done) { + w.webContents.loadURL('about:blank') try { - w.webContents.debugger.attach(); + w.webContents.debugger.attach() } catch(err) { - done('unexpected error : ' + err); + done('unexpected error : ' + err) + } + var callback = function (err, res) { + assert(!res.wasThrown) + assert.equal(res.result.value, 6) + w.webContents.debugger.detach() + done() } - var callback = function(err, res) { - assert(!res.wasThrown); - assert.equal(res.result.value, 6); - w.webContents.debugger.detach(); - done(); - }; const params = { - "expression": "4+2", - }; - w.webContents.debugger.sendCommand("Runtime.evaluate", params, callback); - }); + 'expression': '4+2', + } + w.webContents.debugger.sendCommand('Runtime.evaluate', params, callback) + }) - it('fires message event', function(done) { + it('fires message event', function (done) { var url = process.platform != 'win32' ? 'file://' + path.join(fixtures, 'pages', 'a.html') : - 'file:///' + path.join(fixtures, 'pages', 'a.html').replace(/\\/g, '/'); - w.webContents.loadURL(url); + 'file:///' + path.join(fixtures, 'pages', 'a.html').replace(/\\/g, '/') + w.webContents.loadURL(url) try { - w.webContents.debugger.attach(); + w.webContents.debugger.attach() } catch(err) { - done('unexpected error : ' + err); + done('unexpected error : ' + err) } - w.webContents.debugger.on('message', function(e, method, params) { - if(method == "Console.messageAdded") { - assert.equal(params.message.type, 'log'); - assert.equal(params.message.url, url); - assert.equal(params.message.text, 'a'); - w.webContents.debugger.detach(); - done(); + w.webContents.debugger.on('message', function (e, method, params) { + if (method == 'Console.messageAdded') { + assert.equal(params.message.type, 'log') + assert.equal(params.message.url, url) + assert.equal(params.message.text, 'a') + w.webContents.debugger.detach() + done() } - }); - w.webContents.debugger.sendCommand("Console.enable"); - }); + }) + w.webContents.debugger.sendCommand('Console.enable') + }) - it('returns error message when command fails', function(done) { - w.webContents.loadURL('about:blank'); + it('returns error message when command fails', function (done) { + w.webContents.loadURL('about:blank') try { - w.webContents.debugger.attach(); + w.webContents.debugger.attach() } catch(err) { - done('unexpected error : ' + err); + done('unexpected error : ' + err) } - w.webContents.debugger.sendCommand("Test", function(err) { - assert.equal(err.message, '\'Test\' wasn\'t found'); - w.webContents.debugger.detach(); - done(); - }); - }); - }); -}); + w.webContents.debugger.sendCommand('Test', function (err) { + assert.equal(err.message, "'Test' wasn't found") + w.webContents.debugger.detach() + done() + }) + }) + }) +}) diff --git a/spec/api-deprecations-spec.js b/spec/api-deprecations-spec.js index 2f010059059..375de5895fe 100644 --- a/spec/api-deprecations-spec.js +++ b/spec/api-deprecations-spec.js @@ -1,27 +1,27 @@ -const assert = require('assert'); -const deprecations = require('electron').deprecations; +const assert = require('assert') +const deprecations = require('electron').deprecations -describe('deprecations', function() { - beforeEach(function() { - deprecations.setHandler(null); - process.throwDeprecation = true; - }); +describe('deprecations', function () { + beforeEach(function () { + deprecations.setHandler(null) + process.throwDeprecation = true + }) - it('allows a deprecation handler function to be specified', function() { - var messages = []; + it('allows a deprecation handler function to be specified', function () { + var messages = [] deprecations.setHandler(function (message) { - messages.push(message); - }); + messages.push(message) + }) - require('electron').webFrame.registerUrlSchemeAsSecure('some-scheme'); + require('electron').webFrame.registerUrlSchemeAsSecure('some-scheme') - assert.deepEqual(messages, ['registerUrlSchemeAsSecure is deprecated. Use registerURLSchemeAsSecure instead.']); - }); + assert.deepEqual(messages, ['registerUrlSchemeAsSecure is deprecated. Use registerURLSchemeAsSecure instead.']) + }) - it('throws an exception if no deprecation handler is specified', function() { - assert.throws(function() { - require('electron').webFrame.registerUrlSchemeAsPrivileged('some-scheme'); - }, "registerUrlSchemeAsPrivileged is deprecated. Use registerURLSchemeAsPrivileged instead."); - }); -}); + it('throws an exception if no deprecation handler is specified', function () { + assert.throws(function () { + require('electron').webFrame.registerUrlSchemeAsPrivileged('some-scheme') + }, 'registerUrlSchemeAsPrivileged is deprecated. Use registerURLSchemeAsPrivileged instead.') + }) +}) diff --git a/spec/api-desktop-capturer-spec.js b/spec/api-desktop-capturer-spec.js index 02eda9003b8..9e85a48fbcc 100644 --- a/spec/api-desktop-capturer-spec.js +++ b/spec/api-desktop-capturer-spec.js @@ -1,27 +1,27 @@ -const assert = require('assert'); -const desktopCapturer = require('electron').desktopCapturer; +const assert = require('assert') +const desktopCapturer = require('electron').desktopCapturer -describe('desktopCapturer', function() { - it('should return a non-empty array of sources', function(done) { +describe('desktopCapturer', function () { + it('should return a non-empty array of sources', function (done) { desktopCapturer.getSources({ types: ['window', 'screen'] - }, function(error, sources) { - assert.equal(error, null); - assert.notEqual(sources.length, 0); - done(); - }); - }); + }, function (error, sources) { + assert.equal(error, null) + assert.notEqual(sources.length, 0) + done() + }) + }) - it('does not throw an error when called more than once (regression)', function(done) { - var callCount = 0; + it('does not throw an error when called more than once (regression)', function (done) { + var callCount = 0 var callback = function (error, sources) { - callCount++; - assert.equal(error, null); - assert.notEqual(sources.length, 0); - if (callCount === 2) done(); - }; + callCount++ + assert.equal(error, null) + assert.notEqual(sources.length, 0) + if (callCount === 2) done() + } - desktopCapturer.getSources({types: ['window', 'screen']}, callback); - desktopCapturer.getSources({types: ['window', 'screen']}, callback); - }); -}); + desktopCapturer.getSources({types: ['window', 'screen']}, callback) + desktopCapturer.getSources({types: ['window', 'screen']}, callback) + }) +}) diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 641d89270cb..862a6c99c17 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -1,210 +1,210 @@ -'use strict'; +'use strict' -const assert = require('assert'); -const path = require('path'); +const assert = require('assert') +const path = require('path') -const ipcRenderer = require('electron').ipcRenderer; -const remote = require('electron').remote; +const ipcRenderer = require('electron').ipcRenderer +const remote = require('electron').remote -const ipcMain = remote.require('electron').ipcMain; -const BrowserWindow = remote.require('electron').BrowserWindow; +const ipcMain = remote.require('electron').ipcMain +const BrowserWindow = remote.require('electron').BrowserWindow -const comparePaths = function(path1, path2) { +const comparePaths = function (path1, path2) { if (process.platform === 'win32') { - path1 = path1.toLowerCase(); - path2 = path2.toLowerCase(); + path1 = path1.toLowerCase() + path2 = path2.toLowerCase() } - assert.equal(path1, path2); -}; + assert.equal(path1, path2) +} -describe('ipc module', function() { - var fixtures = path.join(__dirname, 'fixtures'); +describe('ipc module', function () { + var fixtures = path.join(__dirname, 'fixtures') - describe('remote.require', function() { - it('should returns same object for the same module', function() { - var dialog1 = remote.require('electron'); - var dialog2 = remote.require('electron'); - assert.equal(dialog1, dialog2); - }); + describe('remote.require', function () { + it('should returns same object for the same module', function () { + var dialog1 = remote.require('electron') + var dialog2 = remote.require('electron') + assert.equal(dialog1, dialog2) + }) - it('should work when object contains id property', function() { - var a = remote.require(path.join(fixtures, 'module', 'id.js')); - assert.equal(a.id, 1127); - }); + it('should work when object contains id property', function () { + var a = remote.require(path.join(fixtures, 'module', 'id.js')) + assert.equal(a.id, 1127) + }) - it('should search module from the user app', function() { - comparePaths(path.normalize(remote.process.mainModule.filename), path.resolve(__dirname, 'static', 'main.js')); - comparePaths(path.normalize(remote.process.mainModule.paths[0]), path.resolve(__dirname, 'static', 'node_modules')); - }); - }); + it('should search module from the user app', function () { + comparePaths(path.normalize(remote.process.mainModule.filename), path.resolve(__dirname, 'static', 'main.js')) + comparePaths(path.normalize(remote.process.mainModule.paths[0]), path.resolve(__dirname, 'static', 'node_modules')) + }) + }) - describe('remote.createFunctionWithReturnValue', function() { - it('should be called in browser synchronously', function() { - var buf = new Buffer('test'); - var call = remote.require(path.join(fixtures, 'module', 'call.js')); - var result = call.call(remote.createFunctionWithReturnValue(buf)); - assert.equal(result.constructor.name, 'Buffer'); - }); - }); + describe('remote.createFunctionWithReturnValue', function () { + it('should be called in browser synchronously', function () { + var buf = new Buffer('test') + var call = remote.require(path.join(fixtures, 'module', 'call.js')) + var result = call.call(remote.createFunctionWithReturnValue(buf)) + assert.equal(result.constructor.name, 'Buffer') + }) + }) - describe('remote object in renderer', function() { - it('can change its properties', function() { - var property = remote.require(path.join(fixtures, 'module', 'property.js')); - assert.equal(property.property, 1127); - property.property = 1007; - assert.equal(property.property, 1007); - var property2 = remote.require(path.join(fixtures, 'module', 'property.js')); - assert.equal(property2.property, 1007); - property.property = 1127; - }); + describe('remote object in renderer', function () { + it('can change its properties', function () { + var property = remote.require(path.join(fixtures, 'module', 'property.js')) + assert.equal(property.property, 1127) + property.property = 1007 + assert.equal(property.property, 1007) + var property2 = remote.require(path.join(fixtures, 'module', 'property.js')) + assert.equal(property2.property, 1007) + property.property = 1127 + }) - it('can construct an object from its member', function() { - var call = remote.require(path.join(fixtures, 'module', 'call.js')); - var obj = new call.constructor; - assert.equal(obj.test, 'test'); - }); + it('can construct an object from its member', function () { + var call = remote.require(path.join(fixtures, 'module', 'call.js')) + var obj = new call.constructor + assert.equal(obj.test, 'test') + }) - it('can reassign and delete its member functions', function() { - var remoteFunctions = remote.require(path.join(fixtures, 'module', 'function.js')); - assert.equal(remoteFunctions.aFunction(), 1127); + it('can reassign and delete its member functions', function () { + var remoteFunctions = remote.require(path.join(fixtures, 'module', 'function.js')) + assert.equal(remoteFunctions.aFunction(), 1127) - remoteFunctions.aFunction = function () { return 1234; }; - assert.equal(remoteFunctions.aFunction(), 1234); + remoteFunctions.aFunction = function () { return 1234; } + assert.equal(remoteFunctions.aFunction(), 1234) - assert.equal(delete remoteFunctions.aFunction, true); - }); - }); + assert.equal(delete remoteFunctions.aFunction, true) + }) + }) - describe('remote value in browser', function() { - var print = path.join(fixtures, 'module', 'print_name.js'); + describe('remote value in browser', function () { + var print = path.join(fixtures, 'module', 'print_name.js') - it('keeps its constructor name for objects', function() { - var buf = new Buffer('test'); - var print_name = remote.require(print); - assert.equal(print_name.print(buf), 'Buffer'); - }); + it('keeps its constructor name for objects', function () { + var buf = new Buffer('test') + var print_name = remote.require(print) + assert.equal(print_name.print(buf), 'Buffer') + }) - it('supports instanceof Date', function() { - var now = new Date(); - var print_name = remote.require(print); - assert.equal(print_name.print(now), 'Date'); - assert.deepEqual(print_name.echo(now), now); - }); - }); + it('supports instanceof Date', function () { + var now = new Date() + var print_name = remote.require(print) + assert.equal(print_name.print(now), 'Date') + assert.deepEqual(print_name.echo(now), now) + }) + }) - describe('remote promise', function() { - it('can be used as promise in each side', function(done) { - var promise = remote.require(path.join(fixtures, 'module', 'promise.js')); - promise.twicePromise(Promise.resolve(1234)).then(function(value) { - assert.equal(value, 2468); - done(); - }); - }); - }); + describe('remote promise', function () { + it('can be used as promise in each side', function (done) { + var promise = remote.require(path.join(fixtures, 'module', 'promise.js')) + promise.twicePromise(Promise.resolve(1234)).then(function (value) { + assert.equal(value, 2468) + done() + }) + }) + }) - describe('remote webContents', function() { - it('can return same object with different getters', function() { - var contents1 = remote.getCurrentWindow().webContents; - var contents2 = remote.getCurrentWebContents(); - assert(contents1 == contents2); - }); - }); + describe('remote webContents', function () { + it('can return same object with different getters', function () { + var contents1 = remote.getCurrentWindow().webContents + var contents2 = remote.getCurrentWebContents() + assert(contents1 == contents2) + }) + }) - describe('remote class', function() { - let cl = remote.require(path.join(fixtures, 'module', 'class.js')); - let base = cl.base; - let derived = cl.derived; + describe('remote class', function () { + let cl = remote.require(path.join(fixtures, 'module', 'class.js')) + let base = cl.base + let derived = cl.derived - it('can get methods', function() { - assert.equal(base.method(), 'method'); - }); + it('can get methods', function () { + assert.equal(base.method(), 'method') + }) - it('can get properties', function() { - assert.equal(base.readonly, 'readonly'); - }); + it('can get properties', function () { + assert.equal(base.readonly, 'readonly') + }) - it('can change properties', function() { - assert.equal(base.value, 'old'); - base.value = 'new'; - assert.equal(base.value, 'new'); - base.value = 'old'; - }); + it('can change properties', function () { + assert.equal(base.value, 'old') + base.value = 'new' + assert.equal(base.value, 'new') + base.value = 'old' + }) - it('has unenumerable methods', function() { - assert(!base.hasOwnProperty('method')); - assert(Object.getPrototypeOf(base).hasOwnProperty('method')); - }); + it('has unenumerable methods', function () { + assert(!base.hasOwnProperty('method')) + assert(Object.getPrototypeOf(base).hasOwnProperty('method')) + }) - it('keeps prototype chain in derived class', function() { - assert.equal(derived.method(), 'method'); - assert.equal(derived.readonly, 'readonly'); - assert(!derived.hasOwnProperty('method')); - let proto = Object.getPrototypeOf(derived); - assert(!proto.hasOwnProperty('method')); - assert(Object.getPrototypeOf(proto).hasOwnProperty('method')); - }); - }); + it('keeps prototype chain in derived class', function () { + assert.equal(derived.method(), 'method') + assert.equal(derived.readonly, 'readonly') + assert(!derived.hasOwnProperty('method')) + let proto = Object.getPrototypeOf(derived) + assert(!proto.hasOwnProperty('method')) + assert(Object.getPrototypeOf(proto).hasOwnProperty('method')) + }) + }) - describe('ipc.sender.send', function() { - it('should work when sending an object containing id property', function(done) { + describe('ipc.sender.send', function () { + it('should work when sending an object containing id property', function (done) { var obj = { id: 1, name: 'ly' - }; - ipcRenderer.once('message', function(event, message) { - assert.deepEqual(message, obj); - done(); - }); - ipcRenderer.send('message', obj); - }); + } + ipcRenderer.once('message', function (event, message) { + assert.deepEqual(message, obj) + done() + }) + ipcRenderer.send('message', obj) + }) - it('can send instance of Date', function(done) { - const currentDate = new Date(); - ipcRenderer.once('message', function(event, value) { - assert.equal(value, currentDate.toISOString()); - done(); - }); - ipcRenderer.send('message', currentDate); - }); - }); + it('can send instance of Date', function (done) { + const currentDate = new Date() + ipcRenderer.once('message', function (event, value) { + assert.equal(value, currentDate.toISOString()) + done() + }) + ipcRenderer.send('message', currentDate) + }) + }) - describe('ipc.sendSync', function() { - it('can be replied by setting event.returnValue', function() { - var msg = ipcRenderer.sendSync('echo', 'test'); - assert.equal(msg, 'test'); - }); + describe('ipc.sendSync', function () { + it('can be replied by setting event.returnValue', function () { + var msg = ipcRenderer.sendSync('echo', 'test') + assert.equal(msg, 'test') + }) - it('does not crash when reply is not sent and browser is destroyed', function(done) { - this.timeout(10000); + it('does not crash when reply is not sent and browser is destroyed', function (done) { + this.timeout(10000) var w = new BrowserWindow({ show: false - }); - ipcMain.once('send-sync-message', function(event) { - event.returnValue = null; - w.destroy(); - done(); - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'send-sync-message.html')); - }); - }); + }) + ipcMain.once('send-sync-message', function (event) { + event.returnValue = null + w.destroy() + done() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'send-sync-message.html')) + }) + }) - describe('remote listeners', function() { - var w = null; + describe('remote listeners', function () { + var w = null - afterEach(function() { - w.destroy(); - }); + afterEach(function () { + w.destroy() + }) - it('can be added and removed correctly', function() { + it('can be added and removed correctly', function () { w = new BrowserWindow({ show: false - }); - var listener = function() {}; - w.on('test', listener); - assert.equal(w.listenerCount('test'), 1); - w.removeListener('test', listener); - assert.equal(w.listenerCount('test'), 0); - }); - }); -}); + }) + var listener = function () {} + w.on('test', listener) + assert.equal(w.listenerCount('test'), 1) + w.removeListener('test', listener) + assert.equal(w.listenerCount('test'), 0) + }) + }) +}) diff --git a/spec/api-menu-spec.js b/spec/api-menu-spec.js index bb8736e144f..6866448e0fd 100644 --- a/spec/api-menu-spec.js +++ b/spec/api-menu-spec.js @@ -1,25 +1,25 @@ -const assert = require('assert'); +const assert = require('assert') -const remote = require('electron').remote; -const ipcRenderer = require('electron').ipcRenderer; +const remote = require('electron').remote +const ipcRenderer = require('electron').ipcRenderer -const Menu = remote.require('electron').Menu; -const MenuItem = remote.require('electron').MenuItem; +const Menu = remote.require('electron').Menu +const MenuItem = remote.require('electron').MenuItem -describe('menu module', function() { - describe('Menu.buildFromTemplate', function() { - it('should be able to attach extra fields', function() { +describe('menu module', function () { + describe('Menu.buildFromTemplate', function () { + it('should be able to attach extra fields', function () { var menu = Menu.buildFromTemplate([ { label: 'text', extra: 'field' } - ]); - assert.equal(menu.items[0].extra, 'field'); - }); + ]) + assert.equal(menu.items[0].extra, 'field') + }) - it('does not modify the specified template', function() { - var template = ipcRenderer.sendSync('eval', "var template = [{label: 'text', submenu: [{label: 'sub'}]}];\nrequire('electron').Menu.buildFromTemplate(template);\ntemplate;"); + it('does not modify the specified template', function () { + var template = ipcRenderer.sendSync('eval', "var template = [{label: 'text', submenu: [{label: 'sub'}]}];\nrequire('electron').Menu.buildFromTemplate(template);\ntemplate;") assert.deepStrictEqual(template, [ { label: 'text', @@ -29,11 +29,11 @@ describe('menu module', function() { } ] } - ]); - }); + ]) + }) - it('does not throw exceptions for undefined/null values', function() { - assert.doesNotThrow(function() { + it('does not throw exceptions for undefined/null values', function () { + assert.doesNotThrow(function () { Menu.buildFromTemplate([ { label: 'text', @@ -43,12 +43,12 @@ describe('menu module', function() { label: 'text again', accelerator: null } - ]); - }); - }); + ]) + }) + }) - describe('Menu.buildFromTemplate should reorder based on item position specifiers', function() { - it('should position before existing item', function() { + describe('Menu.buildFromTemplate should reorder based on item position specifiers', function () { + it('should position before existing item', function () { var menu = Menu.buildFromTemplate([ { label: '2', @@ -61,13 +61,13 @@ describe('menu module', function() { id: '1', position: 'before=2' } - ]); - assert.equal(menu.items[0].label, '1'); - assert.equal(menu.items[1].label, '2'); - assert.equal(menu.items[2].label, '3'); - }); + ]) + assert.equal(menu.items[0].label, '1') + assert.equal(menu.items[1].label, '2') + assert.equal(menu.items[2].label, '3') + }) - it('should position after existing item', function() { + it('should position after existing item', function () { var menu = Menu.buildFromTemplate([ { label: '1', @@ -80,13 +80,13 @@ describe('menu module', function() { id: '2', position: 'after=1' } - ]); - assert.equal(menu.items[0].label, '1'); - assert.equal(menu.items[1].label, '2'); - assert.equal(menu.items[2].label, '3'); - }); + ]) + assert.equal(menu.items[0].label, '1') + assert.equal(menu.items[1].label, '2') + assert.equal(menu.items[2].label, '3') + }) - it('should position at endof existing separator groups', function() { + it('should position at endof existing separator groups', function () { var menu = Menu.buildFromTemplate([ { type: 'separator', @@ -119,18 +119,18 @@ describe('menu module', function() { id: '3', position: 'endof=numbers' } - ]); - assert.equal(menu.items[0].id, 'numbers'); - assert.equal(menu.items[1].label, '1'); - assert.equal(menu.items[2].label, '2'); - assert.equal(menu.items[3].label, '3'); - assert.equal(menu.items[4].id, 'letters'); - assert.equal(menu.items[5].label, 'a'); - assert.equal(menu.items[6].label, 'b'); - assert.equal(menu.items[7].label, 'c'); - }); + ]) + assert.equal(menu.items[0].id, 'numbers') + assert.equal(menu.items[1].label, '1') + assert.equal(menu.items[2].label, '2') + assert.equal(menu.items[3].label, '3') + assert.equal(menu.items[4].id, 'letters') + assert.equal(menu.items[5].label, 'a') + assert.equal(menu.items[6].label, 'b') + assert.equal(menu.items[7].label, 'c') + }) - it('should create separator group if endof does not reference existing separator group', function() { + it('should create separator group if endof does not reference existing separator group', function () { var menu = Menu.buildFromTemplate([ { label: 'a', @@ -157,18 +157,18 @@ describe('menu module', function() { id: '3', position: 'endof=numbers' } - ]); - assert.equal(menu.items[0].id, 'letters'); - assert.equal(menu.items[1].label, 'a'); - assert.equal(menu.items[2].label, 'b'); - assert.equal(menu.items[3].label, 'c'); - assert.equal(menu.items[4].id, 'numbers'); - assert.equal(menu.items[5].label, '1'); - assert.equal(menu.items[6].label, '2'); - assert.equal(menu.items[7].label, '3'); - }); + ]) + assert.equal(menu.items[0].id, 'letters') + assert.equal(menu.items[1].label, 'a') + assert.equal(menu.items[2].label, 'b') + assert.equal(menu.items[3].label, 'c') + assert.equal(menu.items[4].id, 'numbers') + assert.equal(menu.items[5].label, '1') + assert.equal(menu.items[6].label, '2') + assert.equal(menu.items[7].label, '3') + }) - it('should continue inserting items at next index when no specifier is present', function() { + it('should continue inserting items at next index when no specifier is present', function () { var menu = Menu.buildFromTemplate([ { label: '4', @@ -187,18 +187,18 @@ describe('menu module', function() { label: '3', id: '3' } - ]); - assert.equal(menu.items[0].label, '1'); - assert.equal(menu.items[1].label, '2'); - assert.equal(menu.items[2].label, '3'); - assert.equal(menu.items[3].label, '4'); - assert.equal(menu.items[4].label, '5'); - }); - }); - }); + ]) + assert.equal(menu.items[0].label, '1') + assert.equal(menu.items[1].label, '2') + assert.equal(menu.items[2].label, '3') + assert.equal(menu.items[3].label, '4') + assert.equal(menu.items[4].label, '5') + }) + }) + }) - describe('Menu.insert', function() { - it('should store item in @items by its index', function() { + describe('Menu.insert', function () { + it('should store item in @items by its index', function () { var menu = Menu.buildFromTemplate([ { label: '1' @@ -207,156 +207,156 @@ describe('menu module', function() { }, { label: '3' } - ]); + ]) var item = new MenuItem({ label: 'inserted' - }); - menu.insert(1, item); - assert.equal(menu.items[0].label, '1'); - assert.equal(menu.items[1].label, 'inserted'); - assert.equal(menu.items[2].label, '2'); - assert.equal(menu.items[3].label, '3'); - }); - }); + }) + menu.insert(1, item) + assert.equal(menu.items[0].label, '1') + assert.equal(menu.items[1].label, 'inserted') + assert.equal(menu.items[2].label, '2') + assert.equal(menu.items[3].label, '3') + }) + }) - describe('MenuItem.click', function() { - it('should be called with the item object passed', function(done) { + describe('MenuItem.click', function () { + it('should be called with the item object passed', function (done) { var menu = Menu.buildFromTemplate([ { label: 'text', - click: function(item) { - assert.equal(item.constructor.name, 'MenuItem'); - assert.equal(item.label, 'text'); - done(); + click: function (item) { + assert.equal(item.constructor.name, 'MenuItem') + assert.equal(item.label, 'text') + done() } } - ]); - menu.delegate.executeCommand(menu.items[0].commandId); - }); - }); + ]) + menu.delegate.executeCommand(menu.items[0].commandId) + }) + }) - describe('MenuItem with checked property', function() { - it('clicking an checkbox item should flip the checked property', function() { + describe('MenuItem with checked property', function () { + it('clicking an checkbox item should flip the checked property', function () { var menu = Menu.buildFromTemplate([ { label: 'text', type: 'checkbox' } - ]); - assert.equal(menu.items[0].checked, false); - menu.delegate.executeCommand(menu.items[0].commandId); - assert.equal(menu.items[0].checked, true); - }); + ]) + assert.equal(menu.items[0].checked, false) + menu.delegate.executeCommand(menu.items[0].commandId) + assert.equal(menu.items[0].checked, true) + }) - it('clicking an radio item should always make checked property true', function() { + it('clicking an radio item should always make checked property true', function () { var menu = Menu.buildFromTemplate([ { label: 'text', type: 'radio' } - ]); - menu.delegate.executeCommand(menu.items[0].commandId); - assert.equal(menu.items[0].checked, true); - menu.delegate.executeCommand(menu.items[0].commandId); - assert.equal(menu.items[0].checked, true); - }); + ]) + menu.delegate.executeCommand(menu.items[0].commandId) + assert.equal(menu.items[0].checked, true) + menu.delegate.executeCommand(menu.items[0].commandId) + assert.equal(menu.items[0].checked, true) + }) - it('at least have one item checked in each group', function() { - var i, j, k, menu, template; - template = []; + it('at least have one item checked in each group', function () { + var i, j, k, menu, template + template = [] for (i = j = 0; j <= 10; i = ++j) { template.push({ - label: "" + i, + label: '' + i, type: 'radio' - }); + }) } template.push({ type: 'separator' - }); + }) for (i = k = 12; k <= 20; i = ++k) { template.push({ - label: "" + i, + label: '' + i, type: 'radio' - }); + }) } - menu = Menu.buildFromTemplate(template); - menu.delegate.menuWillShow(); - assert.equal(menu.items[0].checked, true); - assert.equal(menu.items[12].checked, true); - }); + menu = Menu.buildFromTemplate(template) + menu.delegate.menuWillShow() + assert.equal(menu.items[0].checked, true) + assert.equal(menu.items[12].checked, true) + }) - it('should assign groupId automatically', function() { - var groupId, i, j, k, l, m, menu, template; - template = []; + it('should assign groupId automatically', function () { + var groupId, i, j, k, l, m, menu, template + template = [] for (i = j = 0; j <= 10; i = ++j) { template.push({ - label: "" + i, + label: '' + i, type: 'radio' - }); + }) } template.push({ type: 'separator' - }); + }) for (i = k = 12; k <= 20; i = ++k) { template.push({ - label: "" + i, + label: '' + i, type: 'radio' - }); + }) } - menu = Menu.buildFromTemplate(template); - groupId = menu.items[0].groupId; + menu = Menu.buildFromTemplate(template) + groupId = menu.items[0].groupId for (i = l = 0; l <= 10; i = ++l) { - assert.equal(menu.items[i].groupId, groupId); + assert.equal(menu.items[i].groupId, groupId) } for (i = m = 12; m <= 20; i = ++m) { - assert.equal(menu.items[i].groupId, groupId + 1); + assert.equal(menu.items[i].groupId, groupId + 1) } - }); + }) - it("setting 'checked' should flip other items' 'checked' property", function() { - var i, j, k, l, m, menu, n, o, p, q, template; - template = []; + it("setting 'checked' should flip other items' 'checked' property", function () { + var i, j, k, l, m, menu, n, o, p, q, template + template = [] for (i = j = 0; j <= 10; i = ++j) { template.push({ - label: "" + i, + label: '' + i, type: 'radio' - }); + }) } template.push({ type: 'separator' - }); + }) for (i = k = 12; k <= 20; i = ++k) { template.push({ - label: "" + i, + label: '' + i, type: 'radio' - }); + }) } - menu = Menu.buildFromTemplate(template); + menu = Menu.buildFromTemplate(template) for (i = l = 0; l <= 10; i = ++l) { - assert.equal(menu.items[i].checked, false); + assert.equal(menu.items[i].checked, false) } - menu.items[0].checked = true; - assert.equal(menu.items[0].checked, true); + menu.items[0].checked = true + assert.equal(menu.items[0].checked, true) for (i = m = 1; m <= 10; i = ++m) { - assert.equal(menu.items[i].checked, false); + assert.equal(menu.items[i].checked, false) } - menu.items[10].checked = true; - assert.equal(menu.items[10].checked, true); + menu.items[10].checked = true + assert.equal(menu.items[10].checked, true) for (i = n = 0; n <= 9; i = ++n) { - assert.equal(menu.items[i].checked, false); + assert.equal(menu.items[i].checked, false) } for (i = o = 12; o <= 20; i = ++o) { - assert.equal(menu.items[i].checked, false); + assert.equal(menu.items[i].checked, false) } - menu.items[12].checked = true; - assert.equal(menu.items[10].checked, true); + menu.items[12].checked = true + assert.equal(menu.items[10].checked, true) for (i = p = 0; p <= 9; i = ++p) { - assert.equal(menu.items[i].checked, false); + assert.equal(menu.items[i].checked, false) } - assert.equal(menu.items[12].checked, true); + assert.equal(menu.items[12].checked, true) for (i = q = 13; q <= 20; i = ++q) { - assert.equal(menu.items[i].checked, false); + assert.equal(menu.items[i].checked, false) } - }); - }); -}); + }) + }) +}) diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index a7ee8be007e..6c5092cf7c3 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -1,51 +1,51 @@ -'use strict'; +'use strict' -const assert = require('assert'); -const nativeImage = require('electron').nativeImage; -const path = require('path'); +const assert = require('assert') +const nativeImage = require('electron').nativeImage +const path = require('path') describe('nativeImage module', () => { describe('createFromPath(path)', () => { it('returns an empty image for invalid paths', () => { - assert(nativeImage.createFromPath('').isEmpty()); - assert(nativeImage.createFromPath('does-not-exist.png').isEmpty()); - }); + assert(nativeImage.createFromPath('').isEmpty()) + assert(nativeImage.createFromPath('does-not-exist.png').isEmpty()) + }) it('loads images from paths relative to the current working directory', () => { - const imagePath = `.${path.sep}${path.join('spec', 'fixtures', 'assets', 'logo.png')}`; - const image = nativeImage.createFromPath(imagePath); - assert(!image.isEmpty()); - assert.equal(image.getSize().height, 190); - assert.equal(image.getSize().width, 538); - }); + const imagePath = `.${path.sep}${path.join('spec', 'fixtures', 'assets', 'logo.png')}` + const image = nativeImage.createFromPath(imagePath) + assert(!image.isEmpty()) + assert.equal(image.getSize().height, 190) + assert.equal(image.getSize().width, 538) + }) it('loads images from paths with `.` segments', () => { - const imagePath = `${path.join(__dirname, 'fixtures')}${path.sep}.${path.sep}${path.join('assets', 'logo.png')}`; - const image = nativeImage.createFromPath(imagePath); - assert(!image.isEmpty()); - assert.equal(image.getSize().height, 190); - assert.equal(image.getSize().width, 538); - }); + const imagePath = `${path.join(__dirname, 'fixtures')}${path.sep}.${path.sep}${path.join('assets', 'logo.png')}` + const image = nativeImage.createFromPath(imagePath) + assert(!image.isEmpty()) + assert.equal(image.getSize().height, 190) + assert.equal(image.getSize().width, 538) + }) it('loads images from paths with `..` segments', () => { - const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; - const image = nativeImage.createFromPath(imagePath); - assert(!image.isEmpty()); - assert.equal(image.getSize().height, 190); - assert.equal(image.getSize().width, 538); - }); + const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}` + const image = nativeImage.createFromPath(imagePath) + assert(!image.isEmpty()) + assert.equal(image.getSize().height, 190) + assert.equal(image.getSize().width, 538) + }) it('Gets an NSImage pointer on OS X', () => { - if (process.platform !== 'darwin') return; + if (process.platform !== 'darwin') return - const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}`; - const image = nativeImage.createFromPath(imagePath); - const nsimage = image.getNativeHandle(); + const imagePath = `${path.join(__dirname, 'fixtures', 'api')}${path.sep}..${path.sep}${path.join('assets', 'logo.png')}` + const image = nativeImage.createFromPath(imagePath) + const nsimage = image.getNativeHandle() - assert.equal(nsimage.length, 8); + assert.equal(nsimage.length, 8) // If all bytes are null, that's Bad - assert.equal(nsimage.reduce((acc,x) => acc || (x != 0), false), true); - }); - }); -}); + assert.equal(nsimage.reduce((acc, x) => acc || (x != 0), false), true) + }) + }) +}) diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 215868bfdc8..001359d3850 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -1,772 +1,772 @@ -const assert = require('assert'); -const http = require('http'); -const path = require('path'); -const qs = require('querystring'); -const remote = require('electron').remote; -const protocol = remote.require('electron').protocol; +const assert = require('assert') +const http = require('http') +const path = require('path') +const qs = require('querystring') +const remote = require('electron').remote +const protocol = remote.require('electron').protocol -describe('protocol module', function() { - var protocolName = 'sp'; - var text = 'valar morghulis'; +describe('protocol module', function () { + var protocolName = 'sp' + var text = 'valar morghulis' var postData = { name: 'post test', type: 'string' - }; + } - afterEach(function(done) { - protocol.unregisterProtocol(protocolName, function() { - protocol.uninterceptProtocol('http', function() { - done(); - }); - }); - }); + afterEach(function (done) { + protocol.unregisterProtocol(protocolName, function () { + protocol.uninterceptProtocol('http', function () { + done() + }) + }) + }) - describe('protocol.register(Any)Protocol', function() { - var emptyHandler = function(request, callback) { - callback(); - }; + describe('protocol.register(Any)Protocol', function () { + var emptyHandler = function (request, callback) { + callback() + } - it('throws error when scheme is already registered', function(done) { - protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { - assert.equal(error, null); - protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { - assert.notEqual(error, null); - done(); - }); - }); - }); + it('throws error when scheme is already registered', function (done) { + protocol.registerStringProtocol(protocolName, emptyHandler, function (error) { + assert.equal(error, null) + protocol.registerBufferProtocol(protocolName, emptyHandler, function (error) { + assert.notEqual(error, null) + done() + }) + }) + }) - it('does not crash when handler is called twice', function(done) { - var doubleHandler = function(request, callback) { + it('does not crash when handler is called twice', function (done) { + var doubleHandler = function (request, callback) { try { - callback(text); - callback(); + callback(text) + callback() } catch (error) { // Ignore error } - }; - protocol.registerStringProtocol(protocolName, doubleHandler, function(error) { + } + protocol.registerStringProtocol(protocolName, doubleHandler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data) { - assert.equal(data, text); - done(); + url: protocolName + '://fake-host', + success: function (data) { + assert.equal(data, text) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) - it('sends error when callback is called with nothing', function(done) { - protocol.registerBufferProtocol(protocolName, emptyHandler, function(error) { + it('sends error when callback is called with nothing', function (done) { + protocol.registerBufferProtocol(protocolName, emptyHandler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function() { - return done('request succeeded but it should not'); + url: protocolName + '://fake-host', + success: function () { + return done('request succeeded but it should not') }, - error: function(xhr, errorType) { - assert.equal(errorType, 'error'); - return done(); + error: function (xhr, errorType) { + assert.equal(errorType, 'error') + return done() } - }); - }); - }); + }) + }) + }) - it('does not crash when callback is called in next tick', function(done) { - var handler = function(request, callback) { - setImmediate(function() { - callback(text); - }); - }; - protocol.registerStringProtocol(protocolName, handler, function(error) { + it('does not crash when callback is called in next tick', function (done) { + var handler = function (request, callback) { + setImmediate(function () { + callback(text) + }) + } + protocol.registerStringProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data) { - assert.equal(data, text); - done(); + url: protocolName + '://fake-host', + success: function (data) { + assert.equal(data, text) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); - }); + }) + }) + }) + }) - describe('protocol.unregisterProtocol', function() { - it('returns error when scheme does not exist', function(done) { - protocol.unregisterProtocol('not-exist', function(error) { - assert.notEqual(error, null); - done(); - }); - }); - }); + describe('protocol.unregisterProtocol', function () { + it('returns error when scheme does not exist', function (done) { + protocol.unregisterProtocol('not-exist', function (error) { + assert.notEqual(error, null) + done() + }) + }) + }) - describe('protocol.registerStringProtocol', function() { - it('sends string as response', function(done) { - var handler = function(request, callback) { - callback(text); - }; - protocol.registerStringProtocol(protocolName, handler, function(error) { + describe('protocol.registerStringProtocol', function () { + it('sends string as response', function (done) { + var handler = function (request, callback) { + callback(text) + } + protocol.registerStringProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data) { - assert.equal(data, text); - done(); + url: protocolName + '://fake-host', + success: function (data) { + assert.equal(data, text) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) - it('sets Access-Control-Allow-Origin', function(done) { - var handler = function(request, callback) { - callback(text); - }; - protocol.registerStringProtocol(protocolName, handler, function(error) { + it('sets Access-Control-Allow-Origin', function (done) { + var handler = function (request, callback) { + callback(text) + } + protocol.registerStringProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data, status, request) { - assert.equal(data, text); - assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*'); - done(); + url: protocolName + '://fake-host', + success: function (data, status, request) { + assert.equal(data, text) + assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*') + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) - it('sends object as response', function(done) { - var handler = function(request, callback) { + it('sends object as response', function (done) { + var handler = function (request, callback) { callback({ data: text, mimeType: 'text/html' - }); - }; - protocol.registerStringProtocol(protocolName, handler, function(error) { + }) + } + protocol.registerStringProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data) { - assert.equal(data, text); - done(); + url: protocolName + '://fake-host', + success: function (data) { + assert.equal(data, text) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) - it('fails when sending object other than string', function(done) { - var handler = function(request, callback) { - callback(new Date); - }; - protocol.registerBufferProtocol(protocolName, handler, function(error) { + it('fails when sending object other than string', function (done) { + var handler = function (request, callback) { + callback(new Date) + } + protocol.registerBufferProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function() { - done('request succeeded but it should not'); + url: protocolName + '://fake-host', + success: function () { + done('request succeeded but it should not') }, - error: function(xhr, errorType) { - assert.equal(errorType, 'error'); - done(); + error: function (xhr, errorType) { + assert.equal(errorType, 'error') + done() } - }); - }); - }); - }); + }) + }) + }) + }) - describe('protocol.registerBufferProtocol', function() { - var buffer = new Buffer(text); + describe('protocol.registerBufferProtocol', function () { + var buffer = new Buffer(text) - it('sends Buffer as response', function(done) { - var handler = function(request, callback) { - callback(buffer); - }; - protocol.registerBufferProtocol(protocolName, handler, function(error) { + it('sends Buffer as response', function (done) { + var handler = function (request, callback) { + callback(buffer) + } + protocol.registerBufferProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data) { - assert.equal(data, text); - done(); + url: protocolName + '://fake-host', + success: function (data) { + assert.equal(data, text) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) - it('sets Access-Control-Allow-Origin', function(done) { - var handler = function(request, callback) { - callback(buffer); - }; + it('sets Access-Control-Allow-Origin', function (done) { + var handler = function (request, callback) { + callback(buffer) + } - protocol.registerBufferProtocol(protocolName, handler, function(error) { + protocol.registerBufferProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data, status, request) { - assert.equal(data, text); - assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*'); - done(); + url: protocolName + '://fake-host', + success: function (data, status, request) { + assert.equal(data, text) + assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*') + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) - it('sends object as response', function(done) { - var handler = function(request, callback) { + it('sends object as response', function (done) { + var handler = function (request, callback) { callback({ data: buffer, mimeType: 'text/html' - }); - }; - protocol.registerBufferProtocol(protocolName, handler, function(error) { + }) + } + protocol.registerBufferProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data) { - assert.equal(data, text); - done(); + url: protocolName + '://fake-host', + success: function (data) { + assert.equal(data, text) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) - it('fails when sending string', function(done) { - var handler = function(request, callback) { - callback(text); - }; - protocol.registerBufferProtocol(protocolName, handler, function(error) { + it('fails when sending string', function (done) { + var handler = function (request, callback) { + callback(text) + } + protocol.registerBufferProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function() { - done('request succeeded but it should not'); + url: protocolName + '://fake-host', + success: function () { + done('request succeeded but it should not') }, - error: function(xhr, errorType) { - assert.equal(errorType, 'error'); - done(); + error: function (xhr, errorType) { + assert.equal(errorType, 'error') + done() } - }); - }); - }); - }); + }) + }) + }) + }) - describe('protocol.registerFileProtocol', function() { - var filePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'file1'); - var fileContent = require('fs').readFileSync(filePath); - var normalPath = path.join(__dirname, 'fixtures', 'pages', 'a.html'); - var normalContent = require('fs').readFileSync(normalPath); + describe('protocol.registerFileProtocol', function () { + var filePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'file1') + var fileContent = require('fs').readFileSync(filePath) + var normalPath = path.join(__dirname, 'fixtures', 'pages', 'a.html') + var normalContent = require('fs').readFileSync(normalPath) - it('sends file path as response', function(done) { - var handler = function(request, callback) { - callback(filePath); - }; - protocol.registerFileProtocol(protocolName, handler, function(error) { + it('sends file path as response', function (done) { + var handler = function (request, callback) { + callback(filePath) + } + protocol.registerFileProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data) { - assert.equal(data, String(fileContent)); - return done(); + url: protocolName + '://fake-host', + success: function (data) { + assert.equal(data, String(fileContent)) + return done() }, - error: function(xhr, errorType, error) { - return done(error); + error: function (xhr, errorType, error) { + return done(error) } - }); - }); - }); + }) + }) + }) - it('sets Access-Control-Allow-Origin', function(done) { - var handler = function(request, callback) { - callback(filePath); - }; - protocol.registerFileProtocol(protocolName, handler, function(error) { + it('sets Access-Control-Allow-Origin', function (done) { + var handler = function (request, callback) { + callback(filePath) + } + protocol.registerFileProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data, status, request) { - assert.equal(data, String(fileContent)); - assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*'); - done(); + url: protocolName + '://fake-host', + success: function (data, status, request) { + assert.equal(data, String(fileContent)) + assert.equal(request.getResponseHeader('Access-Control-Allow-Origin'), '*') + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); - it('sends object as response', function(done) { - var handler = function(request, callback) { + }) + }) + }) + it('sends object as response', function (done) { + var handler = function (request, callback) { callback({ path: filePath - }); - }; - protocol.registerFileProtocol(protocolName, handler, function(error) { + }) + } + protocol.registerFileProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data) { - assert.equal(data, String(fileContent)); - done(); + url: protocolName + '://fake-host', + success: function (data) { + assert.equal(data, String(fileContent)) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) - it('can send normal file', function(done) { - var handler = function(request, callback) { - callback(normalPath); - }; + it('can send normal file', function (done) { + var handler = function (request, callback) { + callback(normalPath) + } - protocol.registerFileProtocol(protocolName, handler, function(error) { + protocol.registerFileProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data) { - assert.equal(data, String(normalContent)); - done(); + url: protocolName + '://fake-host', + success: function (data) { + assert.equal(data, String(normalContent)) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) - it('fails when sending unexist-file', function(done) { - var fakeFilePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'not-exist'); - var handler = function(request, callback) { - callback(fakeFilePath); - }; - protocol.registerBufferProtocol(protocolName, handler, function(error) { + it('fails when sending unexist-file', function (done) { + var fakeFilePath = path.join(__dirname, 'fixtures', 'asar', 'a.asar', 'not-exist') + var handler = function (request, callback) { + callback(fakeFilePath) + } + protocol.registerBufferProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function() { - done('request succeeded but it should not'); + url: protocolName + '://fake-host', + success: function () { + done('request succeeded but it should not') }, - error: function(xhr, errorType) { - assert.equal(errorType, 'error'); - done(); + error: function (xhr, errorType) { + assert.equal(errorType, 'error') + done() } - }); - }); - }); + }) + }) + }) - it('fails when sending unsupported content', function(done) { - var handler = function(request, callback) { - callback(new Date); - }; - protocol.registerBufferProtocol(protocolName, handler, function(error) { + it('fails when sending unsupported content', function (done) { + var handler = function (request, callback) { + callback(new Date) + } + protocol.registerBufferProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function() { - done('request succeeded but it should not'); + url: protocolName + '://fake-host', + success: function () { + done('request succeeded but it should not') }, - error: function(xhr, errorType) { - assert.equal(errorType, 'error'); - done(); + error: function (xhr, errorType) { + assert.equal(errorType, 'error') + done() } - }); - }); - }); - }); + }) + }) + }) + }) - describe('protocol.registerHttpProtocol', function() { - it('sends url as response', function(done) { - var server = http.createServer(function(req, res) { - assert.notEqual(req.headers.accept, ''); - res.end(text); - server.close(); - }); - server.listen(0, '127.0.0.1', function() { - var port = server.address().port; - var url = "http://127.0.0.1:" + port; - var handler = function(request, callback) { + describe('protocol.registerHttpProtocol', function () { + it('sends url as response', function (done) { + var server = http.createServer(function (req, res) { + assert.notEqual(req.headers.accept, '') + res.end(text) + server.close() + }) + server.listen(0, '127.0.0.1', function () { + var port = server.address().port + var url = 'http://127.0.0.1:' + port + var handler = function (request, callback) { callback({ url: url - }); - }; - protocol.registerHttpProtocol(protocolName, handler, function(error) { + }) + } + protocol.registerHttpProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function(data) { - assert.equal(data, text); - done(); + url: protocolName + '://fake-host', + success: function (data) { + assert.equal(data, text) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); - }); + }) + }) + }) + }) - it('fails when sending invalid url', function(done) { - var handler = function(request, callback) { + it('fails when sending invalid url', function (done) { + var handler = function (request, callback) { callback({ url: 'url' - }); - }; - protocol.registerHttpProtocol(protocolName, handler, function(error) { + }) + } + protocol.registerHttpProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function() { - done('request succeeded but it should not'); + url: protocolName + '://fake-host', + success: function () { + done('request succeeded but it should not') }, - error: function(xhr, errorType) { - assert.equal(errorType, 'error'); - done(); + error: function (xhr, errorType) { + assert.equal(errorType, 'error') + done() } - }); - }); - }); + }) + }) + }) - it('fails when sending unsupported content', function(done) { - var handler = function(request, callback) { - callback(new Date); - }; - protocol.registerHttpProtocol(protocolName, handler, function(error) { + it('fails when sending unsupported content', function (done) { + var handler = function (request, callback) { + callback(new Date) + } + protocol.registerHttpProtocol(protocolName, handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: protocolName + "://fake-host", - success: function() { - done('request succeeded but it should not'); + url: protocolName + '://fake-host', + success: function () { + done('request succeeded but it should not') }, - error: function(xhr, errorType) { - assert.equal(errorType, 'error'); - done(); + error: function (xhr, errorType) { + assert.equal(errorType, 'error') + done() } - }); - }); - }); - }); + }) + }) + }) + }) - describe('protocol.isProtocolHandled', function() { - it('returns true for file:', function(done) { - protocol.isProtocolHandled('file', function(result) { - assert.equal(result, true); - done(); - }); - }); + describe('protocol.isProtocolHandled', function () { + it('returns true for file:', function (done) { + protocol.isProtocolHandled('file', function (result) { + assert.equal(result, true) + done() + }) + }) - it('returns true for http:', function(done) { - protocol.isProtocolHandled('http', function(result) { - assert.equal(result, true); - done(); - }); - }); + it('returns true for http:', function (done) { + protocol.isProtocolHandled('http', function (result) { + assert.equal(result, true) + done() + }) + }) - it('returns true for https:', function(done) { - protocol.isProtocolHandled('https', function(result) { - assert.equal(result, true); - done(); - }); - }); + it('returns true for https:', function (done) { + protocol.isProtocolHandled('https', function (result) { + assert.equal(result, true) + done() + }) + }) - it('returns false when scheme is not registred', function(done) { - protocol.isProtocolHandled('no-exist', function(result) { - assert.equal(result, false); - done(); - }); - }); + it('returns false when scheme is not registred', function (done) { + protocol.isProtocolHandled('no-exist', function (result) { + assert.equal(result, false) + done() + }) + }) - it('returns true for custom protocol', function(done) { - var emptyHandler = function(request, callback) { - callback(); - }; - protocol.registerStringProtocol(protocolName, emptyHandler, function(error) { - assert.equal(error, null); - protocol.isProtocolHandled(protocolName, function(result) { - assert.equal(result, true); - done(); - }); - }); - }); + it('returns true for custom protocol', function (done) { + var emptyHandler = function (request, callback) { + callback() + } + protocol.registerStringProtocol(protocolName, emptyHandler, function (error) { + assert.equal(error, null) + protocol.isProtocolHandled(protocolName, function (result) { + assert.equal(result, true) + done() + }) + }) + }) - it('returns true for intercepted protocol', function(done) { - var emptyHandler = function(request, callback) { - callback(); - }; - protocol.interceptStringProtocol('http', emptyHandler, function(error) { - assert.equal(error, null); - protocol.isProtocolHandled('http', function(result) { - assert.equal(result, true); - done(); - }); - }); - }); - }); + it('returns true for intercepted protocol', function (done) { + var emptyHandler = function (request, callback) { + callback() + } + protocol.interceptStringProtocol('http', emptyHandler, function (error) { + assert.equal(error, null) + protocol.isProtocolHandled('http', function (result) { + assert.equal(result, true) + done() + }) + }) + }) + }) - describe('protocol.intercept(Any)Protocol', function() { - var emptyHandler = function(request, callback) { - callback(); - }; + describe('protocol.intercept(Any)Protocol', function () { + var emptyHandler = function (request, callback) { + callback() + } - it('throws error when scheme is already intercepted', function(done) { - protocol.interceptStringProtocol('http', emptyHandler, function(error) { - assert.equal(error, null); - protocol.interceptBufferProtocol('http', emptyHandler, function(error) { - assert.notEqual(error, null); - done(); - }); - }); - }); + it('throws error when scheme is already intercepted', function (done) { + protocol.interceptStringProtocol('http', emptyHandler, function (error) { + assert.equal(error, null) + protocol.interceptBufferProtocol('http', emptyHandler, function (error) { + assert.notEqual(error, null) + done() + }) + }) + }) - it('does not crash when handler is called twice', function(done) { - var doubleHandler = function(request, callback) { + it('does not crash when handler is called twice', function (done) { + var doubleHandler = function (request, callback) { try { - callback(text); - callback(); + callback(text) + callback() } catch (error) { // Ignore error } - }; - protocol.interceptStringProtocol('http', doubleHandler, function(error) { - if (error) { - return done(error); - } - $.ajax({ - url: 'http://fake-host', - success: function(data) { - assert.equal(data, text); - done(); - }, - error: function(xhr, errorType, error) { - done(error); - } - }); - }); - }); - - it('sends error when callback is called with nothing', function(done) { - if (process.env.TRAVIS === 'true') { - return done(); } - protocol.interceptBufferProtocol('http', emptyHandler, function(error) { + protocol.interceptStringProtocol('http', doubleHandler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ url: 'http://fake-host', - success: function() { - done('request succeeded but it should not'); + success: function (data) { + assert.equal(data, text) + done() }, - error: function(xhr, errorType) { - assert.equal(errorType, 'error'); - done(); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); - }); + }) + }) + }) - describe('protocol.interceptStringProtocol', function() { - it('can intercept http protocol', function(done) { - var handler = function(request, callback) { - callback(text); - }; - protocol.interceptStringProtocol('http', handler, function(error) { + it('sends error when callback is called with nothing', function (done) { + if (process.env.TRAVIS === 'true') { + return done() + } + protocol.interceptBufferProtocol('http', emptyHandler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ url: 'http://fake-host', - success: function(data) { - assert.equal(data, text); - done(); + success: function () { + done('request succeeded but it should not') }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType) { + assert.equal(errorType, 'error') + done() } - }); - }); - }); + }) + }) + }) + }) - it('can set content-type', function(done) { - var handler = function(request, callback) { + describe('protocol.interceptStringProtocol', function () { + it('can intercept http protocol', function (done) { + var handler = function (request, callback) { + callback(text) + } + protocol.interceptStringProtocol('http', handler, function (error) { + if (error) { + return done(error) + } + $.ajax({ + url: 'http://fake-host', + success: function (data) { + assert.equal(data, text) + done() + }, + error: function (xhr, errorType, error) { + done(error) + } + }) + }) + }) + + it('can set content-type', function (done) { + var handler = function (request, callback) { callback({ mimeType: 'application/json', data: '{"value": 1}' - }); - }; - protocol.interceptStringProtocol('http', handler, function(error) { + }) + } + protocol.interceptStringProtocol('http', handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ url: 'http://fake-host', - success: function(data) { - assert.equal(typeof data, 'object'); - assert.equal(data.value, 1); - done(); + success: function (data) { + assert.equal(typeof data, 'object') + assert.equal(data.value, 1) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) - it('can receive post data', function(done) { - var handler = function(request, callback) { - var uploadData = request.uploadData[0].bytes.toString(); + it('can receive post data', function (done) { + var handler = function (request, callback) { + var uploadData = request.uploadData[0].bytes.toString() callback({ data: uploadData - }); - }; - protocol.interceptStringProtocol('http', handler, function(error) { + }) + } + protocol.interceptStringProtocol('http', handler, function (error) { if (error) { - return done(error); - } - $.ajax({ - url: "http://fake-host", - type: "POST", - data: postData, - success: function(data) { - assert.deepEqual(qs.parse(data), postData); - done(); - }, - error: function(xhr, errorType, error) { - done(error); - } - }); - }); - }); - }); - - describe('protocol.interceptBufferProtocol', function() { - it('can intercept http protocol', function(done) { - var handler = function(request, callback) { - callback(new Buffer(text)); - }; - protocol.interceptBufferProtocol('http', handler, function(error) { - if (error) { - return done(error); + return done(error) } $.ajax({ url: 'http://fake-host', - success: function(data) { - assert.equal(data, text); - done(); + type: 'POST', + data: postData, + success: function (data) { + assert.deepEqual(qs.parse(data), postData) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); + }) + }) + }) + }) - it('can receive post data', function(done) { - var handler = function(request, callback) { - var uploadData = request.uploadData[0].bytes; - callback(uploadData); - }; - protocol.interceptBufferProtocol('http', handler, function(error) { + describe('protocol.interceptBufferProtocol', function () { + it('can intercept http protocol', function (done) { + var handler = function (request, callback) { + callback(new Buffer(text)) + } + protocol.interceptBufferProtocol('http', handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: "http://fake-host", - type: "POST", - data: postData, - success: function(data) { - assert.equal(data, $.param(postData)); - done(); + url: 'http://fake-host', + success: function (data) { + assert.equal(data, text) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); - }); + }) + }) + }) - describe('protocol.interceptHttpProtocol', function() { - it('can send POST request', function(done) { - var server = http.createServer(function(req, res) { - var body = ''; - req.on('data', function(chunk) { - body += chunk; - }); - req.on('end', function() { - res.end(body); - }); - server.close(); - }); - server.listen(0, '127.0.0.1', function() { - var port = server.address().port; - var url = "http://127.0.0.1:" + port; - var handler = function(request, callback) { + it('can receive post data', function (done) { + var handler = function (request, callback) { + var uploadData = request.uploadData[0].bytes + callback(uploadData) + } + protocol.interceptBufferProtocol('http', handler, function (error) { + if (error) { + return done(error) + } + $.ajax({ + url: 'http://fake-host', + type: 'POST', + data: postData, + success: function (data) { + assert.equal(data, $.param(postData)) + done() + }, + error: function (xhr, errorType, error) { + done(error) + } + }) + }) + }) + }) + + describe('protocol.interceptHttpProtocol', function () { + it('can send POST request', function (done) { + var server = http.createServer(function (req, res) { + var body = '' + req.on('data', function (chunk) { + body += chunk + }) + req.on('end', function () { + res.end(body) + }) + server.close() + }) + server.listen(0, '127.0.0.1', function () { + var port = server.address().port + var url = 'http://127.0.0.1:' + port + var handler = function (request, callback) { var data = { url: url, method: 'POST', @@ -775,43 +775,43 @@ describe('protocol module', function() { data: request.uploadData[0].bytes.toString() }, session: null - }; - callback(data); - }; - protocol.interceptHttpProtocol('http', handler, function(error) { + } + callback(data) + } + protocol.interceptHttpProtocol('http', handler, function (error) { if (error) { - return done(error); + return done(error) } $.ajax({ - url: "http://fake-host", - type: "POST", + url: 'http://fake-host', + type: 'POST', data: postData, - success: function(data) { - assert.deepEqual(qs.parse(data), postData); - done(); + success: function (data) { + assert.deepEqual(qs.parse(data), postData) + done() }, - error: function(xhr, errorType, error) { - done(error); + error: function (xhr, errorType, error) { + done(error) } - }); - }); - }); - }); - }); + }) + }) + }) + }) + }) - describe('protocol.uninterceptProtocol', function() { - it('returns error when scheme does not exist', function(done) { - protocol.uninterceptProtocol('not-exist', function(error) { - assert.notEqual(error, null); - done(); - }); - }); + describe('protocol.uninterceptProtocol', function () { + it('returns error when scheme does not exist', function (done) { + protocol.uninterceptProtocol('not-exist', function (error) { + assert.notEqual(error, null) + done() + }) + }) - it('returns error when scheme is not intercepted', function(done) { - protocol.uninterceptProtocol('http', function(error) { - assert.notEqual(error, null); - done(); - }); - }); - }); -}); + it('returns error when scheme is not intercepted', function (done) { + protocol.uninterceptProtocol('http', function (error) { + assert.notEqual(error, null) + done() + }) + }) + }) +}) diff --git a/spec/api-screen-spec.js b/spec/api-screen-spec.js index 34828e863e8..8c4f4305baf 100644 --- a/spec/api-screen-spec.js +++ b/spec/api-screen-spec.js @@ -1,21 +1,21 @@ -const assert = require('assert'); -const screen = require('electron').screen; +const assert = require('assert') +const screen = require('electron').screen -describe('screen module', function() { - describe('screen.getCursorScreenPoint()', function() { - it('returns a point object', function() { - var point = screen.getCursorScreenPoint(); - assert.equal(typeof point.x, 'number'); - assert.equal(typeof point.y, 'number'); - }); - }); +describe('screen module', function () { + describe('screen.getCursorScreenPoint()', function () { + it('returns a point object', function () { + var point = screen.getCursorScreenPoint() + assert.equal(typeof point.x, 'number') + assert.equal(typeof point.y, 'number') + }) + }) - describe('screen.getPrimaryDisplay()', function() { - it('returns a display object', function() { - var display = screen.getPrimaryDisplay(); - assert.equal(typeof display.scaleFactor, 'number'); - assert(display.size.width > 0); - assert(display.size.height > 0); - }); - }); -}); + describe('screen.getPrimaryDisplay()', function () { + it('returns a display object', function () { + var display = screen.getPrimaryDisplay() + assert.equal(typeof display.scaleFactor, 'number') + assert(display.size.width > 0) + assert(display.size.height > 0) + }) + }) +}) diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index 9fedcc29e77..2f4a50f69e5 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -1,265 +1,265 @@ -const assert = require('assert'); -const http = require('http'); -const path = require('path'); -const fs = require('fs'); +const assert = require('assert') +const http = require('http') +const path = require('path') +const fs = require('fs') -const ipcRenderer = require('electron').ipcRenderer; -const remote = require('electron').remote; +const ipcRenderer = require('electron').ipcRenderer +const remote = require('electron').remote -const ipcMain = remote.ipcMain; -const session = remote.session; -const BrowserWindow = remote.BrowserWindow; +const ipcMain = remote.ipcMain +const session = remote.session +const BrowserWindow = remote.BrowserWindow -describe('session module', function() { - this.timeout(10000); +describe('session module', function () { + this.timeout(10000) - var fixtures = path.resolve(__dirname, 'fixtures'); - var w = null; - var url = "http://127.0.0.1"; + var fixtures = path.resolve(__dirname, 'fixtures') + var w = null + var url = 'http://127.0.0.1' - beforeEach(function() { + beforeEach(function () { w = new BrowserWindow({ show: false, width: 400, height: 400 - }); - }); + }) + }) - afterEach(function() { - w.destroy(); - }); + afterEach(function () { + w.destroy() + }) - describe('session.cookies', function() { - it('should get cookies', function(done) { - var server = http.createServer(function(req, res) { - res.setHeader('Set-Cookie', ['0=0']); - res.end('finished'); - server.close(); - }); - server.listen(0, '127.0.0.1', function() { - var port = server.address().port; - w.loadURL(url + ":" + port); - w.webContents.on('did-finish-load', function() { + describe('session.cookies', function () { + it('should get cookies', function (done) { + var server = http.createServer(function (req, res) { + res.setHeader('Set-Cookie', ['0=0']) + res.end('finished') + server.close() + }) + server.listen(0, '127.0.0.1', function () { + var port = server.address().port + w.loadURL(url + ':' + port) + w.webContents.on('did-finish-load', function () { w.webContents.session.cookies.get({ url: url - }, function(error, list) { - var cookie, i, len; + }, function (error, list) { + var cookie, i, len if (error) { - return done(error); + return done(error) } for (i = 0, len = list.length; i < len; i++) { - cookie = list[i]; + cookie = list[i] if (cookie.name === '0') { if (cookie.value === '0') { - return done(); + return done() } else { - return done("cookie value is " + cookie.value + " while expecting 0"); + return done('cookie value is ' + cookie.value + ' while expecting 0') } } } - done('Can not find cookie'); - }); - }); - }); - }); + done('Can not find cookie') + }) + }) + }) + }) - it('should over-write the existent cookie', function(done) { + it('should over-write the existent cookie', function (done) { session.defaultSession.cookies.set({ url: url, name: '1', value: '1' - }, function(error) { + }, function (error) { if (error) { - return done(error); + return done(error) } session.defaultSession.cookies.get({ url: url - }, function(error, list) { - var cookie, i, len; + }, function (error, list) { + var cookie, i, len if (error) { - return done(error); + return done(error) } for (i = 0, len = list.length; i < len; i++) { - cookie = list[i]; + cookie = list[i] if (cookie.name === '1') { if (cookie.value === '1') { - return done(); + return done() } else { - return done("cookie value is " + cookie.value + " while expecting 1"); + return done('cookie value is ' + cookie.value + ' while expecting 1') } } } - done('Can not find cookie'); - }); - }); - }); + done('Can not find cookie') + }) + }) + }) - it('should remove cookies', function(done) { + it('should remove cookies', function (done) { session.defaultSession.cookies.set({ url: url, name: '2', value: '2' - }, function(error) { + }, function (error) { if (error) { - return done(error); + return done(error) } - session.defaultSession.cookies.remove(url, '2', function() { + session.defaultSession.cookies.remove(url, '2', function () { session.defaultSession.cookies.get({ url: url - }, function(error, list) { - var cookie, i, len; + }, function (error, list) { + var cookie, i, len if (error) { - return done(error); + return done(error) } for (i = 0, len = list.length; i < len; i++) { - cookie = list[i]; + cookie = list[i] if (cookie.name === '2') { - return done('Cookie not deleted'); + return done('Cookie not deleted') } } - done(); - }); - }); - }); - }); - }); + done() + }) + }) + }) + }) + }) - describe('session.clearStorageData(options)', function() { - fixtures = path.resolve(__dirname, 'fixtures'); - it('clears localstorage data', function(done) { - ipcMain.on('count', function(event, count) { - ipcMain.removeAllListeners('count'); - assert(!count); - done(); - }); - w.loadURL('file://' + path.join(fixtures, 'api', 'localstorage.html')); - w.webContents.on('did-finish-load', function() { + describe('session.clearStorageData(options)', function () { + fixtures = path.resolve(__dirname, 'fixtures') + it('clears localstorage data', function (done) { + ipcMain.on('count', function (event, count) { + ipcMain.removeAllListeners('count') + assert(!count) + done() + }) + w.loadURL('file://' + path.join(fixtures, 'api', 'localstorage.html')) + w.webContents.on('did-finish-load', function () { var options = { - origin: "file://", + origin: 'file://', storages: ['localstorage'], quotas: ['persistent'] - }; - w.webContents.session.clearStorageData(options, function() { - w.webContents.send('getcount'); - }); - }); - }); - }); + } + w.webContents.session.clearStorageData(options, function () { + w.webContents.send('getcount') + }) + }) + }) + }) - describe('session will-download event', function() { - var w = null; + describe('session will-download event', function () { + var w = null - beforeEach(function() { + beforeEach(function () { w = new BrowserWindow({ show: false, width: 400, height: 400 - }); - }); + }) + }) - afterEach(function() { - w.destroy(); - }); + afterEach(function () { + w.destroy() + }) - it('can cancel default download behavior', function(done) { - const mockFile = new Buffer(1024); - const contentDisposition = 'inline; filename="mockFile.txt"'; - const downloadServer = http.createServer(function(req, res) { + it('can cancel default download behavior', function (done) { + const mockFile = new Buffer(1024) + const contentDisposition = 'inline; filename="mockFile.txt"' + const downloadServer = http.createServer(function (req, res) { res.writeHead(200, { 'Content-Length': mockFile.length, 'Content-Type': 'application/plain', 'Content-Disposition': contentDisposition - }); - res.end(mockFile); - downloadServer.close(); - }); + }) + res.end(mockFile) + downloadServer.close() + }) - downloadServer.listen(0, '127.0.0.1', function() { - const port = downloadServer.address().port; - const url = "http://127.0.0.1:" + port + '/'; + downloadServer.listen(0, '127.0.0.1', function () { + const port = downloadServer.address().port + const url = 'http://127.0.0.1:' + port + '/' - ipcRenderer.sendSync('set-download-option', false, true); - w.loadURL(url); - ipcRenderer.once('download-error', function(event, downloadUrl, filename, error) { - assert.equal(downloadUrl, url); - assert.equal(filename, 'mockFile.txt'); - assert.equal(error, 'Object has been destroyed'); - done(); - }); - }); - }); - }); + ipcRenderer.sendSync('set-download-option', false, true) + w.loadURL(url) + ipcRenderer.once('download-error', function (event, downloadUrl, filename, error) { + assert.equal(downloadUrl, url) + assert.equal(filename, 'mockFile.txt') + assert.equal(error, 'Object has been destroyed') + done() + }) + }) + }) + }) - describe('DownloadItem', function() { - var mockPDF = new Buffer(1024 * 1024 * 5); - var contentDisposition = 'inline; filename="mock.pdf"'; - var downloadFilePath = path.join(fixtures, 'mock.pdf'); - var downloadServer = http.createServer(function(req, res) { + describe('DownloadItem', function () { + var mockPDF = new Buffer(1024 * 1024 * 5) + var contentDisposition = 'inline; filename="mock.pdf"' + var downloadFilePath = path.join(fixtures, 'mock.pdf') + var downloadServer = http.createServer(function (req, res) { res.writeHead(200, { 'Content-Length': mockPDF.length, 'Content-Type': 'application/pdf', 'Content-Disposition': contentDisposition - }); - res.end(mockPDF); - downloadServer.close(); - }); - var assertDownload = function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port) { - assert.equal(state, 'completed'); - assert.equal(filename, 'mock.pdf'); - assert.equal(url, "http://127.0.0.1:" + port + "/"); - assert.equal(mimeType, 'application/pdf'); - assert.equal(receivedBytes, mockPDF.length); - assert.equal(totalBytes, mockPDF.length); - assert.equal(disposition, contentDisposition); - assert(fs.existsSync(downloadFilePath)); - fs.unlinkSync(downloadFilePath); - }; + }) + res.end(mockPDF) + downloadServer.close() + }) + var assertDownload = function (event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port) { + assert.equal(state, 'completed') + assert.equal(filename, 'mock.pdf') + assert.equal(url, 'http://127.0.0.1:' + port + '/') + assert.equal(mimeType, 'application/pdf') + assert.equal(receivedBytes, mockPDF.length) + assert.equal(totalBytes, mockPDF.length) + assert.equal(disposition, contentDisposition) + assert(fs.existsSync(downloadFilePath)) + fs.unlinkSync(downloadFilePath) + } - it('can download using BrowserWindow.loadURL', function(done) { - downloadServer.listen(0, '127.0.0.1', function() { - var port = downloadServer.address().port; - ipcRenderer.sendSync('set-download-option', false, false); - w.loadURL(url + ":" + port); - ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { - assertDownload(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port); - done(); - }); - }); - }); + it('can download using BrowserWindow.loadURL', function (done) { + downloadServer.listen(0, '127.0.0.1', function () { + var port = downloadServer.address().port + ipcRenderer.sendSync('set-download-option', false, false) + w.loadURL(url + ':' + port) + ipcRenderer.once('download-done', function (event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { + assertDownload(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port) + done() + }) + }) + }) - it('can download using WebView.downloadURL', function(done) { - downloadServer.listen(0, '127.0.0.1', function() { - var port = downloadServer.address().port; - ipcRenderer.sendSync('set-download-option', false, false); - var webview = new WebView; - webview.src = "file://" + fixtures + "/api/blank.html"; - webview.addEventListener('did-finish-load', function() { - webview.downloadURL(url + ":" + port + "/"); - }); - ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { - assertDownload(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port); - document.body.removeChild(webview); - done(); - }); - document.body.appendChild(webview); - }); - }); + it('can download using WebView.downloadURL', function (done) { + downloadServer.listen(0, '127.0.0.1', function () { + var port = downloadServer.address().port + ipcRenderer.sendSync('set-download-option', false, false) + var webview = new WebView + webview.src = 'file://' + fixtures + '/api/blank.html' + webview.addEventListener('did-finish-load', function () { + webview.downloadURL(url + ':' + port + '/') + }) + ipcRenderer.once('download-done', function (event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { + assertDownload(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename, port) + document.body.removeChild(webview) + done() + }) + document.body.appendChild(webview) + }) + }) - it('can cancel download', function(done) { - downloadServer.listen(0, '127.0.0.1', function() { - var port = downloadServer.address().port; - ipcRenderer.sendSync('set-download-option', true, false); - w.loadURL(url + ":" + port + "/"); - ipcRenderer.once('download-done', function(event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { - assert.equal(state, 'cancelled'); - assert.equal(filename, 'mock.pdf'); - assert.equal(mimeType, 'application/pdf'); - assert.equal(receivedBytes, 0); - assert.equal(totalBytes, mockPDF.length); - assert.equal(disposition, contentDisposition); - done(); - }); - }); - }); - }); -}); + it('can cancel download', function (done) { + downloadServer.listen(0, '127.0.0.1', function () { + var port = downloadServer.address().port + ipcRenderer.sendSync('set-download-option', true, false) + w.loadURL(url + ':' + port + '/') + ipcRenderer.once('download-done', function (event, state, url, mimeType, receivedBytes, totalBytes, disposition, filename) { + assert.equal(state, 'cancelled') + assert.equal(filename, 'mock.pdf') + assert.equal(mimeType, 'application/pdf') + assert.equal(receivedBytes, 0) + assert.equal(totalBytes, mockPDF.length) + assert.equal(disposition, contentDisposition) + done() + }) + }) + }) + }) +}) diff --git a/spec/api-web-frame-spec.js b/spec/api-web-frame-spec.js index 15f31aa8f09..519966c8cea 100644 --- a/spec/api-web-frame-spec.js +++ b/spec/api-web-frame-spec.js @@ -1,19 +1,19 @@ -const assert = require('assert'); -const path = require('path'); -const webFrame = require('electron').webFrame; +const assert = require('assert') +const path = require('path') +const webFrame = require('electron').webFrame -describe('webFrame module', function() { - var fixtures = path.resolve(__dirname, 'fixtures'); - describe('webFrame.registerURLSchemeAsPrivileged', function() { - it('supports fetch api', function(done) { - webFrame.registerURLSchemeAsPrivileged('file'); - var url = "file://" + fixtures + "/assets/logo.png"; - fetch(url).then(function(response) { - assert(response.ok); - done(); - }).catch(function(err) { - done('unexpected error : ' + err); - }); - }); - }); -}); +describe('webFrame module', function () { + var fixtures = path.resolve(__dirname, 'fixtures') + describe('webFrame.registerURLSchemeAsPrivileged', function () { + it('supports fetch api', function (done) { + webFrame.registerURLSchemeAsPrivileged('file') + var url = 'file://' + fixtures + '/assets/logo.png' + fetch(url).then(function (response) { + assert(response.ok) + done() + }).catch(function (err) { + done('unexpected error : ' + err) + }) + }) + }) +}) diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index 77f160a2004..abc4f9568cd 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -1,413 +1,412 @@ -const assert = require('assert'); -const http = require('http'); -const qs = require('querystring'); -const remote = require('electron').remote; -const session = remote.session; +const assert = require('assert') +const http = require('http') +const qs = require('querystring') +const remote = require('electron').remote +const session = remote.session -describe('webRequest module', function() { - var ses = session.defaultSession; - var server = http.createServer(function(req, res) { - res.setHeader('Custom', ['Header']); - var content = req.url; +describe('webRequest module', function () { + var ses = session.defaultSession + var server = http.createServer(function (req, res) { + res.setHeader('Custom', ['Header']) + var content = req.url if (req.headers.accept === '*/*;test/header') { - content += 'header/received'; + content += 'header/received' } - res.end(content); - }); - var defaultURL = null; + res.end(content) + }) + var defaultURL = null - before(function(done) { - server.listen(0, '127.0.0.1', function() { - var port = server.address().port; - defaultURL = "http://127.0.0.1:" + port + "/"; - done(); - }); - }); + before(function (done) { + server.listen(0, '127.0.0.1', function () { + var port = server.address().port + defaultURL = 'http://127.0.0.1:' + port + '/' + done() + }) + }) - after(function() { - server.close(); - }); + after(function () { + server.close() + }) - describe('webRequest.onBeforeRequest', function() { - afterEach(function() { - ses.webRequest.onBeforeRequest(null); - }); + describe('webRequest.onBeforeRequest', function () { + afterEach(function () { + ses.webRequest.onBeforeRequest(null) + }) - it('can cancel the request', function(done) { - ses.webRequest.onBeforeRequest(function(details, callback) { + it('can cancel the request', function (done) { + ses.webRequest.onBeforeRequest(function (details, callback) { callback({ cancel: true - }); - }); + }) + }) $.ajax({ url: defaultURL, - success: function() { - done('unexpected success'); + success: function () { + done('unexpected success') }, - error: function() { - done(); + error: function () { + done() } - }); - }); + }) + }) - it('can filter URLs', function(done) { + it('can filter URLs', function (done) { var filter = { - urls: [defaultURL + "filter/*"] - }; - ses.webRequest.onBeforeRequest(filter, function(details, callback) { + urls: [defaultURL + 'filter/*'] + } + ses.webRequest.onBeforeRequest(filter, function (details, callback) { callback({ cancel: true - }); - }); + }) + }) $.ajax({ - url: defaultURL + "nofilter/test", - success: function(data) { - assert.equal(data, '/nofilter/test'); + url: defaultURL + 'nofilter/test', + success: function (data) { + assert.equal(data, '/nofilter/test') $.ajax({ - url: defaultURL + "filter/test", - success: function() { - done('unexpected success'); + url: defaultURL + 'filter/test', + success: function () { + done('unexpected success') }, - error: function() { - done(); + error: function () { + done() } - }); + }) }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); + }) + }) - it('receives details object', function(done) { - ses.webRequest.onBeforeRequest(function(details, callback) { - assert.equal(typeof details.id, 'number'); - assert.equal(typeof details.timestamp, 'number'); - assert.equal(details.url, defaultURL); - assert.equal(details.method, 'GET'); - assert.equal(details.resourceType, 'xhr'); - assert(!details.uploadData); - callback({}); - }); + it('receives details object', function (done) { + ses.webRequest.onBeforeRequest(function (details, callback) { + assert.equal(typeof details.id, 'number') + assert.equal(typeof details.timestamp, 'number') + assert.equal(details.url, defaultURL) + assert.equal(details.method, 'GET') + assert.equal(details.resourceType, 'xhr') + assert(!details.uploadData) + callback({}) + }) $.ajax({ url: defaultURL, - success: function(data) { - assert.equal(data, '/'); - done(); + success: function (data) { + assert.equal(data, '/') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); + }) + }) - it('receives post data in details object', function(done) { + it('receives post data in details object', function (done) { var postData = { name: 'post test', type: 'string' - }; - ses.webRequest.onBeforeRequest(function(details, callback) { - assert.equal(details.url, defaultURL); - assert.equal(details.method, 'POST'); - assert.equal(details.uploadData.length, 1); - var data = qs.parse(details.uploadData[0].bytes.toString()); - assert.deepEqual(data, postData); + } + ses.webRequest.onBeforeRequest(function (details, callback) { + assert.equal(details.url, defaultURL) + assert.equal(details.method, 'POST') + assert.equal(details.uploadData.length, 1) + var data = qs.parse(details.uploadData[0].bytes.toString()) + assert.deepEqual(data, postData) callback({ cancel: true - }); - }); + }) + }) $.ajax({ url: defaultURL, type: 'POST', data: postData, - success: function() { - }, - error: function() { - done(); + success: function () {}, + error: function () { + done() } - }); - }); + }) + }) - it('can redirect the request', function(done) { - ses.webRequest.onBeforeRequest(function(details, callback) { + it('can redirect the request', function (done) { + ses.webRequest.onBeforeRequest(function (details, callback) { if (details.url === defaultURL) { callback({ - redirectURL: defaultURL + "redirect" - }); + redirectURL: defaultURL + 'redirect' + }) } else { - callback({}); + callback({}) } - }); + }) $.ajax({ url: defaultURL, - success: function(data) { - assert.equal(data, '/redirect'); - done(); + success: function (data) { + assert.equal(data, '/redirect') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); - }); + }) + }) + }) - describe('webRequest.onBeforeSendHeaders', function() { - afterEach(function() { - ses.webRequest.onBeforeSendHeaders(null); - }); + describe('webRequest.onBeforeSendHeaders', function () { + afterEach(function () { + ses.webRequest.onBeforeSendHeaders(null) + }) - it('receives details object', function(done) { - ses.webRequest.onBeforeSendHeaders(function(details, callback) { - assert.equal(typeof details.requestHeaders, 'object'); - callback({}); - }); + it('receives details object', function (done) { + ses.webRequest.onBeforeSendHeaders(function (details, callback) { + assert.equal(typeof details.requestHeaders, 'object') + callback({}) + }) $.ajax({ url: defaultURL, - success: function(data) { - assert.equal(data, '/'); - done(); + success: function (data) { + assert.equal(data, '/') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); + }) + }) - it('can change the request headers', function(done) { - ses.webRequest.onBeforeSendHeaders(function(details, callback) { - var requestHeaders = details.requestHeaders; - requestHeaders.Accept = '*/*;test/header'; + it('can change the request headers', function (done) { + ses.webRequest.onBeforeSendHeaders(function (details, callback) { + var requestHeaders = details.requestHeaders + requestHeaders.Accept = '*/*;test/header' callback({ requestHeaders: requestHeaders - }); - }); + }) + }) $.ajax({ url: defaultURL, - success: function(data) { - assert.equal(data, '/header/received'); - done(); + success: function (data) { + assert.equal(data, '/header/received') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); + }) + }) - it('resets the whole headers', function(done) { + it('resets the whole headers', function (done) { var requestHeaders = { Test: 'header' - }; - ses.webRequest.onBeforeSendHeaders(function(details, callback) { + } + ses.webRequest.onBeforeSendHeaders(function (details, callback) { callback({ requestHeaders: requestHeaders - }); - }); - ses.webRequest.onSendHeaders(function(details) { - assert.deepEqual(details.requestHeaders, requestHeaders); - done(); - }); + }) + }) + ses.webRequest.onSendHeaders(function (details) { + assert.deepEqual(details.requestHeaders, requestHeaders) + done() + }) $.ajax({ url: defaultURL, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); - }); + }) + }) + }) - describe('webRequest.onSendHeaders', function() { - afterEach(function() { - ses.webRequest.onSendHeaders(null); - }); + describe('webRequest.onSendHeaders', function () { + afterEach(function () { + ses.webRequest.onSendHeaders(null) + }) - it('receives details object', function(done) { - ses.webRequest.onSendHeaders(function(details) { - assert.equal(typeof details.requestHeaders, 'object'); - }); + it('receives details object', function (done) { + ses.webRequest.onSendHeaders(function (details) { + assert.equal(typeof details.requestHeaders, 'object') + }) $.ajax({ url: defaultURL, - success: function(data) { - assert.equal(data, '/'); - done(); + success: function (data) { + assert.equal(data, '/') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); - }); + }) + }) + }) - describe('webRequest.onHeadersReceived', function() { - afterEach(function() { - ses.webRequest.onHeadersReceived(null); - }); + describe('webRequest.onHeadersReceived', function () { + afterEach(function () { + ses.webRequest.onHeadersReceived(null) + }) - it('receives details object', function(done) { - ses.webRequest.onHeadersReceived(function(details, callback) { - assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); - assert.equal(details.statusCode, 200); - assert.equal(details.responseHeaders['Custom'], 'Header'); - callback({}); - }); + it('receives details object', function (done) { + ses.webRequest.onHeadersReceived(function (details, callback) { + assert.equal(details.statusLine, 'HTTP/1.1 200 OK') + assert.equal(details.statusCode, 200) + assert.equal(details.responseHeaders['Custom'], 'Header') + callback({}) + }) $.ajax({ url: defaultURL, - success: function(data) { - assert.equal(data, '/'); - done(); + success: function (data) { + assert.equal(data, '/') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); + }) + }) - it('can change the response header', function(done) { - ses.webRequest.onHeadersReceived(function(details, callback) { - var responseHeaders = details.responseHeaders; - responseHeaders['Custom'] = ['Changed']; + it('can change the response header', function (done) { + ses.webRequest.onHeadersReceived(function (details, callback) { + var responseHeaders = details.responseHeaders + responseHeaders['Custom'] = ['Changed'] callback({ responseHeaders: responseHeaders - }); - }); + }) + }) $.ajax({ url: defaultURL, - success: function(data, status, xhr) { - assert.equal(xhr.getResponseHeader('Custom'), 'Changed'); - assert.equal(data, '/'); - done(); + success: function (data, status, xhr) { + assert.equal(xhr.getResponseHeader('Custom'), 'Changed') + assert.equal(data, '/') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); + }) + }) - it('does not change header by default', function(done) { - ses.webRequest.onHeadersReceived(function(details, callback) { - callback({}); - }); + it('does not change header by default', function (done) { + ses.webRequest.onHeadersReceived(function (details, callback) { + callback({}) + }) $.ajax({ url: defaultURL, - success: function(data, status, xhr) { - assert.equal(xhr.getResponseHeader('Custom'), 'Header'); - assert.equal(data, '/'); - done(); + success: function (data, status, xhr) { + assert.equal(xhr.getResponseHeader('Custom'), 'Header') + assert.equal(data, '/') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); - }); + }) + }) + }) - describe('webRequest.onResponseStarted', function() { - afterEach(function() { - ses.webRequest.onResponseStarted(null); - }); + describe('webRequest.onResponseStarted', function () { + afterEach(function () { + ses.webRequest.onResponseStarted(null) + }) - it('receives details object', function(done) { - ses.webRequest.onResponseStarted(function(details) { - assert.equal(typeof details.fromCache, 'boolean'); - assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); - assert.equal(details.statusCode, 200); - assert.equal(details.responseHeaders['Custom'], 'Header'); - }); + it('receives details object', function (done) { + ses.webRequest.onResponseStarted(function (details) { + assert.equal(typeof details.fromCache, 'boolean') + assert.equal(details.statusLine, 'HTTP/1.1 200 OK') + assert.equal(details.statusCode, 200) + assert.equal(details.responseHeaders['Custom'], 'Header') + }) $.ajax({ url: defaultURL, - success: function(data, status, xhr) { - assert.equal(xhr.getResponseHeader('Custom'), 'Header'); - assert.equal(data, '/'); - done(); + success: function (data, status, xhr) { + assert.equal(xhr.getResponseHeader('Custom'), 'Header') + assert.equal(data, '/') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); - }); + }) + }) + }) - describe('webRequest.onBeforeRedirect', function() { - afterEach(function() { - ses.webRequest.onBeforeRedirect(null); - ses.webRequest.onBeforeRequest(null); - }); + describe('webRequest.onBeforeRedirect', function () { + afterEach(function () { + ses.webRequest.onBeforeRedirect(null) + ses.webRequest.onBeforeRequest(null) + }) - it('receives details object', function(done) { - var redirectURL = defaultURL + "redirect"; - ses.webRequest.onBeforeRequest(function(details, callback) { + it('receives details object', function (done) { + var redirectURL = defaultURL + 'redirect' + ses.webRequest.onBeforeRequest(function (details, callback) { if (details.url === defaultURL) { callback({ redirectURL: redirectURL - }); + }) } else { - callback({}); + callback({}) } - }); - ses.webRequest.onBeforeRedirect(function(details) { - assert.equal(typeof details.fromCache, 'boolean'); - assert.equal(details.statusLine, 'HTTP/1.1 307 Internal Redirect'); - assert.equal(details.statusCode, 307); - assert.equal(details.redirectURL, redirectURL); - }); + }) + ses.webRequest.onBeforeRedirect(function (details) { + assert.equal(typeof details.fromCache, 'boolean') + assert.equal(details.statusLine, 'HTTP/1.1 307 Internal Redirect') + assert.equal(details.statusCode, 307) + assert.equal(details.redirectURL, redirectURL) + }) $.ajax({ url: defaultURL, - success: function(data) { - assert.equal(data, '/redirect'); - done(); + success: function (data) { + assert.equal(data, '/redirect') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); - }); + }) + }) + }) - describe('webRequest.onCompleted', function() { - afterEach(function() { - ses.webRequest.onCompleted(null); - }); + describe('webRequest.onCompleted', function () { + afterEach(function () { + ses.webRequest.onCompleted(null) + }) - it('receives details object', function(done) { - ses.webRequest.onCompleted(function(details) { - assert.equal(typeof details.fromCache, 'boolean'); - assert.equal(details.statusLine, 'HTTP/1.1 200 OK'); - assert.equal(details.statusCode, 200); - }); + it('receives details object', function (done) { + ses.webRequest.onCompleted(function (details) { + assert.equal(typeof details.fromCache, 'boolean') + assert.equal(details.statusLine, 'HTTP/1.1 200 OK') + assert.equal(details.statusCode, 200) + }) $.ajax({ url: defaultURL, - success: function(data) { - assert.equal(data, '/'); - done(); + success: function (data) { + assert.equal(data, '/') + done() }, - error: function(xhr, errorType) { - done(errorType); + error: function (xhr, errorType) { + done(errorType) } - }); - }); - }); + }) + }) + }) - describe('webRequest.onErrorOccurred', function() { - afterEach(function() { - ses.webRequest.onErrorOccurred(null); - ses.webRequest.onBeforeRequest(null); - }); + describe('webRequest.onErrorOccurred', function () { + afterEach(function () { + ses.webRequest.onErrorOccurred(null) + ses.webRequest.onBeforeRequest(null) + }) - it('receives details object', function(done) { - ses.webRequest.onBeforeRequest(function(details, callback) { + it('receives details object', function (done) { + ses.webRequest.onBeforeRequest(function (details, callback) { callback({ cancel: true - }); - }); - ses.webRequest.onErrorOccurred(function(details) { - assert.equal(details.error, 'net::ERR_BLOCKED_BY_CLIENT'); - done(); - }); + }) + }) + ses.webRequest.onErrorOccurred(function (details) { + assert.equal(details.error, 'net::ERR_BLOCKED_BY_CLIENT') + done() + }) $.ajax({ url: defaultURL, - success: function() { - done('unexpected success'); + success: function () { + done('unexpected success') } - }); - }); - }); -}); + }) + }) + }) +}) diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 0e0a7f89f17..050d8d7deda 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -1,813 +1,813 @@ -const assert = require('assert'); -const child_process = require('child_process'); -const fs = require('fs'); -const path = require('path'); +const assert = require('assert') +const child_process = require('child_process') +const fs = require('fs') +const path = require('path') -const nativeImage = require('electron').nativeImage; -const remote = require('electron').remote; +const nativeImage = require('electron').nativeImage +const remote = require('electron').remote -const ipcMain = remote.require('electron').ipcMain; -const BrowserWindow = remote.require('electron').BrowserWindow; +const ipcMain = remote.require('electron').ipcMain +const BrowserWindow = remote.require('electron').BrowserWindow -describe('asar package', function() { - var fixtures = path.join(__dirname, 'fixtures'); +describe('asar package', function () { + var fixtures = path.join(__dirname, 'fixtures') - describe('node api', function() { - describe('fs.readFileSync', function() { - it('does not leak fd', function() { - var readCalls = 1; + describe('node api', function () { + describe('fs.readFileSync', function () { + it('does not leak fd', function () { + var readCalls = 1 while(readCalls <= 10000) { - fs.readFileSync(path.join(process.resourcesPath, 'atom.asar', 'renderer', 'api', 'ipc.js')); - readCalls++; + fs.readFileSync(path.join(process.resourcesPath, 'atom.asar', 'renderer', 'api', 'ipc.js')) + readCalls++ } - }); + }) - it('reads a normal file', function() { - var file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); - assert.equal(fs.readFileSync(file1).toString().trim(), 'file1'); - var file2 = path.join(fixtures, 'asar', 'a.asar', 'file2'); - assert.equal(fs.readFileSync(file2).toString().trim(), 'file2'); - var file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); - assert.equal(fs.readFileSync(file3).toString().trim(), 'file3'); - }); + it('reads a normal file', function () { + var file1 = path.join(fixtures, 'asar', 'a.asar', 'file1') + assert.equal(fs.readFileSync(file1).toString().trim(), 'file1') + var file2 = path.join(fixtures, 'asar', 'a.asar', 'file2') + assert.equal(fs.readFileSync(file2).toString().trim(), 'file2') + var file3 = path.join(fixtures, 'asar', 'a.asar', 'file3') + assert.equal(fs.readFileSync(file3).toString().trim(), 'file3') + }) - it('reads from a empty file', function() { - var file = path.join(fixtures, 'asar', 'empty.asar', 'file1'); - var buffer = fs.readFileSync(file); - assert.equal(buffer.length, 0); - assert.equal(buffer.toString(), ''); - }); + it('reads from a empty file', function () { + var file = path.join(fixtures, 'asar', 'empty.asar', 'file1') + var buffer = fs.readFileSync(file) + assert.equal(buffer.length, 0) + assert.equal(buffer.toString(), '') + }) - it('reads a linked file', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'link1'); - assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); - }); + it('reads a linked file', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'link1') + assert.equal(fs.readFileSync(p).toString().trim(), 'file1') + }) - it('reads a file from linked directory', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1'); - assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); - p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); - assert.equal(fs.readFileSync(p).toString().trim(), 'file1'); - }); + it('reads a file from linked directory', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1') + assert.equal(fs.readFileSync(p).toString().trim(), 'file1') + p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1') + assert.equal(fs.readFileSync(p).toString().trim(), 'file1') + }) - it('throws ENOENT error when can not find file', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - var throws = function() { - fs.readFileSync(p); - }; - assert.throws(throws, /ENOENT/); - }); + it('throws ENOENT error when can not find file', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') + var throws = function () { + fs.readFileSync(p) + } + assert.throws(throws, /ENOENT/) + }) - it('passes ENOENT error to callback when can not find file', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - var async = false; - fs.readFile(p, function(e) { - assert(async); - assert(/ENOENT/.test(e)); - }); - async = true; - }); + it('passes ENOENT error to callback when can not find file', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') + var async = false + fs.readFile(p, function (e) { + assert(async) + assert(/ENOENT/.test(e)) + }) + async = true + }) - it('reads a normal file with unpacked files', function() { - var p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); - assert.equal(fs.readFileSync(p).toString().trim(), 'a'); - }); - }); + it('reads a normal file with unpacked files', function () { + var p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt') + assert.equal(fs.readFileSync(p).toString().trim(), 'a') + }) + }) - describe('fs.readFile', function() { - it('reads a normal file', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'file1'); - fs.readFile(p, function(err, content) { - assert.equal(err, null); - assert.equal(String(content).trim(), 'file1'); - done(); - }); - }); + describe('fs.readFile', function () { + it('reads a normal file', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'file1') + fs.readFile(p, function (err, content) { + assert.equal(err, null) + assert.equal(String(content).trim(), 'file1') + done() + }) + }) - it('reads from a empty file', function(done) { - var p = path.join(fixtures, 'asar', 'empty.asar', 'file1'); - fs.readFile(p, function(err, content) { - assert.equal(err, null); - assert.equal(String(content), ''); - done(); - }); - }); + it('reads from a empty file', function (done) { + var p = path.join(fixtures, 'asar', 'empty.asar', 'file1') + fs.readFile(p, function (err, content) { + assert.equal(err, null) + assert.equal(String(content), '') + done() + }) + }) - it('reads a linked file', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'link1'); - fs.readFile(p, function(err, content) { - assert.equal(err, null); - assert.equal(String(content).trim(), 'file1'); - done(); - }); - }); + it('reads a linked file', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link1') + fs.readFile(p, function (err, content) { + assert.equal(err, null) + assert.equal(String(content).trim(), 'file1') + done() + }) + }) - it('reads a file from linked directory', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); - fs.readFile(p, function(err, content) { - assert.equal(err, null); - assert.equal(String(content).trim(), 'file1'); - done(); - }); - }); + it('reads a file from linked directory', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1') + fs.readFile(p, function (err, content) { + assert.equal(err, null) + assert.equal(String(content).trim(), 'file1') + done() + }) + }) - it('throws ENOENT error when can not find file', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - fs.readFile(p, function(err) { - assert.equal(err.code, 'ENOENT'); - done(); - }); - }); - }); + it('throws ENOENT error when can not find file', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') + fs.readFile(p, function (err) { + assert.equal(err.code, 'ENOENT') + done() + }) + }) + }) - describe('fs.lstatSync', function() { - it('handles path with trailing slash correctly', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); - fs.lstatSync(p); - fs.lstatSync(p + '/'); - }); + describe('fs.lstatSync', function () { + it('handles path with trailing slash correctly', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1') + fs.lstatSync(p) + fs.lstatSync(p + '/') + }) - it('returns information of root', function() { - var p = path.join(fixtures, 'asar', 'a.asar'); - var stats = fs.lstatSync(p); - assert.equal(stats.isFile(), false); - assert.equal(stats.isDirectory(), true); - assert.equal(stats.isSymbolicLink(), false); - assert.equal(stats.size, 0); - }); + it('returns information of root', function () { + var p = path.join(fixtures, 'asar', 'a.asar') + var stats = fs.lstatSync(p) + assert.equal(stats.isFile(), false) + assert.equal(stats.isDirectory(), true) + assert.equal(stats.isSymbolicLink(), false) + assert.equal(stats.size, 0) + }) - it('returns information of a normal file', function() { - var file, j, len, p, ref2, stats; - ref2 = ['file1', 'file2', 'file3', path.join('dir1', 'file1'), path.join('link2', 'file1')]; + it('returns information of a normal file', function () { + var file, j, len, p, ref2, stats + ref2 = ['file1', 'file2', 'file3', path.join('dir1', 'file1'), path.join('link2', 'file1')] for (j = 0, len = ref2.length; j < len; j++) { - file = ref2[j]; - p = path.join(fixtures, 'asar', 'a.asar', file); - stats = fs.lstatSync(p); - assert.equal(stats.isFile(), true); - assert.equal(stats.isDirectory(), false); - assert.equal(stats.isSymbolicLink(), false); - assert.equal(stats.size, 6); + file = ref2[j] + p = path.join(fixtures, 'asar', 'a.asar', file) + stats = fs.lstatSync(p) + assert.equal(stats.isFile(), true) + assert.equal(stats.isDirectory(), false) + assert.equal(stats.isSymbolicLink(), false) + assert.equal(stats.size, 6) } - }); + }) - it('returns information of a normal directory', function() { - var file, j, len, p, ref2, stats; - ref2 = ['dir1', 'dir2', 'dir3']; + it('returns information of a normal directory', function () { + var file, j, len, p, ref2, stats + ref2 = ['dir1', 'dir2', 'dir3'] for (j = 0, len = ref2.length; j < len; j++) { - file = ref2[j]; - p = path.join(fixtures, 'asar', 'a.asar', file); - stats = fs.lstatSync(p); - assert.equal(stats.isFile(), false); - assert.equal(stats.isDirectory(), true); - assert.equal(stats.isSymbolicLink(), false); - assert.equal(stats.size, 0); + file = ref2[j] + p = path.join(fixtures, 'asar', 'a.asar', file) + stats = fs.lstatSync(p) + assert.equal(stats.isFile(), false) + assert.equal(stats.isDirectory(), true) + assert.equal(stats.isSymbolicLink(), false) + assert.equal(stats.size, 0) } - }); + }) - it('returns information of a linked file', function() { - var file, j, len, p, ref2, stats; - ref2 = ['link1', path.join('dir1', 'link1'), path.join('link2', 'link2')]; + it('returns information of a linked file', function () { + var file, j, len, p, ref2, stats + ref2 = ['link1', path.join('dir1', 'link1'), path.join('link2', 'link2')] for (j = 0, len = ref2.length; j < len; j++) { - file = ref2[j]; - p = path.join(fixtures, 'asar', 'a.asar', file); - stats = fs.lstatSync(p); - assert.equal(stats.isFile(), false); - assert.equal(stats.isDirectory(), false); - assert.equal(stats.isSymbolicLink(), true); - assert.equal(stats.size, 0); + file = ref2[j] + p = path.join(fixtures, 'asar', 'a.asar', file) + stats = fs.lstatSync(p) + assert.equal(stats.isFile(), false) + assert.equal(stats.isDirectory(), false) + assert.equal(stats.isSymbolicLink(), true) + assert.equal(stats.size, 0) } - }); + }) - it('returns information of a linked directory', function() { - var file, j, len, p, ref2, stats; - ref2 = ['link2', path.join('dir1', 'link2'), path.join('link2', 'link2')]; + it('returns information of a linked directory', function () { + var file, j, len, p, ref2, stats + ref2 = ['link2', path.join('dir1', 'link2'), path.join('link2', 'link2')] for (j = 0, len = ref2.length; j < len; j++) { - file = ref2[j]; - p = path.join(fixtures, 'asar', 'a.asar', file); - stats = fs.lstatSync(p); - assert.equal(stats.isFile(), false); - assert.equal(stats.isDirectory(), false); - assert.equal(stats.isSymbolicLink(), true); - assert.equal(stats.size, 0); + file = ref2[j] + p = path.join(fixtures, 'asar', 'a.asar', file) + stats = fs.lstatSync(p) + assert.equal(stats.isFile(), false) + assert.equal(stats.isDirectory(), false) + assert.equal(stats.isSymbolicLink(), true) + assert.equal(stats.size, 0) } - }); + }) - it('throws ENOENT error when can not find file', function() { - var file, j, len, p, ref2, throws; - ref2 = ['file4', 'file5', path.join('dir1', 'file4')]; + it('throws ENOENT error when can not find file', function () { + var file, j, len, p, ref2, throws + ref2 = ['file4', 'file5', path.join('dir1', 'file4')] for (j = 0, len = ref2.length; j < len; j++) { - file = ref2[j]; - p = path.join(fixtures, 'asar', 'a.asar', file); - throws = function() { - fs.lstatSync(p); - }; - assert.throws(throws, /ENOENT/); + file = ref2[j] + p = path.join(fixtures, 'asar', 'a.asar', file) + throws = function () { + fs.lstatSync(p) + } + assert.throws(throws, /ENOENT/) } - }); - }); + }) + }) - describe('fs.lstat', function() { - it('handles path with trailing slash correctly', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1'); - fs.lstat(p + '/', done); - }); + describe('fs.lstat', function () { + it('handles path with trailing slash correctly', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2', 'file1') + fs.lstat(p + '/', done) + }) - it('returns information of root', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar'); - fs.lstat(p, function(err, stats) { - assert.equal(err, null); - assert.equal(stats.isFile(), false); - assert.equal(stats.isDirectory(), true); - assert.equal(stats.isSymbolicLink(), false); - assert.equal(stats.size, 0); - done(); - }); - }); + it('returns information of root', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar') + fs.lstat(p, function (err, stats) { + assert.equal(err, null) + assert.equal(stats.isFile(), false) + assert.equal(stats.isDirectory(), true) + assert.equal(stats.isSymbolicLink(), false) + assert.equal(stats.size, 0) + done() + }) + }) - it('returns information of a normal file', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1'); - fs.lstat(p, function(err, stats) { - assert.equal(err, null); - assert.equal(stats.isFile(), true); - assert.equal(stats.isDirectory(), false); - assert.equal(stats.isSymbolicLink(), false); - assert.equal(stats.size, 6); - done(); - }); - }); + it('returns information of a normal file', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'file1') + fs.lstat(p, function (err, stats) { + assert.equal(err, null) + assert.equal(stats.isFile(), true) + assert.equal(stats.isDirectory(), false) + assert.equal(stats.isSymbolicLink(), false) + assert.equal(stats.size, 6) + done() + }) + }) - it('returns information of a normal directory', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); - fs.lstat(p, function(err, stats) { - assert.equal(err, null); - assert.equal(stats.isFile(), false); - assert.equal(stats.isDirectory(), true); - assert.equal(stats.isSymbolicLink(), false); - assert.equal(stats.size, 0); - done(); - }); - }); + it('returns information of a normal directory', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'dir1') + fs.lstat(p, function (err, stats) { + assert.equal(err, null) + assert.equal(stats.isFile(), false) + assert.equal(stats.isDirectory(), true) + assert.equal(stats.isSymbolicLink(), false) + assert.equal(stats.size, 0) + done() + }) + }) - it('returns information of a linked file', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link1'); - fs.lstat(p, function(err, stats) { - assert.equal(err, null); - assert.equal(stats.isFile(), false); - assert.equal(stats.isDirectory(), false); - assert.equal(stats.isSymbolicLink(), true); - assert.equal(stats.size, 0); - done(); - }); - }); + it('returns information of a linked file', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link1') + fs.lstat(p, function (err, stats) { + assert.equal(err, null) + assert.equal(stats.isFile(), false) + assert.equal(stats.isDirectory(), false) + assert.equal(stats.isSymbolicLink(), true) + assert.equal(stats.size, 0) + done() + }) + }) - it('returns information of a linked directory', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); - fs.lstat(p, function(err, stats) { - assert.equal(err, null); - assert.equal(stats.isFile(), false); - assert.equal(stats.isDirectory(), false); - assert.equal(stats.isSymbolicLink(), true); - assert.equal(stats.size, 0); - done(); - }); - }); + it('returns information of a linked directory', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2') + fs.lstat(p, function (err, stats) { + assert.equal(err, null) + assert.equal(stats.isFile(), false) + assert.equal(stats.isDirectory(), false) + assert.equal(stats.isSymbolicLink(), true) + assert.equal(stats.size, 0) + done() + }) + }) - it('throws ENOENT error when can not find file', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'file4'); - fs.lstat(p, function(err) { - assert.equal(err.code, 'ENOENT'); - done(); - }); - }); - }); + it('throws ENOENT error when can not find file', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'file4') + fs.lstat(p, function (err) { + assert.equal(err.code, 'ENOENT') + done() + }) + }) + }) - describe('fs.realpathSync', function() { - it('returns real path root', function() { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = 'a.asar'; - var r = fs.realpathSync(path.join(parent, p)); - assert.equal(r, path.join(parent, p)); - }); + describe('fs.realpathSync', function () { + it('returns real path root', function () { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = 'a.asar' + var r = fs.realpathSync(path.join(parent, p)) + assert.equal(r, path.join(parent, p)) + }) - it('returns real path of a normal file', function() { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('a.asar', 'file1'); - var r = fs.realpathSync(path.join(parent, p)); - assert.equal(r, path.join(parent, p)); - }); + it('returns real path of a normal file', function () { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('a.asar', 'file1') + var r = fs.realpathSync(path.join(parent, p)) + assert.equal(r, path.join(parent, p)) + }) - it('returns real path of a normal directory', function() { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('a.asar', 'dir1'); - var r = fs.realpathSync(path.join(parent, p)); - assert.equal(r, path.join(parent, p)); - }); + it('returns real path of a normal directory', function () { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('a.asar', 'dir1') + var r = fs.realpathSync(path.join(parent, p)) + assert.equal(r, path.join(parent, p)) + }) - it('returns real path of a linked file', function() { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('a.asar', 'link2', 'link1'); - var r = fs.realpathSync(path.join(parent, p)); - assert.equal(r, path.join(parent, 'a.asar', 'file1')); - }); + it('returns real path of a linked file', function () { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('a.asar', 'link2', 'link1') + var r = fs.realpathSync(path.join(parent, p)) + assert.equal(r, path.join(parent, 'a.asar', 'file1')) + }) - it('returns real path of a linked directory', function() { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('a.asar', 'link2', 'link2'); - var r = fs.realpathSync(path.join(parent, p)); - assert.equal(r, path.join(parent, 'a.asar', 'dir1')); - }); + it('returns real path of a linked directory', function () { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('a.asar', 'link2', 'link2') + var r = fs.realpathSync(path.join(parent, p)) + assert.equal(r, path.join(parent, 'a.asar', 'dir1')) + }) - it('returns real path of an unpacked file', function() { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('unpack.asar', 'a.txt'); - var r = fs.realpathSync(path.join(parent, p)); - assert.equal(r, path.join(parent, p)); - }); + it('returns real path of an unpacked file', function () { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('unpack.asar', 'a.txt') + var r = fs.realpathSync(path.join(parent, p)) + assert.equal(r, path.join(parent, p)) + }) - it('throws ENOENT error when can not find file', function() { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('a.asar', 'not-exist'); - var throws = function() { - fs.realpathSync(path.join(parent, p)); - }; - assert.throws(throws, /ENOENT/); - }); - }); + it('throws ENOENT error when can not find file', function () { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('a.asar', 'not-exist') + var throws = function () { + fs.realpathSync(path.join(parent, p)) + } + assert.throws(throws, /ENOENT/) + }) + }) - describe('fs.realpath', function() { - it('returns real path root', function(done) { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = 'a.asar'; - fs.realpath(path.join(parent, p), function(err, r) { - assert.equal(err, null); - assert.equal(r, path.join(parent, p)); - done(); - }); - }); + describe('fs.realpath', function () { + it('returns real path root', function (done) { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = 'a.asar' + fs.realpath(path.join(parent, p), function (err, r) { + assert.equal(err, null) + assert.equal(r, path.join(parent, p)) + done() + }) + }) - it('returns real path of a normal file', function(done) { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('a.asar', 'file1'); - fs.realpath(path.join(parent, p), function(err, r) { - assert.equal(err, null); - assert.equal(r, path.join(parent, p)); - done(); - }); - }); + it('returns real path of a normal file', function (done) { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('a.asar', 'file1') + fs.realpath(path.join(parent, p), function (err, r) { + assert.equal(err, null) + assert.equal(r, path.join(parent, p)) + done() + }) + }) - it('returns real path of a normal directory', function(done) { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('a.asar', 'dir1'); - fs.realpath(path.join(parent, p), function(err, r) { - assert.equal(err, null); - assert.equal(r, path.join(parent, p)); - done(); - }); - }); + it('returns real path of a normal directory', function (done) { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('a.asar', 'dir1') + fs.realpath(path.join(parent, p), function (err, r) { + assert.equal(err, null) + assert.equal(r, path.join(parent, p)) + done() + }) + }) - it('returns real path of a linked file', function(done) { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('a.asar', 'link2', 'link1'); - fs.realpath(path.join(parent, p), function(err, r) { - assert.equal(err, null); - assert.equal(r, path.join(parent, 'a.asar', 'file1')); - done(); - }); - }); + it('returns real path of a linked file', function (done) { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('a.asar', 'link2', 'link1') + fs.realpath(path.join(parent, p), function (err, r) { + assert.equal(err, null) + assert.equal(r, path.join(parent, 'a.asar', 'file1')) + done() + }) + }) - it('returns real path of a linked directory', function(done) { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('a.asar', 'link2', 'link2'); - fs.realpath(path.join(parent, p), function(err, r) { - assert.equal(err, null); - assert.equal(r, path.join(parent, 'a.asar', 'dir1')); - done(); - }); - }); + it('returns real path of a linked directory', function (done) { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('a.asar', 'link2', 'link2') + fs.realpath(path.join(parent, p), function (err, r) { + assert.equal(err, null) + assert.equal(r, path.join(parent, 'a.asar', 'dir1')) + done() + }) + }) - it('returns real path of an unpacked file', function(done) { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('unpack.asar', 'a.txt'); - fs.realpath(path.join(parent, p), function(err, r) { - assert.equal(err, null); - assert.equal(r, path.join(parent, p)); - done(); - }); - }); + it('returns real path of an unpacked file', function (done) { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('unpack.asar', 'a.txt') + fs.realpath(path.join(parent, p), function (err, r) { + assert.equal(err, null) + assert.equal(r, path.join(parent, p)) + done() + }) + }) - it('throws ENOENT error when can not find file', function(done) { - var parent = fs.realpathSync(path.join(fixtures, 'asar')); - var p = path.join('a.asar', 'not-exist'); - fs.realpath(path.join(parent, p), function(err) { - assert.equal(err.code, 'ENOENT'); - done(); - }); - }); - }); - describe('fs.readdirSync', function() { - it('reads dirs from root', function() { - var p = path.join(fixtures, 'asar', 'a.asar'); - var dirs = fs.readdirSync(p); - assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); - }); + it('throws ENOENT error when can not find file', function (done) { + var parent = fs.realpathSync(path.join(fixtures, 'asar')) + var p = path.join('a.asar', 'not-exist') + fs.realpath(path.join(parent, p), function (err) { + assert.equal(err.code, 'ENOENT') + done() + }) + }) + }) + describe('fs.readdirSync', function () { + it('reads dirs from root', function () { + var p = path.join(fixtures, 'asar', 'a.asar') + var dirs = fs.readdirSync(p) + assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']) + }) - it('reads dirs from a normal dir', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); - var dirs = fs.readdirSync(p); - assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); - }); + it('reads dirs from a normal dir', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'dir1') + var dirs = fs.readdirSync(p) + assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']) + }) - it('reads dirs from a linked dir', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); - var dirs = fs.readdirSync(p); - assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); - }); + it('reads dirs from a linked dir', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2') + var dirs = fs.readdirSync(p) + assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']) + }) - it('throws ENOENT error when can not find file', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - var throws = function() { - fs.readdirSync(p); - }; - assert.throws(throws, /ENOENT/); - }); - }); + it('throws ENOENT error when can not find file', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') + var throws = function () { + fs.readdirSync(p) + } + assert.throws(throws, /ENOENT/) + }) + }) - describe('fs.readdir', function() { - it('reads dirs from root', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar'); - fs.readdir(p, function(err, dirs) { - assert.equal(err, null); - assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']); - done(); - }); - }); + describe('fs.readdir', function () { + it('reads dirs from root', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar') + fs.readdir(p, function (err, dirs) { + assert.equal(err, null) + assert.deepEqual(dirs, ['dir1', 'dir2', 'dir3', 'file1', 'file2', 'file3', 'link1', 'link2', 'ping.js']) + done() + }) + }) - it('reads dirs from a normal dir', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'dir1'); - fs.readdir(p, function(err, dirs) { - assert.equal(err, null); - assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); - done(); - }); - }); - it('reads dirs from a linked dir', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2'); - fs.readdir(p, function(err, dirs) { - assert.equal(err, null); - assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']); - done(); - }); - }); + it('reads dirs from a normal dir', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'dir1') + fs.readdir(p, function (err, dirs) { + assert.equal(err, null) + assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']) + done() + }) + }) + it('reads dirs from a linked dir', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'link2', 'link2') + fs.readdir(p, function (err, dirs) { + assert.equal(err, null) + assert.deepEqual(dirs, ['file1', 'file2', 'file3', 'link1', 'link2']) + done() + }) + }) - it('throws ENOENT error when can not find file', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - fs.readdir(p, function(err) { - assert.equal(err.code, 'ENOENT'); - done(); - }); - }); - }); + it('throws ENOENT error when can not find file', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') + fs.readdir(p, function (err) { + assert.equal(err.code, 'ENOENT') + done() + }) + }) + }) - describe('fs.openSync', function() { - it('opens a normal/linked/under-linked-directory file', function() { - var buffer, fd, file, j, len, p, ref2; - ref2 = ['file1', 'link1', path.join('link2', 'file1')]; + describe('fs.openSync', function () { + it('opens a normal/linked/under-linked-directory file', function () { + var buffer, fd, file, j, len, p, ref2 + ref2 = ['file1', 'link1', path.join('link2', 'file1')] for (j = 0, len = ref2.length; j < len; j++) { - file = ref2[j]; - p = path.join(fixtures, 'asar', 'a.asar', file); - fd = fs.openSync(p, 'r'); - buffer = new Buffer(6); - fs.readSync(fd, buffer, 0, 6, 0); - assert.equal(String(buffer).trim(), 'file1'); - fs.closeSync(fd); + file = ref2[j] + p = path.join(fixtures, 'asar', 'a.asar', file) + fd = fs.openSync(p, 'r') + buffer = new Buffer(6) + fs.readSync(fd, buffer, 0, 6, 0) + assert.equal(String(buffer).trim(), 'file1') + fs.closeSync(fd) } - }); + }) - it('throws ENOENT error when can not find file', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - var throws = function() { - fs.openSync(p); - }; - assert.throws(throws, /ENOENT/); - }); - }); + it('throws ENOENT error when can not find file', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') + var throws = function () { + fs.openSync(p) + } + assert.throws(throws, /ENOENT/) + }) + }) - describe('fs.open', function() { - it('opens a normal file', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'file1'); - fs.open(p, 'r', function(err, fd) { - assert.equal(err, null); - var buffer = new Buffer(6); - fs.read(fd, buffer, 0, 6, 0, function(err) { - assert.equal(err, null); - assert.equal(String(buffer).trim(), 'file1'); - fs.close(fd, done); - }); - }); - }); + describe('fs.open', function () { + it('opens a normal file', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'file1') + fs.open(p, 'r', function (err, fd) { + assert.equal(err, null) + var buffer = new Buffer(6) + fs.read(fd, buffer, 0, 6, 0, function (err) { + assert.equal(err, null) + assert.equal(String(buffer).trim(), 'file1') + fs.close(fd, done) + }) + }) + }) - it('throws ENOENT error when can not find file', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - fs.open(p, 'r', function(err) { - assert.equal(err.code, 'ENOENT'); - done(); - }); - }); - }); + it('throws ENOENT error when can not find file', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') + fs.open(p, 'r', function (err) { + assert.equal(err.code, 'ENOENT') + done() + }) + }) + }) - describe('fs.mkdir', function() { - it('throws error when calling inside asar archive', function(done) { - var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - fs.mkdir(p, function(err) { - assert.equal(err.code, 'ENOTDIR'); - done(); - }); - }); - }); + describe('fs.mkdir', function () { + it('throws error when calling inside asar archive', function (done) { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') + fs.mkdir(p, function (err) { + assert.equal(err.code, 'ENOTDIR') + done() + }) + }) + }) - describe('fs.mkdirSync', function() { - it('throws error when calling inside asar archive', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - assert.throws((function() { - fs.mkdirSync(p); - }), new RegExp('ENOTDIR')); - }); - }); + describe('fs.mkdirSync', function () { + it('throws error when calling inside asar archive', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') + assert.throws((function () { + fs.mkdirSync(p) + }), new RegExp('ENOTDIR')) + }) + }) - describe('child_process.fork', function() { - it('opens a normal js file', function(done) { - var child = child_process.fork(path.join(fixtures, 'asar', 'a.asar', 'ping.js')); - child.on('message', function(msg) { - assert.equal(msg, 'message'); - done(); - }); - child.send('message'); - }); + describe('child_process.fork', function () { + it('opens a normal js file', function (done) { + var child = child_process.fork(path.join(fixtures, 'asar', 'a.asar', 'ping.js')) + child.on('message', function (msg) { + assert.equal(msg, 'message') + done() + }) + child.send('message') + }) - it('supports asar in the forked js', function(done) { - var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); - var child = child_process.fork(path.join(fixtures, 'module', 'asar.js')); - child.on('message', function(content) { - assert.equal(content, fs.readFileSync(file).toString()); - done(); - }); - child.send(file); - }); - }); + it('supports asar in the forked js', function (done) { + var file = path.join(fixtures, 'asar', 'a.asar', 'file1') + var child = child_process.fork(path.join(fixtures, 'module', 'asar.js')) + child.on('message', function (content) { + assert.equal(content, fs.readFileSync(file).toString()) + done() + }) + child.send(file) + }) + }) - describe('child_process.execFile', function() { - var echo, execFile, execFileSync, ref2; + describe('child_process.execFile', function () { + var echo, execFile, execFileSync, ref2 if (process.platform !== 'darwin') { - return; + return } - ref2 = require('child_process'), execFile = ref2.execFile, execFileSync = ref2.execFileSync; - echo = path.join(fixtures, 'asar', 'echo.asar', 'echo'); + ref2 = require('child_process'), execFile = ref2.execFile, execFileSync = ref2.execFileSync + echo = path.join(fixtures, 'asar', 'echo.asar', 'echo') - it('executes binaries', function(done) { - execFile(echo, ['test'], function(error, stdout) { - assert.equal(error, null); - assert.equal(stdout, 'test\n'); - done(); - }); - }); + it('executes binaries', function (done) { + execFile(echo, ['test'], function (error, stdout) { + assert.equal(error, null) + assert.equal(stdout, 'test\n') + done() + }) + }) - xit('execFileSync executes binaries', function() { - var output = execFileSync(echo, ['test']); - assert.equal(String(output), 'test\n'); - }); - }); + xit('execFileSync executes binaries', function () { + var output = execFileSync(echo, ['test']) + assert.equal(String(output), 'test\n') + }) + }) - describe('internalModuleReadFile', function() { - var internalModuleReadFile = process.binding('fs').internalModuleReadFile; + describe('internalModuleReadFile', function () { + var internalModuleReadFile = process.binding('fs').internalModuleReadFile - it('read a normal file', function() { - var file1 = path.join(fixtures, 'asar', 'a.asar', 'file1'); - assert.equal(internalModuleReadFile(file1).toString().trim(), 'file1'); - var file2 = path.join(fixtures, 'asar', 'a.asar', 'file2'); - assert.equal(internalModuleReadFile(file2).toString().trim(), 'file2'); - var file3 = path.join(fixtures, 'asar', 'a.asar', 'file3'); - assert.equal(internalModuleReadFile(file3).toString().trim(), 'file3'); - }); + it('read a normal file', function () { + var file1 = path.join(fixtures, 'asar', 'a.asar', 'file1') + assert.equal(internalModuleReadFile(file1).toString().trim(), 'file1') + var file2 = path.join(fixtures, 'asar', 'a.asar', 'file2') + assert.equal(internalModuleReadFile(file2).toString().trim(), 'file2') + var file3 = path.join(fixtures, 'asar', 'a.asar', 'file3') + assert.equal(internalModuleReadFile(file3).toString().trim(), 'file3') + }) - it('reads a normal file with unpacked files', function() { - var p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt'); - assert.equal(internalModuleReadFile(p).toString().trim(), 'a'); - }); - }); + it('reads a normal file with unpacked files', function () { + var p = path.join(fixtures, 'asar', 'unpack.asar', 'a.txt') + assert.equal(internalModuleReadFile(p).toString().trim(), 'a') + }) + }) - describe('process.noAsar', function() { - var errorName = process.platform === 'win32' ? 'ENOENT' : 'ENOTDIR'; + describe('process.noAsar', function () { + var errorName = process.platform === 'win32' ? 'ENOENT' : 'ENOTDIR' - beforeEach(function() { - process.noAsar = true; - }); + beforeEach(function () { + process.noAsar = true + }) - afterEach(function() { - process.noAsar = false; - }); + afterEach(function () { + process.noAsar = false + }) - it('disables asar support in sync API', function() { - var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); - var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); - assert.throws((function() { - fs.readFileSync(file); - }), new RegExp(errorName)); - assert.throws((function() { - fs.lstatSync(file); - }), new RegExp(errorName)); - assert.throws((function() { - fs.realpathSync(file); - }), new RegExp(errorName)); - assert.throws((function() { - fs.readdirSync(dir); - }), new RegExp(errorName)); - }); + it('disables asar support in sync API', function () { + var file = path.join(fixtures, 'asar', 'a.asar', 'file1') + var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1') + assert.throws((function () { + fs.readFileSync(file) + }), new RegExp(errorName)) + assert.throws((function () { + fs.lstatSync(file) + }), new RegExp(errorName)) + assert.throws((function () { + fs.realpathSync(file) + }), new RegExp(errorName)) + assert.throws((function () { + fs.readdirSync(dir) + }), new RegExp(errorName)) + }) - it('disables asar support in async API', function(done) { - var file = path.join(fixtures, 'asar', 'a.asar', 'file1'); - var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1'); - fs.readFile(file, function(error) { - assert.equal(error.code, errorName); - fs.lstat(file, function(error) { - assert.equal(error.code, errorName); - fs.realpath(file, function(error) { - assert.equal(error.code, errorName); - fs.readdir(dir, function(error) { - assert.equal(error.code, errorName); - done(); - }); - }); - }); - }); - }); + it('disables asar support in async API', function (done) { + var file = path.join(fixtures, 'asar', 'a.asar', 'file1') + var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1') + fs.readFile(file, function (error) { + assert.equal(error.code, errorName) + fs.lstat(file, function (error) { + assert.equal(error.code, errorName) + fs.realpath(file, function (error) { + assert.equal(error.code, errorName) + fs.readdir(dir, function (error) { + assert.equal(error.code, errorName) + done() + }) + }) + }) + }) + }) - it('treats *.asar as normal file', function() { - var originalFs = require('original-fs'); - var asar = path.join(fixtures, 'asar', 'a.asar'); - var content1 = fs.readFileSync(asar); - var content2 = originalFs.readFileSync(asar); - assert.equal(content1.compare(content2), 0); - assert.throws((function() { - fs.readdirSync(asar); - }), /ENOTDIR/); - }); - }); - }); + it('treats *.asar as normal file', function () { + var originalFs = require('original-fs') + var asar = path.join(fixtures, 'asar', 'a.asar') + var content1 = fs.readFileSync(asar) + var content2 = originalFs.readFileSync(asar) + assert.equal(content1.compare(content2), 0) + assert.throws((function () { + fs.readdirSync(asar) + }), /ENOTDIR/) + }) + }) + }) - describe('asar protocol', function() { - var url = require('url'); + describe('asar protocol', function () { + var url = require('url') - it('can request a file in package', function(done) { - var p = path.resolve(fixtures, 'asar', 'a.asar', 'file1'); - $.get("file://" + p, function(data) { - assert.equal(data.trim(), 'file1'); - done(); - }); - }); + it('can request a file in package', function (done) { + var p = path.resolve(fixtures, 'asar', 'a.asar', 'file1') + $.get('file://' + p, function (data) { + assert.equal(data.trim(), 'file1') + done() + }) + }) - it('can request a file in package with unpacked files', function(done) { - var p = path.resolve(fixtures, 'asar', 'unpack.asar', 'a.txt'); - $.get("file://" + p, function(data) { - assert.equal(data.trim(), 'a'); - done(); - }); - }); + it('can request a file in package with unpacked files', function (done) { + var p = path.resolve(fixtures, 'asar', 'unpack.asar', 'a.txt') + $.get('file://' + p, function (data) { + assert.equal(data.trim(), 'a') + done() + }) + }) - it('can request a linked file in package', function(done) { - var p = path.resolve(fixtures, 'asar', 'a.asar', 'link2', 'link1'); - $.get("file://" + p, function(data) { - assert.equal(data.trim(), 'file1'); - done(); - }); - }); + it('can request a linked file in package', function (done) { + var p = path.resolve(fixtures, 'asar', 'a.asar', 'link2', 'link1') + $.get('file://' + p, function (data) { + assert.equal(data.trim(), 'file1') + done() + }) + }) - it('can request a file in filesystem', function(done) { - var p = path.resolve(fixtures, 'asar', 'file'); - $.get("file://" + p, function(data) { - assert.equal(data.trim(), 'file'); - done(); - }); - }); + it('can request a file in filesystem', function (done) { + var p = path.resolve(fixtures, 'asar', 'file') + $.get('file://' + p, function (data) { + assert.equal(data.trim(), 'file') + done() + }) + }) - it('gets 404 when file is not found', function(done) { - var p = path.resolve(fixtures, 'asar', 'a.asar', 'no-exist'); + it('gets 404 when file is not found', function (done) { + var p = path.resolve(fixtures, 'asar', 'a.asar', 'no-exist') $.ajax({ - url: "file://" + p, - error: function(err) { - assert.equal(err.status, 404); - done(); + url: 'file://' + p, + error: function (err) { + assert.equal(err.status, 404) + done() } - }); - }); + }) + }) - it('sets __dirname correctly', function(done) { - after(function() { - w.destroy(); - ipcMain.removeAllListeners('dirname'); - }); + it('sets __dirname correctly', function (done) { + after(function () { + w.destroy() + ipcMain.removeAllListeners('dirname') + }) var w = new BrowserWindow({ show: false, width: 400, height: 400 - }); - var p = path.resolve(fixtures, 'asar', 'web.asar', 'index.html'); + }) + var p = path.resolve(fixtures, 'asar', 'web.asar', 'index.html') var u = url.format({ protocol: 'file', slashed: true, pathname: p - }); - ipcMain.once('dirname', function(event, dirname) { - assert.equal(dirname, path.dirname(p)); - done(); - }); - w.loadURL(u); - }); + }) + ipcMain.once('dirname', function (event, dirname) { + assert.equal(dirname, path.dirname(p)) + done() + }) + w.loadURL(u) + }) - it('loads script tag in html', function(done) { - after(function() { - w.destroy(); - ipcMain.removeAllListeners('ping'); - }); + it('loads script tag in html', function (done) { + after(function () { + w.destroy() + ipcMain.removeAllListeners('ping') + }) var w = new BrowserWindow({ show: false, width: 400, height: 400 - }); - var p = path.resolve(fixtures, 'asar', 'script.asar', 'index.html'); + }) + var p = path.resolve(fixtures, 'asar', 'script.asar', 'index.html') var u = url.format({ protocol: 'file', slashed: true, pathname: p - }); - w.loadURL(u); - ipcMain.once('ping', function(event, message) { - assert.equal(message, 'pong'); - done(); - }); - }); - }); + }) + w.loadURL(u) + ipcMain.once('ping', function (event, message) { + assert.equal(message, 'pong') + done() + }) + }) + }) - describe('original-fs module', function() { - var originalFs = require('original-fs'); + describe('original-fs module', function () { + var originalFs = require('original-fs') - it('treats .asar as file', function() { - var file = path.join(fixtures, 'asar', 'a.asar'); - var stats = originalFs.statSync(file); - assert(stats.isFile()); - }); + it('treats .asar as file', function () { + var file = path.join(fixtures, 'asar', 'a.asar') + var stats = originalFs.statSync(file) + assert(stats.isFile()) + }) - it('is available in forked scripts', function(done) { - var child = child_process.fork(path.join(fixtures, 'module', 'original-fs.js')); - child.on('message', function(msg) { - assert.equal(msg, 'object'); - done(); - }); - child.send('message'); - }); - }); + it('is available in forked scripts', function (done) { + var child = child_process.fork(path.join(fixtures, 'module', 'original-fs.js')) + child.on('message', function (msg) { + assert.equal(msg, 'object') + done() + }) + child.send('message') + }) + }) - describe('graceful-fs module', function() { - var gfs = require('graceful-fs'); + describe('graceful-fs module', function () { + var gfs = require('graceful-fs') - it('recognize asar archvies', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'link1'); - assert.equal(gfs.readFileSync(p).toString().trim(), 'file1'); - }); - it('does not touch global fs object', function() { - assert.notEqual(fs.readdir, gfs.readdir); - }); - }); + it('recognize asar archvies', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'link1') + assert.equal(gfs.readFileSync(p).toString().trim(), 'file1') + }) + it('does not touch global fs object', function () { + assert.notEqual(fs.readdir, gfs.readdir) + }) + }) - describe('mkdirp module', function() { - var mkdirp = require('mkdirp'); + describe('mkdirp module', function () { + var mkdirp = require('mkdirp') - it('throws error when calling inside asar archive', function() { - var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist'); - assert.throws((function() { - mkdirp.sync(p); - }), new RegExp('ENOTDIR')); - }); - }); + it('throws error when calling inside asar archive', function () { + var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') + assert.throws((function () { + mkdirp.sync(p) + }), new RegExp('ENOTDIR')) + }) + }) - describe('native-image', function() { - it('reads image from asar archive', function() { - var p = path.join(fixtures, 'asar', 'logo.asar', 'logo.png'); - var logo = nativeImage.createFromPath(p); + describe('native-image', function () { + it('reads image from asar archive', function () { + var p = path.join(fixtures, 'asar', 'logo.asar', 'logo.png') + var logo = nativeImage.createFromPath(p) assert.deepEqual(logo.getSize(), { width: 55, height: 55 - }); - }); + }) + }) - it('reads image from asar archive with unpacked files', function() { - var p = path.join(fixtures, 'asar', 'unpack.asar', 'atom.png'); - var logo = nativeImage.createFromPath(p); + it('reads image from asar archive with unpacked files', function () { + var p = path.join(fixtures, 'asar', 'unpack.asar', 'atom.png') + var logo = nativeImage.createFromPath(p) assert.deepEqual(logo.getSize(), { width: 1024, height: 1024 - }); - }); - }); -}); + }) + }) + }) +}) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index ac9403a7ecd..40e46dcb5ea 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -1,432 +1,432 @@ -const assert = require('assert'); -const http = require('http'); -const path = require('path'); -const ws = require('ws'); -const remote = require('electron').remote; +const assert = require('assert') +const http = require('http') +const path = require('path') +const ws = require('ws') +const remote = require('electron').remote -const BrowserWindow = remote.require('electron').BrowserWindow; -const session = remote.require('electron').session; +const BrowserWindow = remote.require('electron').BrowserWindow +const session = remote.require('electron').session -const isCI = remote.getGlobal('isCi'); +const isCI = remote.getGlobal('isCi') -describe('chromium feature', function() { - var fixtures = path.resolve(__dirname, 'fixtures'); - var listener = null; +describe('chromium feature', function () { + var fixtures = path.resolve(__dirname, 'fixtures') + var listener = null - afterEach(function() { + afterEach(function () { if (listener != null) { - window.removeEventListener('message', listener); + window.removeEventListener('message', listener) } - listener = null; - }); + listener = null + }) - xdescribe('heap snapshot', function() { - it('does not crash', function() { - process.atomBinding('v8_util').takeHeapSnapshot(); - }); - }); + xdescribe('heap snapshot', function () { + it('does not crash', function () { + process.atomBinding('v8_util').takeHeapSnapshot() + }) + }) - describe('sending request of http protocol urls', function() { - it('does not crash', function(done) { - this.timeout(5000); + describe('sending request of http protocol urls', function () { + it('does not crash', function (done) { + this.timeout(5000) - var server = http.createServer(function(req, res) { - res.end(); - server.close(); - done(); - }); - server.listen(0, '127.0.0.1', function() { - var port = server.address().port; - $.get("http://127.0.0.1:" + port); - }); - }); - }); + var server = http.createServer(function (req, res) { + res.end() + server.close() + done() + }) + server.listen(0, '127.0.0.1', function () { + var port = server.address().port + $.get('http://127.0.0.1:' + port) + }) + }) + }) - describe('document.hidden', function() { - var url = "file://" + fixtures + "/pages/document-hidden.html"; - var w = null; + describe('document.hidden', function () { + var url = 'file://' + fixtures + '/pages/document-hidden.html' + var w = null - afterEach(function() { - w != null ? w.destroy() : void 0; - }); + afterEach(function () { + w != null ? w.destroy() : void 0 + }) - it('is set correctly when window is not shown', function(done) { + it('is set correctly when window is not shown', function (done) { w = new BrowserWindow({ show: false - }); - w.webContents.on('ipc-message', function(event, args) { - assert.deepEqual(args, ['hidden', true]); - done(); - }); - w.loadURL(url); - }); + }) + w.webContents.on('ipc-message', function (event, args) { + assert.deepEqual(args, ['hidden', true]) + done() + }) + w.loadURL(url) + }) - it('is set correctly when window is inactive', function(done) { + it('is set correctly when window is inactive', function (done) { w = new BrowserWindow({ show: false - }); - w.webContents.on('ipc-message', function(event, args) { - assert.deepEqual(args, ['hidden', false]); - done(); - }); - w.showInactive(); - w.loadURL(url); - }); - }); + }) + w.webContents.on('ipc-message', function (event, args) { + assert.deepEqual(args, ['hidden', false]) + done() + }) + w.showInactive() + w.loadURL(url) + }) + }) - xdescribe('navigator.webkitGetUserMedia', function() { - it('calls its callbacks', function(done) { - this.timeout(5000); + xdescribe('navigator.webkitGetUserMedia', function () { + it('calls its callbacks', function (done) { + this.timeout(5000) navigator.webkitGetUserMedia({ audio: true, video: false - }, function() { - done(); - }, function() { - done(); - }); - }); - }); + }, function () { + done() + }, function () { + done() + }) + }) + }) - describe('navigator.mediaDevices', function() { + describe('navigator.mediaDevices', function () { if (process.env.TRAVIS === 'true') { - return; + return } if (isCI && process.platform === 'linux') { - return; + return } - it('can return labels of enumerated devices', function(done) { + it('can return labels of enumerated devices', function (done) { navigator.mediaDevices.enumerateDevices().then((devices) => { - const labels = devices.map((device) => device.label); - const labelFound = labels.some((label) => !!label); + const labels = devices.map((device) => device.label) + const labelFound = labels.some((label) => !!label) if (labelFound) - done(); + done() else - done('No device labels found: ' + JSON.stringify(labels)); - }).catch(done); - }); - }); + done('No device labels found: ' + JSON.stringify(labels)) + }).catch(done) + }) + }) - describe('navigator.language', function() { - it('should not be empty', function() { - assert.notEqual(navigator.language, ''); - }); - }); + describe('navigator.language', function () { + it('should not be empty', function () { + assert.notEqual(navigator.language, '') + }) + }) - describe('navigator.serviceWorker', function() { - var url = "file://" + fixtures + "/pages/service-worker/index.html"; - var w = null; + describe('navigator.serviceWorker', function () { + var url = 'file://' + fixtures + '/pages/service-worker/index.html' + var w = null - afterEach(function() { - w != null ? w.destroy() : void 0; - }); + afterEach(function () { + w != null ? w.destroy() : void 0 + }) - it('should register for file scheme', function(done) { + it('should register for file scheme', function (done) { w = new BrowserWindow({ show: false - }); - w.webContents.on('ipc-message', function(event, args) { + }) + w.webContents.on('ipc-message', function (event, args) { if (args[0] === 'reload') { - w.webContents.reload(); + w.webContents.reload() } else if (args[0] === 'error') { - done('unexpected error : ' + args[1]); + done('unexpected error : ' + args[1]) } else if (args[0] === 'response') { - assert.equal(args[1], 'Hello from serviceWorker!'); + assert.equal(args[1], 'Hello from serviceWorker!') session.defaultSession.clearStorageData({ storages: ['serviceworkers'] - }, function() { - done(); - }); + }, function () { + done() + }) } - }); - w.loadURL(url); - }); - }); + }) + w.loadURL(url) + }) + }) - describe('window.open', function() { - this.timeout(20000); + describe('window.open', function () { + this.timeout(20000) - it('returns a BrowserWindowProxy object', function() { - var b = window.open('about:blank', '', 'show=no'); - assert.equal(b.closed, false); - assert.equal(b.constructor.name, 'BrowserWindowProxy'); - b.close(); - }); + it('returns a BrowserWindowProxy object', function () { + var b = window.open('about:blank', '', 'show=no') + assert.equal(b.closed, false) + assert.equal(b.constructor.name, 'BrowserWindowProxy') + b.close() + }) - it('accepts "nodeIntegration" as feature', function(done) { - var b; - listener = function(event) { - assert.equal(event.data, 'undefined'); - b.close(); - done(); - }; - window.addEventListener('message', listener); - b = window.open("file://" + fixtures + "/pages/window-opener-node.html", '', 'nodeIntegration=no,show=no'); - }); + it('accepts "nodeIntegration" as feature', function (done) { + var b + listener = function (event) { + assert.equal(event.data, 'undefined') + b.close() + done() + } + window.addEventListener('message', listener) + b = window.open('file://' + fixtures + '/pages/window-opener-node.html', '', 'nodeIntegration=no,show=no') + }) - it('inherit options of parent window', function(done) { - var b; - listener = function(event) { - var height, ref1, width; - ref1 = remote.getCurrentWindow().getSize(), width = ref1[0], height = ref1[1]; - assert.equal(event.data, "size: " + width + " " + height); - b.close(); - done(); - }; - window.addEventListener('message', listener); - b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', 'show=no'); - }); + it('inherit options of parent window', function (done) { + var b + listener = function (event) { + var height, ref1, width + ref1 = remote.getCurrentWindow().getSize(), width = ref1[0], height = ref1[1] + assert.equal(event.data, 'size: ' + width + ' ' + height) + b.close() + done() + } + window.addEventListener('message', listener) + b = window.open('file://' + fixtures + '/pages/window-open-size.html', '', 'show=no') + }) - it('does not override child options', function(done) { - var b, size; + it('does not override child options', function (done) { + var b, size size = { width: 350, height: 450 - }; - listener = function(event) { - assert.equal(event.data, "size: " + size.width + " " + size.height); - b.close(); - done(); - }; - window.addEventListener('message', listener); - b = window.open("file://" + fixtures + "/pages/window-open-size.html", '', "show=no,width=" + size.width + ",height=" + size.height); - }); + } + listener = function (event) { + assert.equal(event.data, 'size: ' + size.width + ' ' + size.height) + b.close() + done() + } + window.addEventListener('message', listener) + b = window.open('file://' + fixtures + '/pages/window-open-size.html', '', 'show=no,width=' + size.width + ',height=' + size.height) + }) - it('defines a window.location getter', function(done) { - var b, targetURL; - targetURL = "file://" + fixtures + "/pages/base-page.html"; - b = window.open(targetURL); - BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { - assert.equal(b.location, targetURL); - b.close(); - done(); - }); - }); + it('defines a window.location getter', function (done) { + var b, targetURL + targetURL = 'file://' + fixtures + '/pages/base-page.html' + b = window.open(targetURL) + BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function () { + assert.equal(b.location, targetURL) + b.close() + done() + }) + }) - it('defines a window.location setter', function(done) { + it('defines a window.location setter', function (done) { // Load a page that definitely won't redirect - var b; - b = window.open("about:blank"); - BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { + var b + b = window.open('about:blank') + BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function () { // When it loads, redirect - b.location = "file://" + fixtures + "/pages/base-page.html"; - BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { + b.location = 'file://' + fixtures + '/pages/base-page.html' + BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function () { // After our second redirect, cleanup and callback - b.close(); - done(); - }); - }); - }); - }); + b.close() + done() + }) + }) + }) + }) - describe('window.opener', function() { - this.timeout(10000); + describe('window.opener', function () { + this.timeout(10000) - var url = "file://" + fixtures + "/pages/window-opener.html"; - var w = null; + var url = 'file://' + fixtures + '/pages/window-opener.html' + var w = null - afterEach(function() { - w != null ? w.destroy() : void 0; - }); + afterEach(function () { + w != null ? w.destroy() : void 0 + }) - it('is null for main window', function(done) { + it('is null for main window', function (done) { w = new BrowserWindow({ show: false - }); - w.webContents.on('ipc-message', function(event, args) { - assert.deepEqual(args, ['opener', null]); - done(); - }); - w.loadURL(url); - }); + }) + w.webContents.on('ipc-message', function (event, args) { + assert.deepEqual(args, ['opener', null]) + done() + }) + w.loadURL(url) + }) - it('is not null for window opened by window.open', function(done) { - var b; - listener = function(event) { - assert.equal(event.data, 'object'); - b.close(); - done(); - }; - window.addEventListener('message', listener); - b = window.open(url, '', 'show=no'); - }); - }); - - describe('window.postMessage', function() { - it('sets the source and origin correctly', function(done) { - var b, sourceId; - sourceId = remote.getCurrentWindow().id; - listener = function(event) { - window.removeEventListener('message', listener); - b.close(); - var message = JSON.parse(event.data); - assert.equal(message.data, 'testing'); - assert.equal(message.origin, 'file://'); - assert.equal(message.sourceEqualsOpener, true); - assert.equal(message.sourceId, sourceId); - assert.equal(event.origin, 'file://'); - done(); - }; - window.addEventListener('message', listener); - b = window.open("file://" + fixtures + "/pages/window-open-postMessage.html", '', 'show=no'); - BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function() { - b.postMessage('testing', '*'); - }); - }); - }); - - describe('window.opener.postMessage', function() { - it('sets source and origin correctly', function(done) { - var b; - listener = function(event) { - window.removeEventListener('message', listener); - b.close(); - assert.equal(event.source, b); - assert.equal(event.origin, 'file://'); - done(); - }; - window.addEventListener('message', listener); - b = window.open("file://" + fixtures + "/pages/window-opener-postMessage.html", '', 'show=no'); - }); - }); - - describe('creating a Uint8Array under browser side', function() { - it('does not crash', function() { - var RUint8Array = remote.getGlobal('Uint8Array'); - new RUint8Array; - }); - }); - - describe('webgl', function() { - it('can be get as context in canvas', function() { - if (process.platform === 'linux') { - return; + it('is not null for window opened by window.open', function (done) { + var b + listener = function (event) { + assert.equal(event.data, 'object') + b.close() + done() } - var webgl = document.createElement('canvas').getContext('webgl'); - assert.notEqual(webgl, null); - }); - }); + window.addEventListener('message', listener) + b = window.open(url, '', 'show=no') + }) + }) - describe('web workers', function() { - it('Worker can work', function(done) { - var worker = new Worker('../fixtures/workers/worker.js'); - var message = 'ping'; - worker.onmessage = function(event) { - assert.equal(event.data, message); - worker.terminate(); - done(); - }; - worker.postMessage(message); - }); + describe('window.postMessage', function () { + it('sets the source and origin correctly', function (done) { + var b, sourceId + sourceId = remote.getCurrentWindow().id + listener = function (event) { + window.removeEventListener('message', listener) + b.close() + var message = JSON.parse(event.data) + assert.equal(message.data, 'testing') + assert.equal(message.origin, 'file://') + assert.equal(message.sourceEqualsOpener, true) + assert.equal(message.sourceId, sourceId) + assert.equal(event.origin, 'file://') + done() + } + window.addEventListener('message', listener) + b = window.open('file://' + fixtures + '/pages/window-open-postMessage.html', '', 'show=no') + BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function () { + b.postMessage('testing', '*') + }) + }) + }) - it('SharedWorker can work', function(done) { - var worker = new SharedWorker('../fixtures/workers/shared_worker.js'); - var message = 'ping'; - worker.port.onmessage = function(event) { - assert.equal(event.data, message); - done(); - }; - worker.port.postMessage(message); - }); - }); + describe('window.opener.postMessage', function () { + it('sets source and origin correctly', function (done) { + var b + listener = function (event) { + window.removeEventListener('message', listener) + b.close() + assert.equal(event.source, b) + assert.equal(event.origin, 'file://') + done() + } + window.addEventListener('message', listener) + b = window.open('file://' + fixtures + '/pages/window-opener-postMessage.html', '', 'show=no') + }) + }) - describe('iframe', function() { - var iframe = null; + describe('creating a Uint8Array under browser side', function () { + it('does not crash', function () { + var RUint8Array = remote.getGlobal('Uint8Array') + new RUint8Array + }) + }) - beforeEach(function() { - iframe = document.createElement('iframe'); - }); + describe('webgl', function () { + it('can be get as context in canvas', function () { + if (process.platform === 'linux') { + return + } + var webgl = document.createElement('canvas').getContext('webgl') + assert.notEqual(webgl, null) + }) + }) - afterEach(function() { - document.body.removeChild(iframe); - }); + describe('web workers', function () { + it('Worker can work', function (done) { + var worker = new Worker('../fixtures/workers/worker.js') + var message = 'ping' + worker.onmessage = function (event) { + assert.equal(event.data, message) + worker.terminate() + done() + } + worker.postMessage(message) + }) - it('does not have node integration', function(done) { - iframe.src = "file://" + fixtures + "/pages/set-global.html"; - document.body.appendChild(iframe); - iframe.onload = function() { - assert.equal(iframe.contentWindow.test, 'undefined undefined undefined'); - done(); - }; - }); - }); + it('SharedWorker can work', function (done) { + var worker = new SharedWorker('../fixtures/workers/shared_worker.js') + var message = 'ping' + worker.port.onmessage = function (event) { + assert.equal(event.data, message) + done() + } + worker.port.postMessage(message) + }) + }) - describe('storage', function() { - it('requesting persitent quota works', function(done) { - navigator.webkitPersistentStorage.requestQuota(1024 * 1024, function(grantedBytes) { - assert.equal(grantedBytes, 1048576); - done(); - }); - }); - }); + describe('iframe', function () { + var iframe = null - describe('websockets', function() { - var wss = null; - var server = null; - var WebSocketServer = ws.Server; + beforeEach(function () { + iframe = document.createElement('iframe') + }) - afterEach(function() { - wss.close(); - server.close(); - }); + afterEach(function () { + document.body.removeChild(iframe) + }) - it('has user agent', function(done) { - server = http.createServer(); - server.listen(0, '127.0.0.1', function() { - var port = server.address().port; + it('does not have node integration', function (done) { + iframe.src = 'file://' + fixtures + '/pages/set-global.html' + document.body.appendChild(iframe) + iframe.onload = function () { + assert.equal(iframe.contentWindow.test, 'undefined undefined undefined') + done() + } + }) + }) + + describe('storage', function () { + it('requesting persitent quota works', function (done) { + navigator.webkitPersistentStorage.requestQuota(1024 * 1024, function (grantedBytes) { + assert.equal(grantedBytes, 1048576) + done() + }) + }) + }) + + describe('websockets', function () { + var wss = null + var server = null + var WebSocketServer = ws.Server + + afterEach(function () { + wss.close() + server.close() + }) + + it('has user agent', function (done) { + server = http.createServer() + server.listen(0, '127.0.0.1', function () { + var port = server.address().port wss = new WebSocketServer({ server: server - }); - wss.on('error', done); - wss.on('connection', function(ws) { + }) + wss.on('error', done) + wss.on('connection', function (ws) { if (ws.upgradeReq.headers['user-agent']) { - done(); + done() } else { - done('user agent is empty'); + done('user agent is empty') } - }); - new WebSocket("ws://127.0.0.1:" + port); - }); - }); - }); + }) + new WebSocket('ws://127.0.0.1:' + port) + }) + }) + }) - describe('Promise', function() { - it('resolves correctly in Node.js calls', function(done) { + describe('Promise', function () { + it('resolves correctly in Node.js calls', function (done) { document.registerElement('x-element', { prototype: Object.create(HTMLElement.prototype, { createdCallback: { - value: function() {} + value: function () {} } }) - }); - setImmediate(function() { - var called = false; - Promise.resolve().then(function() { - done(called ? void 0 : new Error('wrong sequence')); - }); - document.createElement('x-element'); - called = true; - }); - }); + }) + setImmediate(function () { + var called = false + Promise.resolve().then(function () { + done(called ? void 0 : new Error('wrong sequence')) + }) + document.createElement('x-element') + called = true + }) + }) - it('resolves correctly in Electron calls', function(done) { + it('resolves correctly in Electron calls', function (done) { document.registerElement('y-element', { prototype: Object.create(HTMLElement.prototype, { createdCallback: { - value: function() {} + value: function () {} } }) - }); - remote.getGlobal('setImmediate')(function() { - var called = false; - Promise.resolve().then(function() { - done(called ? void 0 : new Error('wrong sequence')); - }); - document.createElement('y-element'); - called = true; - }); - }); - }); -}); + }) + remote.getGlobal('setImmediate')(function () { + var called = false + Promise.resolve().then(function () { + done(called ? void 0 : new Error('wrong sequence')) + }) + document.createElement('y-element') + called = true + }) + }) + }) +}) diff --git a/spec/fixtures/api/quit-app/main.js b/spec/fixtures/api/quit-app/main.js index 114e830076a..e2f97affe6d 100644 --- a/spec/fixtures/api/quit-app/main.js +++ b/spec/fixtures/api/quit-app/main.js @@ -1,12 +1,12 @@ -var app = require('electron').app; +var app = require('electron').app app.on('ready', function () { // This setImmediate call gets the spec passing on Linux setImmediate(function () { - app.exit(123); - }); -}); + app.exit(123) + }) +}) process.on('exit', function (code) { - console.log('Exit event with code: ' + code); -}); + console.log('Exit event with code: ' + code) +}) diff --git a/spec/fixtures/module/asar.js b/spec/fixtures/module/asar.js index 1fb8750878a..e01b64a2eca 100644 --- a/spec/fixtures/module/asar.js +++ b/spec/fixtures/module/asar.js @@ -1,4 +1,4 @@ -var fs = require('fs'); -process.on('message', function(file) { - process.send(fs.readFileSync(file).toString()); -}); +var fs = require('fs') +process.on('message', function (file) { + process.send(fs.readFileSync(file).toString()) +}) diff --git a/spec/fixtures/module/call.js b/spec/fixtures/module/call.js index ce0eb6324df..d09d677199b 100644 --- a/spec/fixtures/module/call.js +++ b/spec/fixtures/module/call.js @@ -1,7 +1,7 @@ -exports.call = function(func) { - return func(); -}; +exports.call = function (func) { + return func() +} -exports.constructor = function() { - this.test = 'test'; -}; +exports.constructor = function () { + this.test = 'test' +} diff --git a/spec/fixtures/module/class.js b/spec/fixtures/module/class.js index f25eb2593ff..c961dd8040c 100644 --- a/spec/fixtures/module/class.js +++ b/spec/fixtures/module/class.js @@ -1,22 +1,22 @@ -'use strict'; +'use strict' -let value = 'old'; +let value = 'old' class BaseClass { - method() { - return 'method'; + method () { + return 'method' } - get readonly() { - return 'readonly'; + get readonly () { + return 'readonly' } - get value() { - return value; + get value () { + return value } - set value(val) { - value = val; + set value (val) { + value = val } } diff --git a/spec/fixtures/module/create_socket.js b/spec/fixtures/module/create_socket.js index 2a8b475c519..2528b993d65 100644 --- a/spec/fixtures/module/create_socket.js +++ b/spec/fixtures/module/create_socket.js @@ -1,4 +1,4 @@ -var net = require('net'); -var server = net.createServer(function() {}); -server.listen(process.argv[2]); -process.exit(0); +var net = require('net') +var server = net.createServer(function () {}) +server.listen(process.argv[2]) +process.exit(0) diff --git a/spec/fixtures/module/fork_ping.js b/spec/fixtures/module/fork_ping.js index a43f7d8dce7..76bf1b0e368 100644 --- a/spec/fixtures/module/fork_ping.js +++ b/spec/fixtures/module/fork_ping.js @@ -1,14 +1,14 @@ -process.on('uncaughtException', function(error) { - process.send(error.stack); -}); +process.on('uncaughtException', function (error) { + process.send(error.stack) +}) -var child = require('child_process').fork(__dirname + '/ping.js'); -process.on('message', function(msg) { - child.send(msg); -}); +var child = require('child_process').fork(__dirname + '/ping.js') +process.on('message', function (msg) { + child.send(msg) +}) child.on('message', function (msg) { - process.send(msg); -}); -child.on('exit', function(code) { - process.exit(code); -}); + process.send(msg) +}) +child.on('exit', function (code) { + process.exit(code) +}) diff --git a/spec/fixtures/module/function.js b/spec/fixtures/module/function.js index 803a2838d37..526daf76fa8 100644 --- a/spec/fixtures/module/function.js +++ b/spec/fixtures/module/function.js @@ -1 +1 @@ -exports.aFunction = function() { return 1127; }; +exports.aFunction = function () { return 1127; } diff --git a/spec/fixtures/module/id.js b/spec/fixtures/module/id.js index 5bfae457fe0..2faec9d3832 100644 --- a/spec/fixtures/module/id.js +++ b/spec/fixtures/module/id.js @@ -1 +1 @@ -exports.id = 1127; +exports.id = 1127 diff --git a/spec/fixtures/module/locale-compare.js b/spec/fixtures/module/locale-compare.js index 32dfb309926..3446e2f443d 100644 --- a/spec/fixtures/module/locale-compare.js +++ b/spec/fixtures/module/locale-compare.js @@ -3,5 +3,5 @@ process.on('message', function () { 'a'.localeCompare('a'), 'ä'.localeCompare('z', 'de'), 'ä'.localeCompare('a', 'sv', { sensitivity: 'base' }), - ]); -}); + ]) +}) diff --git a/spec/fixtures/module/original-fs.js b/spec/fixtures/module/original-fs.js index 7a527c63358..341dcb2e0de 100644 --- a/spec/fixtures/module/original-fs.js +++ b/spec/fixtures/module/original-fs.js @@ -1,3 +1,3 @@ process.on('message', function () { - process.send(typeof require('original-fs')); -}); + process.send(typeof require('original-fs')) +}) diff --git a/spec/fixtures/module/ping.js b/spec/fixtures/module/ping.js index fdb9d1ec4ce..90b3d1fb20a 100644 --- a/spec/fixtures/module/ping.js +++ b/spec/fixtures/module/ping.js @@ -1,4 +1,4 @@ -process.on('message', function(msg) { - process.send(msg); - process.exit(0); -}); +process.on('message', function (msg) { + process.send(msg) + process.exit(0) +}) diff --git a/spec/fixtures/module/preload-ipc.js b/spec/fixtures/module/preload-ipc.js index ed95055c124..3f7e5ea35ce 100644 --- a/spec/fixtures/module/preload-ipc.js +++ b/spec/fixtures/module/preload-ipc.js @@ -1,4 +1,4 @@ -var ipcRenderer = require('electron').ipcRenderer; -ipcRenderer.on('ping', function(event, message) { - ipcRenderer.sendToHost('pong', message); -}); +var ipcRenderer = require('electron').ipcRenderer +ipcRenderer.on('ping', function (event, message) { + ipcRenderer.sendToHost('pong', message) +}) diff --git a/spec/fixtures/module/preload-node-off.js b/spec/fixtures/module/preload-node-off.js index 9020f4513a1..54fe343a9ca 100644 --- a/spec/fixtures/module/preload-node-off.js +++ b/spec/fixtures/module/preload-node-off.js @@ -1,7 +1,7 @@ -setImmediate(function() { +setImmediate(function () { try { - console.log([typeof process, typeof setImmediate, typeof global].join(' ')); + console.log([typeof process, typeof setImmediate, typeof global].join(' ')) } catch (e) { - console.log(e.message); + console.log(e.message) } -}); +}) diff --git a/spec/fixtures/module/preload.js b/spec/fixtures/module/preload.js index 205a077ddb1..39c8b11fbe3 100644 --- a/spec/fixtures/module/preload.js +++ b/spec/fixtures/module/preload.js @@ -1 +1 @@ -console.log([typeof require, typeof module, typeof process].join(' ')); +console.log([typeof require, typeof module, typeof process].join(' ')) diff --git a/spec/fixtures/module/print_name.js b/spec/fixtures/module/print_name.js index 96ac2d6f3cb..db4f71d407b 100644 --- a/spec/fixtures/module/print_name.js +++ b/spec/fixtures/module/print_name.js @@ -1,7 +1,7 @@ -exports.print = function(obj) { - return obj.constructor.name; -}; +exports.print = function (obj) { + return obj.constructor.name +} -exports.echo = function(obj) { - return obj; -}; +exports.echo = function (obj) { + return obj +} diff --git a/spec/fixtures/module/process_args.js b/spec/fixtures/module/process_args.js index bba351154f6..56e3906c553 100644 --- a/spec/fixtures/module/process_args.js +++ b/spec/fixtures/module/process_args.js @@ -1,4 +1,4 @@ -process.on('message', function() { - process.send(process.argv); - process.exit(0); -}); +process.on('message', function () { + process.send(process.argv) + process.exit(0) +}) diff --git a/spec/fixtures/module/promise.js b/spec/fixtures/module/promise.js index b9b568855e3..d34058cc803 100644 --- a/spec/fixtures/module/promise.js +++ b/spec/fixtures/module/promise.js @@ -1,5 +1,5 @@ exports.twicePromise = function (promise) { return promise.then(function (value) { - return value * 2; - }); -}; + return value * 2 + }) +} diff --git a/spec/fixtures/module/property.js b/spec/fixtures/module/property.js index 36286d800e1..88e596f7308 100644 --- a/spec/fixtures/module/property.js +++ b/spec/fixtures/module/property.js @@ -1 +1 @@ -exports.property = 1127; +exports.property = 1127 diff --git a/spec/fixtures/module/runas.js b/spec/fixtures/module/runas.js index c4845e026f2..6422fce052a 100644 --- a/spec/fixtures/module/runas.js +++ b/spec/fixtures/module/runas.js @@ -1,6 +1,6 @@ -process.on('uncaughtException', function(err) { - process.send(err.message); -}); +process.on('uncaughtException', function (err) { + process.send(err.message) +}) -require('runas'); -process.send('ok'); +require('runas') +process.send('ok') diff --git a/spec/fixtures/module/send-later.js b/spec/fixtures/module/send-later.js index 704f47d328d..8eb16f72f8c 100644 --- a/spec/fixtures/module/send-later.js +++ b/spec/fixtures/module/send-later.js @@ -1,4 +1,4 @@ -var ipcRenderer = require('electron').ipcRenderer; -window.onload = function() { - ipcRenderer.send('answer', typeof window.process); -}; +var ipcRenderer = require('electron').ipcRenderer +window.onload = function () { + ipcRenderer.send('answer', typeof window.process) +} diff --git a/spec/fixtures/module/set-global.js b/spec/fixtures/module/set-global.js index f39919ff9d8..ba4f30d155b 100644 --- a/spec/fixtures/module/set-global.js +++ b/spec/fixtures/module/set-global.js @@ -1 +1 @@ -window.test = 'preload'; +window.test = 'preload' diff --git a/spec/fixtures/module/set-immediate.js b/spec/fixtures/module/set-immediate.js index d36355ee23b..69563fd0a83 100644 --- a/spec/fixtures/module/set-immediate.js +++ b/spec/fixtures/module/set-immediate.js @@ -1,11 +1,11 @@ -process.on('uncaughtException', function(error) { - process.send(error.message); - process.exit(1); -}); +process.on('uncaughtException', function (error) { + process.send(error.message) + process.exit(1) +}) -process.on('message', function() { - setImmediate(function() { - process.send('ok'); - process.exit(0); - }); -}); +process.on('message', function () { + setImmediate(function () { + process.send('ok') + process.exit(0) + }) +}) diff --git a/spec/fixtures/pages/service-worker/service-worker.js b/spec/fixtures/pages/service-worker/service-worker.js index 854b3558a95..7d80f45e2df 100644 --- a/spec/fixtures/pages/service-worker/service-worker.js +++ b/spec/fixtures/pages/service-worker/service-worker.js @@ -1,9 +1,9 @@ -self.addEventListener('fetch', function(event) { - var requestUrl = new URL(event.request.url); +self.addEventListener('fetch', function (event) { + var requestUrl = new URL(event.request.url) if (requestUrl.pathname === '/echo' && - event.request.headers.has('X-Mock-Response')) { - var mockResponse = new Response('Hello from serviceWorker!'); - event.respondWith(mockResponse); + event.request.headers.has('X-Mock-Response')) { + var mockResponse = new Response('Hello from serviceWorker!') + event.respondWith(mockResponse) } -}); +}) diff --git a/spec/fixtures/workers/shared_worker.js b/spec/fixtures/workers/shared_worker.js index 40220793979..35cb40d03b5 100644 --- a/spec/fixtures/workers/shared_worker.js +++ b/spec/fixtures/workers/shared_worker.js @@ -1,7 +1,7 @@ -this.onconnect = function(event) { - var port = event.ports[0]; - port.start(); - port.onmessage = function(event) { - port.postMessage(event.data); - }; -}; +this.onconnect = function (event) { + var port = event.ports[0] + port.start() + port.onmessage = function (event) { + port.postMessage(event.data) + } +} diff --git a/spec/fixtures/workers/worker.js b/spec/fixtures/workers/worker.js index 4f445470b9a..884c17ac86e 100644 --- a/spec/fixtures/workers/worker.js +++ b/spec/fixtures/workers/worker.js @@ -1,3 +1,3 @@ -this.onmessage = function(msg) { - this.postMessage(msg.data); -}; +this.onmessage = function (msg) { + this.postMessage(msg.data) +} diff --git a/spec/modules-spec.js b/spec/modules-spec.js index fb53a90cf73..0f694e5e6d8 100644 --- a/spec/modules-spec.js +++ b/spec/modules-spec.js @@ -1,47 +1,47 @@ -const assert = require('assert'); -const path = require('path'); -const temp = require('temp'); +const assert = require('assert') +const path = require('path') +const temp = require('temp') -describe('third-party module', function() { - var fixtures = path.join(__dirname, 'fixtures'); - temp.track(); +describe('third-party module', function () { + var fixtures = path.join(__dirname, 'fixtures') + temp.track() if (process.platform !== 'win32' || process.execPath.toLowerCase().indexOf('\\out\\d\\') === -1) { - describe('runas', function() { - it('can be required in renderer', function() { - require('runas'); - }); + describe('runas', function () { + it('can be required in renderer', function () { + require('runas') + }) - it('can be required in node binary', function(done) { - var runas = path.join(fixtures, 'module', 'runas.js'); - var child = require('child_process').fork(runas); - child.on('message', function(msg) { - assert.equal(msg, 'ok'); - done(); - }); - }); - }); + it('can be required in node binary', function (done) { + var runas = path.join(fixtures, 'module', 'runas.js') + var child = require('child_process').fork(runas) + child.on('message', function (msg) { + assert.equal(msg, 'ok') + done() + }) + }) + }) - describe('ffi', function() { - it('does not crash', function() { - var ffi = require('ffi'); + describe('ffi', function () { + it('does not crash', function () { + var ffi = require('ffi') var libm = ffi.Library('libm', { ceil: ['double', ['double']] - }); - assert.equal(libm.ceil(1.5), 2); - }); - }); + }) + assert.equal(libm.ceil(1.5), 2) + }) + }) } - describe('q', function() { - var Q = require('q'); - describe('Q.when', function() { - it('emits the fullfil callback', function(done) { - Q(true).then(function(val) { - assert.equal(val, true); - done(); - }); - }); - }); - }); -}); + describe('q', function () { + var Q = require('q') + describe('Q.when', function () { + it('emits the fullfil callback', function (done) { + Q(true).then(function (val) { + assert.equal(val, true) + done() + }) + }) + }) + }) +}) diff --git a/spec/node-spec.js b/spec/node-spec.js index 83f685d95f0..286c4d6f916 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -1,220 +1,220 @@ -const assert = require('assert'); -const child_process = require('child_process'); -const fs = require('fs'); -const path = require('path'); -const os = require('os'); -const remote = require('electron').remote; +const assert = require('assert') +const child_process = require('child_process') +const fs = require('fs') +const path = require('path') +const os = require('os') +const remote = require('electron').remote -describe('node feature', function() { - var fixtures = path.join(__dirname, 'fixtures'); +describe('node feature', function () { + var fixtures = path.join(__dirname, 'fixtures') - describe('child_process', function() { - describe('child_process.fork', function() { - it('works in current process', function(done) { - var child = child_process.fork(path.join(fixtures, 'module', 'ping.js')); - child.on('message', function(msg) { - assert.equal(msg, 'message'); - done(); - }); - child.send('message'); - }); + describe('child_process', function () { + describe('child_process.fork', function () { + it('works in current process', function (done) { + var child = child_process.fork(path.join(fixtures, 'module', 'ping.js')) + child.on('message', function (msg) { + assert.equal(msg, 'message') + done() + }) + child.send('message') + }) - it('preserves args', function(done) { - var args = ['--expose_gc', '-test', '1']; - var child = child_process.fork(path.join(fixtures, 'module', 'process_args.js'), args); - child.on('message', function(msg) { - assert.deepEqual(args, msg.slice(2)); - done(); - }); - child.send('message'); - }); + it('preserves args', function (done) { + var args = ['--expose_gc', '-test', '1'] + var child = child_process.fork(path.join(fixtures, 'module', 'process_args.js'), args) + child.on('message', function (msg) { + assert.deepEqual(args, msg.slice(2)) + done() + }) + child.send('message') + }) - it('works in forked process', function(done) { - var child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js')); - child.on('message', function(msg) { - assert.equal(msg, 'message'); - done(); - }); - child.send('message'); - }); + it('works in forked process', function (done) { + var child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js')) + child.on('message', function (msg) { + assert.equal(msg, 'message') + done() + }) + child.send('message') + }) - it('works in forked process when options.env is specifed', function(done) { + it('works in forked process when options.env is specifed', function (done) { var child = child_process.fork(path.join(fixtures, 'module', 'fork_ping.js'), [], { path: process.env['PATH'] - }); - child.on('message', function(msg) { - assert.equal(msg, 'message'); - done(); - }); - child.send('message'); - }); + }) + child.on('message', function (msg) { + assert.equal(msg, 'message') + done() + }) + child.send('message') + }) - it('works in browser process', function(done) { - var fork = remote.require('child_process').fork; - var child = fork(path.join(fixtures, 'module', 'ping.js')); - child.on('message', function(msg) { - assert.equal(msg, 'message'); - done(); - }); - child.send('message'); - }); + it('works in browser process', function (done) { + var fork = remote.require('child_process').fork + var child = fork(path.join(fixtures, 'module', 'ping.js')) + child.on('message', function (msg) { + assert.equal(msg, 'message') + done() + }) + child.send('message') + }) - it('has String::localeCompare working in script', function(done) { - var child = child_process.fork(path.join(fixtures, 'module', 'locale-compare.js')); - child.on('message', function(msg) { - assert.deepEqual(msg, [0, -1, 1]); - done(); - }); - child.send('message'); - }); + it('has String::localeCompare working in script', function (done) { + var child = child_process.fork(path.join(fixtures, 'module', 'locale-compare.js')) + child.on('message', function (msg) { + assert.deepEqual(msg, [0, -1, 1]) + done() + }) + child.send('message') + }) - it('has setImmediate working in script', function(done) { - var child = child_process.fork(path.join(fixtures, 'module', 'set-immediate.js')); - child.on('message', function(msg) { - assert.equal(msg, 'ok'); - done(); - }); - child.send('message'); - }); - }); - }); + it('has setImmediate working in script', function (done) { + var child = child_process.fork(path.join(fixtures, 'module', 'set-immediate.js')) + child.on('message', function (msg) { + assert.equal(msg, 'ok') + done() + }) + child.send('message') + }) + }) + }) - describe('contexts', function() { - describe('setTimeout in fs callback', function() { + describe('contexts', function () { + describe('setTimeout in fs callback', function () { if (process.env.TRAVIS === 'true') { - return; + return } - it('does not crash', function(done) { - fs.readFile(__filename, function() { - setTimeout(done, 0); - }); - }); - }); + it('does not crash', function (done) { + fs.readFile(__filename, function () { + setTimeout(done, 0) + }) + }) + }) - describe('throw error in node context', function() { - it('gets caught', function(done) { - var error = new Error('boo!'); - var lsts = process.listeners('uncaughtException'); - process.removeAllListeners('uncaughtException'); - process.on('uncaughtException', function() { - var i, len, lst; - process.removeAllListeners('uncaughtException'); + describe('throw error in node context', function () { + it('gets caught', function (done) { + var error = new Error('boo!') + var lsts = process.listeners('uncaughtException') + process.removeAllListeners('uncaughtException') + process.on('uncaughtException', function () { + var i, len, lst + process.removeAllListeners('uncaughtException') for (i = 0, len = lsts.length; i < len; i++) { - lst = lsts[i]; - process.on('uncaughtException', lst); + lst = lsts[i] + process.on('uncaughtException', lst) } - done(); - }); - fs.readFile(__filename, function() { - throw error; - }); - }); - }); + done() + }) + fs.readFile(__filename, function () { + throw error + }) + }) + }) - describe('setTimeout called under Chromium event loop in browser process', function() { - it('can be scheduled in time', function(done) { - remote.getGlobal('setTimeout')(done, 0); - }); - }); + describe('setTimeout called under Chromium event loop in browser process', function () { + it('can be scheduled in time', function (done) { + remote.getGlobal('setTimeout')(done, 0) + }) + }) - describe('setInterval called under Chromium event loop in browser process', function() { - it('can be scheduled in time', function(done) { - var clear, interval; - clear = function() { - remote.getGlobal('clearInterval')(interval); - done(); - }; - interval = remote.getGlobal('setInterval')(clear, 10); - }); - }); - }); + describe('setInterval called under Chromium event loop in browser process', function () { + it('can be scheduled in time', function (done) { + var clear, interval + clear = function () { + remote.getGlobal('clearInterval')(interval) + done() + } + interval = remote.getGlobal('setInterval')(clear, 10) + }) + }) + }) - describe('message loop', function() { - describe('process.nextTick', function() { - it('emits the callback', function(done) { - process.nextTick(done); - }); + describe('message loop', function () { + describe('process.nextTick', function () { + it('emits the callback', function (done) { + process.nextTick(done) + }) - it('works in nested calls', function(done) { - process.nextTick(function() { - process.nextTick(function() { - process.nextTick(done); - }); - }); - }); - }); + it('works in nested calls', function (done) { + process.nextTick(function () { + process.nextTick(function () { + process.nextTick(done) + }) + }) + }) + }) - describe('setImmediate', function() { - it('emits the callback', function(done) { - setImmediate(done); - }); + describe('setImmediate', function () { + it('emits the callback', function (done) { + setImmediate(done) + }) - it('works in nested calls', function(done) { - setImmediate(function() { - setImmediate(function() { - setImmediate(done); - }); - }); - }); - }); - }); + it('works in nested calls', function (done) { + setImmediate(function () { + setImmediate(function () { + setImmediate(done) + }) + }) + }) + }) + }) - describe('net.connect', function() { + describe('net.connect', function () { if (process.platform !== 'darwin') { - return; + return } - it('emit error when connect to a socket path without listeners', function(done) { - var socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock'); - var script = path.join(fixtures, 'module', 'create_socket.js'); - var child = child_process.fork(script, [socketPath]); - child.on('exit', function(code) { - assert.equal(code, 0); - var client = require('net').connect(socketPath); - client.on('error', function(error) { - assert.equal(error.code, 'ECONNREFUSED'); - done(); - }); - }); - }); - }); + it('emit error when connect to a socket path without listeners', function (done) { + var socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock') + var script = path.join(fixtures, 'module', 'create_socket.js') + var child = child_process.fork(script, [socketPath]) + child.on('exit', function (code) { + assert.equal(code, 0) + var client = require('net').connect(socketPath) + client.on('error', function (error) { + assert.equal(error.code, 'ECONNREFUSED') + done() + }) + }) + }) + }) - describe('Buffer', function() { - it('can be created from WebKit external string', function() { - var p = document.createElement('p'); - p.innerText = '闲云潭影日悠悠,物换星移几度秋'; - var b = new Buffer(p.innerText); - assert.equal(b.toString(), '闲云潭影日悠悠,物换星移几度秋'); - assert.equal(Buffer.byteLength(p.innerText), 45); - }); + describe('Buffer', function () { + it('can be created from WebKit external string', function () { + var p = document.createElement('p') + p.innerText = '闲云潭影日悠悠,物换星移几度秋' + var b = new Buffer(p.innerText) + assert.equal(b.toString(), '闲云潭影日悠悠,物换星移几度秋') + assert.equal(Buffer.byteLength(p.innerText), 45) + }) - it('correctly parses external one-byte UTF8 string', function() { - var p = document.createElement('p'); - p.innerText = 'Jøhänñéß'; - var b = new Buffer(p.innerText); - assert.equal(b.toString(), 'Jøhänñéß'); - assert.equal(Buffer.byteLength(p.innerText), 13); - }); - }); + it('correctly parses external one-byte UTF8 string', function () { + var p = document.createElement('p') + p.innerText = 'Jøhänñéß' + var b = new Buffer(p.innerText) + assert.equal(b.toString(), 'Jøhänñéß') + assert.equal(Buffer.byteLength(p.innerText), 13) + }) + }) - describe('process.stdout', function() { - it('should not throw exception', function() { - process.stdout; - }); + describe('process.stdout', function () { + it('should not throw exception', function () { + process.stdout + }) - it('should not throw exception when calling write()', function() { - process.stdout.write('test'); - }); + it('should not throw exception when calling write()', function () { + process.stdout.write('test') + }) - xit('should have isTTY defined', function() { - assert.equal(typeof process.stdout.isTTY, 'boolean'); - }); - }); + xit('should have isTTY defined', function () { + assert.equal(typeof process.stdout.isTTY, 'boolean') + }) + }) - describe('vm.createContext', function() { - it('should not crash', function() { - require('vm').runInNewContext(''); - }); - }); -}); + describe('vm.createContext', function () { + it('should not crash', function () { + require('vm').runInNewContext('') + }) + }) +}) diff --git a/spec/static/main.js b/spec/static/main.js index 77a3c392722..f1d2a5eafa6 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -1,81 +1,81 @@ // Disable use of deprecated functions. -process.throwDeprecation = true; +process.throwDeprecation = true -const electron = require('electron'); -const app = electron.app; -const ipcMain = electron.ipcMain; -const dialog = electron.dialog; -const BrowserWindow = electron.BrowserWindow; +const electron = require('electron') +const app = electron.app +const ipcMain = electron.ipcMain +const dialog = electron.dialog +const BrowserWindow = electron.BrowserWindow -const path = require('path'); -const url = require('url'); +const path = require('path') +const url = require('url') var argv = require('yargs') .boolean('ci') .string('g').alias('g', 'grep') .boolean('i').alias('i', 'invert') - .argv; + .argv -var window = null; -process.port = 0; // will be used by crash-reporter spec. +var window = null +process.port = 0; // will be used by crash-reporter spec. -app.commandLine.appendSwitch('js-flags', '--expose_gc'); -app.commandLine.appendSwitch('ignore-certificate-errors'); -app.commandLine.appendSwitch('disable-renderer-backgrounding'); +app.commandLine.appendSwitch('js-flags', '--expose_gc') +app.commandLine.appendSwitch('ignore-certificate-errors') +app.commandLine.appendSwitch('disable-renderer-backgrounding') // Accessing stdout in the main process will result in the process.stdout // throwing UnknownSystemError in renderer process sometimes. This line makes // sure we can reproduce it in renderer process. -process.stdout; +process.stdout // Access console to reproduce #3482. -console; +console -ipcMain.on('message', function(event, arg) { - event.sender.send('message', arg); -}); +ipcMain.on('message', function (event, arg) { + event.sender.send('message', arg) +}) -ipcMain.on('console.log', function(event, args) { - console.error.apply(console, args); -}); +ipcMain.on('console.log', function (event, args) { + console.error.apply(console, args) +}) -ipcMain.on('console.error', function(event, args) { - console.error.apply(console, args); -}); +ipcMain.on('console.error', function (event, args) { + console.error.apply(console, args) +}) -ipcMain.on('process.exit', function(event, code) { - process.exit(code); -}); +ipcMain.on('process.exit', function (event, code) { + process.exit(code) +}) -ipcMain.on('eval', function(event, script) { - event.returnValue = eval(script); -}); +ipcMain.on('eval', function (event, script) { + event.returnValue = eval(script) +}) -ipcMain.on('echo', function(event, msg) { - event.returnValue = msg; -}); +ipcMain.on('echo', function (event, msg) { + event.returnValue = msg +}) -global.isCi = !!argv.ci; +global.isCi = !!argv.ci if (global.isCi) { - process.removeAllListeners('uncaughtException'); - process.on('uncaughtException', function(error) { - console.error(error, error.stack); - process.exit(1); - }); + process.removeAllListeners('uncaughtException') + process.on('uncaughtException', function (error) { + console.error(error, error.stack) + process.exit(1) + }) } -app.on('window-all-closed', function() { - app.quit(); -}); +app.on('window-all-closed', function () { + app.quit() +}) -app.on('ready', function() { +app.on('ready', function () { // Test if using protocol module would crash. - electron.protocol.registerStringProtocol('test-if-crashes', function() {}); + electron.protocol.registerStringProtocol('test-if-crashes', function () {}) // Send auto updater errors to window to be verified in specs electron.autoUpdater.on('error', function (error) { - window.send('auto-updater-error', error.message); - }); + window.send('auto-updater-error', error.message) + }) window = new BrowserWindow({ title: 'Electron Tests', @@ -83,70 +83,70 @@ app.on('ready', function() { width: 800, height: 600, webPreferences: { - javascript: true // Test whether web preferences crashes. + javascript: true // Test whether web preferences crashes. }, - }); + }) window.loadURL(url.format({ pathname: __dirname + '/index.html', protocol: 'file', query: { grep: argv.grep, - invert: argv.invert ? 'true': '' + invert: argv.invert ? 'true' : '' } - })); - window.on('unresponsive', function() { + })) + window.on('unresponsive', function () { var chosen = dialog.showMessageBox(window, { type: 'warning', buttons: ['Close', 'Keep Waiting'], message: 'Window is not responsing', detail: 'The window is not responding. Would you like to force close it or just keep waiting?' - }); - if (chosen === 0) window.destroy(); - }); + }) + if (chosen === 0) window.destroy() + }) // For session's download test, listen 'will-download' event in browser, and // reply the result to renderer for verifying - var downloadFilePath = path.join(__dirname, '..', 'fixtures', 'mock.pdf'); - ipcMain.on('set-download-option', function(event, need_cancel, prevent_default) { - window.webContents.session.once('will-download', function(e, item) { + var downloadFilePath = path.join(__dirname, '..', 'fixtures', 'mock.pdf') + ipcMain.on('set-download-option', function (event, need_cancel, prevent_default) { + window.webContents.session.once('will-download', function (e, item) { if (prevent_default) { - e.preventDefault(); - const url = item.getURL(); - const filename = item.getFilename(); - setImmediate(function() { + e.preventDefault() + const url = item.getURL() + const filename = item.getFilename() + setImmediate(function () { try { - item.getURL(); + item.getURL() } catch(err) { - window.webContents.send('download-error', url, filename, err.message); + window.webContents.send('download-error', url, filename, err.message) } - }); + }) } else { - item.setSavePath(downloadFilePath); - item.on('done', function(e, state) { + item.setSavePath(downloadFilePath) + item.on('done', function (e, state) { window.webContents.send('download-done', - state, - item.getURL(), - item.getMimeType(), - item.getReceivedBytes(), - item.getTotalBytes(), - item.getContentDisposition(), - item.getFilename()); - }); + state, + item.getURL(), + item.getMimeType(), + item.getReceivedBytes(), + item.getTotalBytes(), + item.getContentDisposition(), + item.getFilename()) + }) if (need_cancel) - item.cancel(); + item.cancel() } - }); - event.returnValue = "done"; - }); + }) + event.returnValue = 'done' + }) - ipcMain.on('executeJavaScript', function(event, code, hasCallback) { + ipcMain.on('executeJavaScript', function (event, code, hasCallback) { if (hasCallback) { window.webContents.executeJavaScript(code, (result) => { - window.webContents.send('executeJavaScript-response', result); - }); + window.webContents.send('executeJavaScript-response', result) + }) } else { - window.webContents.executeJavaScript(code); - event.returnValue = "success"; + window.webContents.executeJavaScript(code) + event.returnValue = 'success' } - }); -}); + }) +}) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 2d0a6282be3..1bb18c0b5e7 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -1,746 +1,746 @@ -const assert = require('assert'); -const path = require('path'); -const http = require('http'); -const url = require('url'); +const assert = require('assert') +const path = require('path') +const http = require('http') +const url = require('url') -describe(' tag', function() { - this.timeout(10000); +describe(' tag', function () { + this.timeout(10000) - var fixtures = path.join(__dirname, 'fixtures'); - var webview = null; + var fixtures = path.join(__dirname, 'fixtures') + var webview = null - beforeEach(function() { - webview = new WebView; - }); + beforeEach(function () { + webview = new WebView + }) - afterEach(function() { + afterEach(function () { if (document.body.contains(webview)) { - document.body.removeChild(webview); + document.body.removeChild(webview) } - }); + }) - describe('src attribute', function() { - it('specifies the page to load', function(done) { - webview.addEventListener('console-message', function(e) { - assert.equal(e.message, 'a'); - done(); - }); - webview.src = "file://" + fixtures + "/pages/a.html"; - document.body.appendChild(webview); - }); + describe('src attribute', function () { + it('specifies the page to load', function (done) { + webview.addEventListener('console-message', function (e) { + assert.equal(e.message, 'a') + done() + }) + webview.src = 'file://' + fixtures + '/pages/a.html' + document.body.appendChild(webview) + }) - it('navigates to new page when changed', function(done) { - var listener = function() { - webview.src = "file://" + fixtures + "/pages/b.html"; - webview.addEventListener('console-message', function(e) { - assert.equal(e.message, 'b'); - done(); - }); - webview.removeEventListener('did-finish-load', listener); - }; - webview.addEventListener('did-finish-load', listener); - webview.src = "file://" + fixtures + "/pages/a.html"; - document.body.appendChild(webview); - }); - }); + it('navigates to new page when changed', function (done) { + var listener = function () { + webview.src = 'file://' + fixtures + '/pages/b.html' + webview.addEventListener('console-message', function (e) { + assert.equal(e.message, 'b') + done() + }) + webview.removeEventListener('did-finish-load', listener) + } + webview.addEventListener('did-finish-load', listener) + webview.src = 'file://' + fixtures + '/pages/a.html' + document.body.appendChild(webview) + }) + }) - describe('nodeintegration attribute', function() { - it('inserts no node symbols when not set', function(done) { - webview.addEventListener('console-message', function(e) { - assert.equal(e.message, 'undefined undefined undefined undefined'); - done(); - }); - webview.src = "file://" + fixtures + "/pages/c.html"; - document.body.appendChild(webview); - }); + describe('nodeintegration attribute', function () { + it('inserts no node symbols when not set', function (done) { + webview.addEventListener('console-message', function (e) { + assert.equal(e.message, 'undefined undefined undefined undefined') + done() + }) + webview.src = 'file://' + fixtures + '/pages/c.html' + document.body.appendChild(webview) + }) - it('inserts node symbols when set', function(done) { - webview.addEventListener('console-message', function(e) { - assert.equal(e.message, 'function object object'); - done(); - }); - webview.setAttribute('nodeintegration', 'on'); - webview.src = "file://" + fixtures + "/pages/d.html"; - document.body.appendChild(webview); - }); + it('inserts node symbols when set', function (done) { + webview.addEventListener('console-message', function (e) { + assert.equal(e.message, 'function object object') + done() + }) + webview.setAttribute('nodeintegration', 'on') + webview.src = 'file://' + fixtures + '/pages/d.html' + document.body.appendChild(webview) + }) - it('loads node symbols after POST navigation when set', function(done) { - webview.addEventListener('console-message', function(e) { - assert.equal(e.message, 'function object object'); - done(); - }); - webview.setAttribute('nodeintegration', 'on'); - webview.src = "file://" + fixtures + "/pages/post.html"; - document.body.appendChild(webview); - }); + it('loads node symbols after POST navigation when set', function (done) { + webview.addEventListener('console-message', function (e) { + assert.equal(e.message, 'function object object') + done() + }) + webview.setAttribute('nodeintegration', 'on') + webview.src = 'file://' + fixtures + '/pages/post.html' + document.body.appendChild(webview) + }) if (process.platform !== 'win32' || process.execPath.toLowerCase().indexOf('\\out\\d\\') === -1) { - it('loads native modules when navigation happens', function(done) { - var listener = function() { - webview.removeEventListener('did-finish-load', listener); - var listener2 = function(e) { - assert.equal(e.message, 'function'); - done(); - }; - webview.addEventListener('console-message', listener2); - webview.reload(); - }; - webview.addEventListener('did-finish-load', listener); - webview.setAttribute('nodeintegration', 'on'); - webview.src = "file://" + fixtures + "/pages/native-module.html"; - document.body.appendChild(webview); - }); + it('loads native modules when navigation happens', function (done) { + var listener = function () { + webview.removeEventListener('did-finish-load', listener) + var listener2 = function (e) { + assert.equal(e.message, 'function') + done() + } + webview.addEventListener('console-message', listener2) + webview.reload() + } + webview.addEventListener('did-finish-load', listener) + webview.setAttribute('nodeintegration', 'on') + webview.src = 'file://' + fixtures + '/pages/native-module.html' + document.body.appendChild(webview) + }) } - }); + }) - describe('preload attribute', function() { - it('loads the script before other scripts in window', function(done) { - var listener = function(e) { - assert.equal(e.message, 'function object object'); - webview.removeEventListener('console-message', listener); - done(); - }; - webview.addEventListener('console-message', listener); - webview.setAttribute('preload', fixtures + "/module/preload.js"); - webview.src = "file://" + fixtures + "/pages/e.html"; - document.body.appendChild(webview); - }); + describe('preload attribute', function () { + it('loads the script before other scripts in window', function (done) { + var listener = function (e) { + assert.equal(e.message, 'function object object') + webview.removeEventListener('console-message', listener) + done() + } + webview.addEventListener('console-message', listener) + webview.setAttribute('preload', fixtures + '/module/preload.js') + webview.src = 'file://' + fixtures + '/pages/e.html' + document.body.appendChild(webview) + }) - it('preload script can still use "process" in required modules when nodeintegration is off', function(done) { - webview.addEventListener('console-message', function(e) { - assert.equal(e.message, 'object undefined object'); - done(); - }); - webview.setAttribute('preload', fixtures + "/module/preload-node-off.js"); - webview.src = "file://" + fixtures + "/api/blank.html"; - document.body.appendChild(webview); - }); + it('preload script can still use "process" in required modules when nodeintegration is off', function (done) { + webview.addEventListener('console-message', function (e) { + assert.equal(e.message, 'object undefined object') + done() + }) + webview.setAttribute('preload', fixtures + '/module/preload-node-off.js') + webview.src = 'file://' + fixtures + '/api/blank.html' + document.body.appendChild(webview) + }) - it('receives ipc message in preload script', function(done) { - var message = 'boom!'; - var listener = function(e) { - assert.equal(e.channel, 'pong'); - assert.deepEqual(e.args, [message]); - webview.removeEventListener('ipc-message', listener); - done(); - }; - var listener2 = function() { - webview.send('ping', message); - webview.removeEventListener('did-finish-load', listener2); - }; - webview.addEventListener('ipc-message', listener); - webview.addEventListener('did-finish-load', listener2); - webview.setAttribute('preload', fixtures + "/module/preload-ipc.js"); - webview.src = "file://" + fixtures + "/pages/e.html"; - document.body.appendChild(webview); - }); - }); + it('receives ipc message in preload script', function (done) { + var message = 'boom!' + var listener = function (e) { + assert.equal(e.channel, 'pong') + assert.deepEqual(e.args, [message]) + webview.removeEventListener('ipc-message', listener) + done() + } + var listener2 = function () { + webview.send('ping', message) + webview.removeEventListener('did-finish-load', listener2) + } + webview.addEventListener('ipc-message', listener) + webview.addEventListener('did-finish-load', listener2) + webview.setAttribute('preload', fixtures + '/module/preload-ipc.js') + webview.src = 'file://' + fixtures + '/pages/e.html' + document.body.appendChild(webview) + }) + }) - describe('httpreferrer attribute', function() { - it('sets the referrer url', function(done) { - var referrer = 'http://github.com/'; - var listener = function(e) { - assert.equal(e.message, referrer); - webview.removeEventListener('console-message', listener); - done(); - }; - webview.addEventListener('console-message', listener); - webview.setAttribute('httpreferrer', referrer); - webview.src = "file://" + fixtures + "/pages/referrer.html"; - document.body.appendChild(webview); - }); - }); + describe('httpreferrer attribute', function () { + it('sets the referrer url', function (done) { + var referrer = 'http://github.com/' + var listener = function (e) { + assert.equal(e.message, referrer) + webview.removeEventListener('console-message', listener) + done() + } + webview.addEventListener('console-message', listener) + webview.setAttribute('httpreferrer', referrer) + webview.src = 'file://' + fixtures + '/pages/referrer.html' + document.body.appendChild(webview) + }) + }) - describe('useragent attribute', function() { - it('sets the user agent', function(done) { - var referrer = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'; - var listener = function(e) { - assert.equal(e.message, referrer); - webview.removeEventListener('console-message', listener); - done(); - }; - webview.addEventListener('console-message', listener); - webview.setAttribute('useragent', referrer); - webview.src = "file://" + fixtures + "/pages/useragent.html"; - document.body.appendChild(webview); - }); - }); + describe('useragent attribute', function () { + it('sets the user agent', function (done) { + var referrer = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko' + var listener = function (e) { + assert.equal(e.message, referrer) + webview.removeEventListener('console-message', listener) + done() + } + webview.addEventListener('console-message', listener) + webview.setAttribute('useragent', referrer) + webview.src = 'file://' + fixtures + '/pages/useragent.html' + document.body.appendChild(webview) + }) + }) - describe('disablewebsecurity attribute', function() { - it('does not disable web security when not set', function(done) { - var src = " "; - var encoded = btoa(unescape(encodeURIComponent(src))); - var listener = function(e) { - assert(/Not allowed to load local resource/.test(e.message)); - webview.removeEventListener('console-message', listener); - done(); - }; - webview.addEventListener('console-message', listener); - webview.src = "data:text/html;base64," + encoded; - document.body.appendChild(webview); - }); + describe('disablewebsecurity attribute', function () { + it('does not disable web security when not set', function (done) { + var src = " " + var encoded = btoa(unescape(encodeURIComponent(src))) + var listener = function (e) { + assert(/Not allowed to load local resource/.test(e.message)) + webview.removeEventListener('console-message', listener) + done() + } + webview.addEventListener('console-message', listener) + webview.src = 'data:text/html;base64,' + encoded + document.body.appendChild(webview) + }) - it('disables web security when set', function(done) { - var src = " "; - var encoded = btoa(unescape(encodeURIComponent(src))); - var listener = function(e) { - assert.equal(e.message, 'ok'); - webview.removeEventListener('console-message', listener); - done(); - }; - webview.addEventListener('console-message', listener); - webview.setAttribute('disablewebsecurity', ''); - webview.src = "data:text/html;base64," + encoded; - document.body.appendChild(webview); - }); - }); + it('disables web security when set', function (done) { + var src = " " + var encoded = btoa(unescape(encodeURIComponent(src))) + var listener = function (e) { + assert.equal(e.message, 'ok') + webview.removeEventListener('console-message', listener) + done() + } + webview.addEventListener('console-message', listener) + webview.setAttribute('disablewebsecurity', '') + webview.src = 'data:text/html;base64,' + encoded + document.body.appendChild(webview) + }) + }) - describe('partition attribute', function() { - it('inserts no node symbols when not set', function(done) { - webview.addEventListener('console-message', function(e) { - assert.equal(e.message, 'undefined undefined undefined undefined'); - done(); - }); - webview.src = "file://" + fixtures + "/pages/c.html"; - webview.partition = 'test1'; - document.body.appendChild(webview); - }); + describe('partition attribute', function () { + it('inserts no node symbols when not set', function (done) { + webview.addEventListener('console-message', function (e) { + assert.equal(e.message, 'undefined undefined undefined undefined') + done() + }) + webview.src = 'file://' + fixtures + '/pages/c.html' + webview.partition = 'test1' + document.body.appendChild(webview) + }) - it('inserts node symbols when set', function(done) { - webview.addEventListener('console-message', function(e) { - assert.equal(e.message, 'function object object'); - done(); - }); - webview.setAttribute('nodeintegration', 'on'); - webview.src = "file://" + fixtures + "/pages/d.html"; - webview.partition = 'test2'; - document.body.appendChild(webview); - }); + it('inserts node symbols when set', function (done) { + webview.addEventListener('console-message', function (e) { + assert.equal(e.message, 'function object object') + done() + }) + webview.setAttribute('nodeintegration', 'on') + webview.src = 'file://' + fixtures + '/pages/d.html' + webview.partition = 'test2' + document.body.appendChild(webview) + }) - it('isolates storage for different id', function(done) { - var listener = function(e) { - assert.equal(e.message, " 0"); - webview.removeEventListener('console-message', listener); - done(); - }; - window.localStorage.setItem('test', 'one'); - webview.addEventListener('console-message', listener); - webview.src = "file://" + fixtures + "/pages/partition/one.html"; - webview.partition = 'test3'; - document.body.appendChild(webview); - }); + it('isolates storage for different id', function (done) { + var listener = function (e) { + assert.equal(e.message, ' 0') + webview.removeEventListener('console-message', listener) + done() + } + window.localStorage.setItem('test', 'one') + webview.addEventListener('console-message', listener) + webview.src = 'file://' + fixtures + '/pages/partition/one.html' + webview.partition = 'test3' + document.body.appendChild(webview) + }) - it('uses current session storage when no id is provided', function(done) { - var listener = function(e) { - assert.equal(e.message, "one 1"); - webview.removeEventListener('console-message', listener); - done(); - }; - window.localStorage.setItem('test', 'one'); - webview.addEventListener('console-message', listener); - webview.src = "file://" + fixtures + "/pages/partition/one.html"; - document.body.appendChild(webview); - }); - }); + it('uses current session storage when no id is provided', function (done) { + var listener = function (e) { + assert.equal(e.message, 'one 1') + webview.removeEventListener('console-message', listener) + done() + } + window.localStorage.setItem('test', 'one') + webview.addEventListener('console-message', listener) + webview.src = 'file://' + fixtures + '/pages/partition/one.html' + document.body.appendChild(webview) + }) + }) - describe('allowpopups attribute', function() { - it('can not open new window when not set', function(done) { - var listener = function(e) { - assert.equal(e.message, 'null'); - webview.removeEventListener('console-message', listener); - done(); - }; - webview.addEventListener('console-message', listener); - webview.src = "file://" + fixtures + "/pages/window-open-hide.html"; - document.body.appendChild(webview); - }); + describe('allowpopups attribute', function () { + it('can not open new window when not set', function (done) { + var listener = function (e) { + assert.equal(e.message, 'null') + webview.removeEventListener('console-message', listener) + done() + } + webview.addEventListener('console-message', listener) + webview.src = 'file://' + fixtures + '/pages/window-open-hide.html' + document.body.appendChild(webview) + }) - it('can open new window when set', function(done) { - var listener = function(e) { - assert.equal(e.message, 'window'); - webview.removeEventListener('console-message', listener); - done(); - }; - webview.addEventListener('console-message', listener); - webview.setAttribute('allowpopups', 'on'); - webview.src = "file://" + fixtures + "/pages/window-open-hide.html"; - document.body.appendChild(webview); - }); - }); + it('can open new window when set', function (done) { + var listener = function (e) { + assert.equal(e.message, 'window') + webview.removeEventListener('console-message', listener) + done() + } + webview.addEventListener('console-message', listener) + webview.setAttribute('allowpopups', 'on') + webview.src = 'file://' + fixtures + '/pages/window-open-hide.html' + document.body.appendChild(webview) + }) + }) - describe('new-window event', function() { - it('emits when window.open is called', function(done) { - webview.addEventListener('new-window', function(e) { - assert.equal(e.url, 'http://host/'); - assert.equal(e.frameName, 'host'); - done(); - }); - webview.src = "file://" + fixtures + "/pages/window-open.html"; - document.body.appendChild(webview); - }); + describe('new-window event', function () { + it('emits when window.open is called', function (done) { + webview.addEventListener('new-window', function (e) { + assert.equal(e.url, 'http://host/') + assert.equal(e.frameName, 'host') + done() + }) + webview.src = 'file://' + fixtures + '/pages/window-open.html' + document.body.appendChild(webview) + }) - it('emits when link with target is called', function(done) { - webview.addEventListener('new-window', function(e) { - assert.equal(e.url, 'http://host/'); - assert.equal(e.frameName, 'target'); - done(); - }); - webview.src = "file://" + fixtures + "/pages/target-name.html"; - document.body.appendChild(webview); - }); - }); + it('emits when link with target is called', function (done) { + webview.addEventListener('new-window', function (e) { + assert.equal(e.url, 'http://host/') + assert.equal(e.frameName, 'target') + done() + }) + webview.src = 'file://' + fixtures + '/pages/target-name.html' + document.body.appendChild(webview) + }) + }) - describe('ipc-message event', function() { - it('emits when guest sends a ipc message to browser', function(done) { - webview.addEventListener('ipc-message', function(e) { - assert.equal(e.channel, 'channel'); - assert.deepEqual(e.args, ['arg1', 'arg2']); - done(); - }); - webview.src = "file://" + fixtures + "/pages/ipc-message.html"; - webview.setAttribute('nodeintegration', 'on'); - document.body.appendChild(webview); - }); - }); + describe('ipc-message event', function () { + it('emits when guest sends a ipc message to browser', function (done) { + webview.addEventListener('ipc-message', function (e) { + assert.equal(e.channel, 'channel') + assert.deepEqual(e.args, ['arg1', 'arg2']) + done() + }) + webview.src = 'file://' + fixtures + '/pages/ipc-message.html' + webview.setAttribute('nodeintegration', 'on') + document.body.appendChild(webview) + }) + }) - describe('page-title-set event', function() { - it('emits when title is set', function(done) { - webview.addEventListener('page-title-set', function(e) { - assert.equal(e.title, 'test'); - assert(e.explicitSet); - done(); - }); - webview.src = "file://" + fixtures + "/pages/a.html"; - document.body.appendChild(webview); - }); - }); + describe('page-title-set event', function () { + it('emits when title is set', function (done) { + webview.addEventListener('page-title-set', function (e) { + assert.equal(e.title, 'test') + assert(e.explicitSet) + done() + }) + webview.src = 'file://' + fixtures + '/pages/a.html' + document.body.appendChild(webview) + }) + }) - describe('page-favicon-updated event', function() { - it('emits when favicon urls are received', function(done) { - webview.addEventListener('page-favicon-updated', function(e) { - assert.equal(e.favicons.length, 2); - var pageUrl = process.platform === 'win32' ? 'file:///C:/favicon.png' : 'file:///favicon.png'; - assert.equal(e.favicons[0], pageUrl); - done(); - }); - webview.src = "file://" + fixtures + "/pages/a.html"; - document.body.appendChild(webview); - }); - }); + describe('page-favicon-updated event', function () { + it('emits when favicon urls are received', function (done) { + webview.addEventListener('page-favicon-updated', function (e) { + assert.equal(e.favicons.length, 2) + var pageUrl = process.platform === 'win32' ? 'file:///C:/favicon.png' : 'file:///favicon.png' + assert.equal(e.favicons[0], pageUrl) + done() + }) + webview.src = 'file://' + fixtures + '/pages/a.html' + document.body.appendChild(webview) + }) + }) - describe('will-navigate event', function() { - it('emits when a url that leads to oustide of the page is clicked', function(done) { - webview.addEventListener('will-navigate', function(e) { - assert.equal(e.url, "http://host/"); - done(); - }); - webview.src = "file://" + fixtures + "/pages/webview-will-navigate.html"; - document.body.appendChild(webview); - }); - }); + describe('will-navigate event', function () { + it('emits when a url that leads to oustide of the page is clicked', function (done) { + webview.addEventListener('will-navigate', function (e) { + assert.equal(e.url, 'http://host/') + done() + }) + webview.src = 'file://' + fixtures + '/pages/webview-will-navigate.html' + document.body.appendChild(webview) + }) + }) - describe('did-navigate event', function() { - var p = path.join(fixtures, 'pages', 'webview-will-navigate.html'); - p = p.replace(/\\/g, '/'); + describe('did-navigate event', function () { + var p = path.join(fixtures, 'pages', 'webview-will-navigate.html') + p = p.replace(/\\/g, '/') var pageUrl = url.format({ protocol: 'file', slashes: true, pathname: p - }); + }) - it('emits when a url that leads to outside of the page is clicked', function(done) { - webview.addEventListener('did-navigate', function(e) { - assert.equal(e.url, pageUrl); - done(); - }); - webview.src = pageUrl; - document.body.appendChild(webview); - }); - }); + it('emits when a url that leads to outside of the page is clicked', function (done) { + webview.addEventListener('did-navigate', function (e) { + assert.equal(e.url, pageUrl) + done() + }) + webview.src = pageUrl + document.body.appendChild(webview) + }) + }) - describe('did-navigate-in-page event', function() { - it('emits when an anchor link is clicked', function(done) { - var p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page.html'); - p = p.replace(/\\/g, '/'); + describe('did-navigate-in-page event', function () { + it('emits when an anchor link is clicked', function (done) { + var p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page.html') + p = p.replace(/\\/g, '/') var pageUrl = url.format({ protocol: 'file', slashes: true, pathname: p - }); - webview.addEventListener('did-navigate-in-page', function(e) { - assert.equal(e.url, pageUrl + "#test_content"); - done(); - }); - webview.src = pageUrl; - document.body.appendChild(webview); - }); + }) + webview.addEventListener('did-navigate-in-page', function (e) { + assert.equal(e.url, pageUrl + '#test_content') + done() + }) + webview.src = pageUrl + document.body.appendChild(webview) + }) - it('emits when window.history.replaceState is called', function(done) { - webview.addEventListener('did-navigate-in-page', function(e) { - assert.equal(e.url, "http://host/"); - done(); - }); - webview.src = "file://" + fixtures + "/pages/webview-did-navigate-in-page-with-history.html"; - document.body.appendChild(webview); - }); + it('emits when window.history.replaceState is called', function (done) { + webview.addEventListener('did-navigate-in-page', function (e) { + assert.equal(e.url, 'http://host/') + done() + }) + webview.src = 'file://' + fixtures + '/pages/webview-did-navigate-in-page-with-history.html' + document.body.appendChild(webview) + }) - it('emits when window.location.hash is changed', function(done) { - var p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page-with-hash.html'); - p = p.replace(/\\/g, '/'); + it('emits when window.location.hash is changed', function (done) { + var p = path.join(fixtures, 'pages', 'webview-did-navigate-in-page-with-hash.html') + p = p.replace(/\\/g, '/') var pageUrl = url.format({ protocol: 'file', slashes: true, pathname: p - }); - webview.addEventListener('did-navigate-in-page', function(e) { - assert.equal(e.url, pageUrl + "#test"); - done(); - }); - webview.src = pageUrl; - document.body.appendChild(webview); - }); - }); + }) + webview.addEventListener('did-navigate-in-page', function (e) { + assert.equal(e.url, pageUrl + '#test') + done() + }) + webview.src = pageUrl + document.body.appendChild(webview) + }) + }) - describe('close event', function() { - it('should fire when interior page calls window.close', function(done) { - webview.addEventListener('close', function() { - done(); - }); - webview.src = "file://" + fixtures + "/pages/close.html"; - document.body.appendChild(webview); - }); - }); + describe('close event', function () { + it('should fire when interior page calls window.close', function (done) { + webview.addEventListener('close', function () { + done() + }) + webview.src = 'file://' + fixtures + '/pages/close.html' + document.body.appendChild(webview) + }) + }) - describe('devtools-opened event', function() { - it('should fire when webview.openDevTools() is called', function(done) { - var listener = function() { - webview.removeEventListener('devtools-opened', listener); - webview.closeDevTools(); - done(); - }; - webview.addEventListener('devtools-opened', listener); - webview.addEventListener('dom-ready', function() { - webview.openDevTools(); - }); - webview.src = "file://" + fixtures + "/pages/base-page.html"; - document.body.appendChild(webview); - }); - }); + describe('devtools-opened event', function () { + it('should fire when webview.openDevTools() is called', function (done) { + var listener = function () { + webview.removeEventListener('devtools-opened', listener) + webview.closeDevTools() + done() + } + webview.addEventListener('devtools-opened', listener) + webview.addEventListener('dom-ready', function () { + webview.openDevTools() + }) + webview.src = 'file://' + fixtures + '/pages/base-page.html' + document.body.appendChild(webview) + }) + }) - describe('devtools-closed event', function() { - it('should fire when webview.closeDevTools() is called', function(done) { - var listener2 = function() { - webview.removeEventListener('devtools-closed', listener2); - done(); - }; - var listener = function() { - webview.removeEventListener('devtools-opened', listener); - webview.closeDevTools(); - }; - webview.addEventListener('devtools-opened', listener); - webview.addEventListener('devtools-closed', listener2); - webview.addEventListener('dom-ready', function() { - webview.openDevTools(); - }); - webview.src = "file://" + fixtures + "/pages/base-page.html"; - document.body.appendChild(webview); - }); - }); + describe('devtools-closed event', function () { + it('should fire when webview.closeDevTools() is called', function (done) { + var listener2 = function () { + webview.removeEventListener('devtools-closed', listener2) + done() + } + var listener = function () { + webview.removeEventListener('devtools-opened', listener) + webview.closeDevTools() + } + webview.addEventListener('devtools-opened', listener) + webview.addEventListener('devtools-closed', listener2) + webview.addEventListener('dom-ready', function () { + webview.openDevTools() + }) + webview.src = 'file://' + fixtures + '/pages/base-page.html' + document.body.appendChild(webview) + }) + }) - describe('devtools-focused event', function() { - it('should fire when webview.openDevTools() is called', function(done) { - var listener = function() { - webview.removeEventListener('devtools-focused', listener); - webview.closeDevTools(); - done(); - }; - webview.addEventListener('devtools-focused', listener); - webview.addEventListener('dom-ready', function() { - webview.openDevTools(); - }); - webview.src = "file://" + fixtures + "/pages/base-page.html"; - document.body.appendChild(webview); - }); - }); + describe('devtools-focused event', function () { + it('should fire when webview.openDevTools() is called', function (done) { + var listener = function () { + webview.removeEventListener('devtools-focused', listener) + webview.closeDevTools() + done() + } + webview.addEventListener('devtools-focused', listener) + webview.addEventListener('dom-ready', function () { + webview.openDevTools() + }) + webview.src = 'file://' + fixtures + '/pages/base-page.html' + document.body.appendChild(webview) + }) + }) - describe('.reload()', function() { - it('should emit beforeunload handler', function(done) { - var listener = function(e) { - assert.equal(e.channel, 'onbeforeunload'); - webview.removeEventListener('ipc-message', listener); - done(); - }; - var listener2 = function() { - webview.reload(); - webview.removeEventListener('did-finish-load', listener2); - }; - webview.addEventListener('ipc-message', listener); - webview.addEventListener('did-finish-load', listener2); - webview.setAttribute('nodeintegration', 'on'); - webview.src = "file://" + fixtures + "/pages/beforeunload-false.html"; - document.body.appendChild(webview); - }); - }); + describe('.reload()', function () { + it('should emit beforeunload handler', function (done) { + var listener = function (e) { + assert.equal(e.channel, 'onbeforeunload') + webview.removeEventListener('ipc-message', listener) + done() + } + var listener2 = function () { + webview.reload() + webview.removeEventListener('did-finish-load', listener2) + } + webview.addEventListener('ipc-message', listener) + webview.addEventListener('did-finish-load', listener2) + webview.setAttribute('nodeintegration', 'on') + webview.src = 'file://' + fixtures + '/pages/beforeunload-false.html' + document.body.appendChild(webview) + }) + }) - describe('.clearHistory()', function() { - it('should clear the navigation history', function(done) { - var listener = function(e) { - assert.equal(e.channel, 'history'); - assert.equal(e.args[0], 2); - assert(webview.canGoBack()); - webview.clearHistory(); - assert(!webview.canGoBack()); - webview.removeEventListener('ipc-message', listener); - done(); - }; - webview.addEventListener('ipc-message', listener); - webview.setAttribute('nodeintegration', 'on'); - webview.src = "file://" + fixtures + "/pages/history.html"; - document.body.appendChild(webview); - }); - }); + describe('.clearHistory()', function () { + it('should clear the navigation history', function (done) { + var listener = function (e) { + assert.equal(e.channel, 'history') + assert.equal(e.args[0], 2) + assert(webview.canGoBack()) + webview.clearHistory() + assert(!webview.canGoBack()) + webview.removeEventListener('ipc-message', listener) + done() + } + webview.addEventListener('ipc-message', listener) + webview.setAttribute('nodeintegration', 'on') + webview.src = 'file://' + fixtures + '/pages/history.html' + document.body.appendChild(webview) + }) + }) - describe('basic auth', function() { - var auth = require('basic-auth'); + describe('basic auth', function () { + var auth = require('basic-auth') - it('should authenticate with correct credentials', function(done) { - var message = 'Authenticated'; - var server = http.createServer(function(req, res) { - var credentials = auth(req); + it('should authenticate with correct credentials', function (done) { + var message = 'Authenticated' + var server = http.createServer(function (req, res) { + var credentials = auth(req) if (credentials.name === 'test' && credentials.pass === 'test') { - res.end(message); + res.end(message) } else { - res.end('failed'); + res.end('failed') } - server.close(); - }); - server.listen(0, '127.0.0.1', function() { - var port = server.address().port; - webview.addEventListener('ipc-message', function(e) { - assert.equal(e.channel, message); - done(); - }); - webview.src = "file://" + fixtures + "/pages/basic-auth.html?port=" + port; - webview.setAttribute('nodeintegration', 'on'); - document.body.appendChild(webview); - }); - }); - }); + server.close() + }) + server.listen(0, '127.0.0.1', function () { + var port = server.address().port + webview.addEventListener('ipc-message', function (e) { + assert.equal(e.channel, message) + done() + }) + webview.src = 'file://' + fixtures + '/pages/basic-auth.html?port=' + port + webview.setAttribute('nodeintegration', 'on') + document.body.appendChild(webview) + }) + }) + }) - describe('dom-ready event', function() { - it('emits when document is loaded', function(done) { - var server = http.createServer(function() {}); - server.listen(0, '127.0.0.1', function() { - var port = server.address().port; - webview.addEventListener('dom-ready', function() { - done(); - }); - webview.src = "file://" + fixtures + "/pages/dom-ready.html?port=" + port; - document.body.appendChild(webview); - }); - }); + describe('dom-ready event', function () { + it('emits when document is loaded', function (done) { + var server = http.createServer(function () {}) + server.listen(0, '127.0.0.1', function () { + var port = server.address().port + webview.addEventListener('dom-ready', function () { + done() + }) + webview.src = 'file://' + fixtures + '/pages/dom-ready.html?port=' + port + document.body.appendChild(webview) + }) + }) - it('throws a custom error when an API method is called before the event is emitted', function() { + it('throws a custom error when an API method is called before the event is emitted', function () { assert.throws(function () { - webview.stop(); - }, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.'); - }); - }); + webview.stop() + }, 'Cannot call stop because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.') + }) + }) - describe('executeJavaScript', function() { - it('should support user gesture', function(done) { + describe('executeJavaScript', function () { + it('should support user gesture', function (done) { if (process.env.TRAVIS !== 'true' || process.platform == 'darwin') - return done(); + return done() - var listener = function() { - webview.removeEventListener('enter-html-full-screen', listener); - done(); - }; - var listener2 = function() { - var jsScript = "document.querySelector('video').webkitRequestFullscreen()"; - webview.executeJavaScript(jsScript, true); - webview.removeEventListener('did-finish-load', listener2); - }; - webview.addEventListener('enter-html-full-screen', listener); - webview.addEventListener('did-finish-load', listener2); - webview.src = "file://" + fixtures + "/pages/fullscreen.html"; - document.body.appendChild(webview); - }); + var listener = function () { + webview.removeEventListener('enter-html-full-screen', listener) + done() + } + var listener2 = function () { + var jsScript = "document.querySelector('video').webkitRequestFullscreen()" + webview.executeJavaScript(jsScript, true) + webview.removeEventListener('did-finish-load', listener2) + } + webview.addEventListener('enter-html-full-screen', listener) + webview.addEventListener('did-finish-load', listener2) + webview.src = 'file://' + fixtures + '/pages/fullscreen.html' + document.body.appendChild(webview) + }) - it('can return the result of the executed script', function(done) { + it('can return the result of the executed script', function (done) { if (process.env.TRAVIS === 'true' && process.platform == 'darwin') - return done(); + return done() - var listener = function() { - var jsScript = "'4'+2"; - webview.executeJavaScript(jsScript, false, function(result) { - assert.equal(result, '42'); - done(); - }); - webview.removeEventListener('did-finish-load', listener); - }; - webview.addEventListener('did-finish-load', listener); - webview.src = "about:blank"; - document.body.appendChild(webview); - }); - }); + var listener = function () { + var jsScript = "'4'+2" + webview.executeJavaScript(jsScript, false, function (result) { + assert.equal(result, '42') + done() + }) + webview.removeEventListener('did-finish-load', listener) + } + webview.addEventListener('did-finish-load', listener) + webview.src = 'about:blank' + document.body.appendChild(webview) + }) + }) - describe('sendInputEvent', function() { - it('can send keyboard event', function(done) { - webview.addEventListener('ipc-message', function(e) { - assert.equal(e.channel, 'keyup'); - assert.deepEqual(e.args, [67, true, false]); - done(); - }); - webview.addEventListener('dom-ready', function() { + describe('sendInputEvent', function () { + it('can send keyboard event', function (done) { + webview.addEventListener('ipc-message', function (e) { + assert.equal(e.channel, 'keyup') + assert.deepEqual(e.args, [67, true, false]) + done() + }) + webview.addEventListener('dom-ready', function () { webview.sendInputEvent({ type: 'keyup', keyCode: 'c', modifiers: ['shift'] - }); - }); - webview.src = "file://" + fixtures + "/pages/onkeyup.html"; - webview.setAttribute('nodeintegration', 'on'); - document.body.appendChild(webview); - }); + }) + }) + webview.src = 'file://' + fixtures + '/pages/onkeyup.html' + webview.setAttribute('nodeintegration', 'on') + document.body.appendChild(webview) + }) - it('can send mouse event', function(done) { - webview.addEventListener('ipc-message', function(e) { - assert.equal(e.channel, 'mouseup'); - assert.deepEqual(e.args, [10, 20, false, true]); - done(); - }); - webview.addEventListener('dom-ready', function() { + it('can send mouse event', function (done) { + webview.addEventListener('ipc-message', function (e) { + assert.equal(e.channel, 'mouseup') + assert.deepEqual(e.args, [10, 20, false, true]) + done() + }) + webview.addEventListener('dom-ready', function () { webview.sendInputEvent({ type: 'mouseup', modifiers: ['ctrl'], x: 10, y: 20 - }); - }); - webview.src = "file://" + fixtures + "/pages/onmouseup.html"; - webview.setAttribute('nodeintegration', 'on'); - document.body.appendChild(webview); - }); - }); + }) + }) + webview.src = 'file://' + fixtures + '/pages/onmouseup.html' + webview.setAttribute('nodeintegration', 'on') + document.body.appendChild(webview) + }) + }) - describe('media-started-playing media-paused events', function() { - it('emits when audio starts and stops playing', function(done) { - var audioPlayed = false; - webview.addEventListener('media-started-playing', function() { - audioPlayed = true; - }); - webview.addEventListener('media-paused', function() { - assert(audioPlayed); - done(); - }); - webview.src = "file://" + fixtures + "/pages/audio.html"; - document.body.appendChild(webview); - }); - }); + describe('media-started-playing media-paused events', function () { + it('emits when audio starts and stops playing', function (done) { + var audioPlayed = false + webview.addEventListener('media-started-playing', function () { + audioPlayed = true + }) + webview.addEventListener('media-paused', function () { + assert(audioPlayed) + done() + }) + webview.src = 'file://' + fixtures + '/pages/audio.html' + document.body.appendChild(webview) + }) + }) - describe('found-in-page event', function() { - it('emits when a request is made', function(done) { - var requestId = null; - var totalMatches = null; - var activeMatchOrdinal = []; - var listener = function(e) { - assert.equal(e.result.requestId, requestId); + describe('found-in-page event', function () { + it('emits when a request is made', function (done) { + var requestId = null + var totalMatches = null + var activeMatchOrdinal = [] + var listener = function (e) { + assert.equal(e.result.requestId, requestId) if (e.result.finalUpdate) { - assert.equal(e.result.matches, 3); - totalMatches = e.result.matches; - listener2(); + assert.equal(e.result.matches, 3) + totalMatches = e.result.matches + listener2() } else { - activeMatchOrdinal.push(e.result.activeMatchOrdinal); + activeMatchOrdinal.push(e.result.activeMatchOrdinal) if (e.result.activeMatchOrdinal == totalMatches) { - assert.deepEqual(activeMatchOrdinal, [1, 2, 3]); - webview.stopFindInPage("clearSelection"); - done(); + assert.deepEqual(activeMatchOrdinal, [1, 2, 3]) + webview.stopFindInPage('clearSelection') + done() } } - }; - var listener2 = function() { - requestId = webview.findInPage("virtual"); - }; - webview.addEventListener('found-in-page', listener); - webview.addEventListener('did-finish-load', listener2); - webview.src = "file://" + fixtures + "/pages/content.html"; - document.body.appendChild(webview); - }); - }); + } + var listener2 = function () { + requestId = webview.findInPage('virtual') + } + webview.addEventListener('found-in-page', listener) + webview.addEventListener('did-finish-load', listener2) + webview.src = 'file://' + fixtures + '/pages/content.html' + document.body.appendChild(webview) + }) + }) - xdescribe('did-change-theme-color event', function() { - it('emits when theme color changes', function(done) { - webview.addEventListener('did-change-theme-color', function() { - done(); - }); - webview.src = "file://" + fixtures + "/pages/theme-color.html"; - document.body.appendChild(webview); - }); - }); + xdescribe('did-change-theme-color event', function () { + it('emits when theme color changes', function (done) { + webview.addEventListener('did-change-theme-color', function () { + done() + }) + webview.src = 'file://' + fixtures + '/pages/theme-color.html' + document.body.appendChild(webview) + }) + }) - describe('permission-request event', function() { - function setUpRequestHandler(webview, requested_permission) { - const session = require('electron').remote.session; - var listener = function(webContents, permission, callback) { - if (webContents.getId() === webview.getId() ) { - assert.equal(permission, requested_permission); - callback(false); + describe('permission-request event', function () { + function setUpRequestHandler (webview, requested_permission) { + const session = require('electron').remote.session + var listener = function (webContents, permission, callback) { + if (webContents.getId() === webview.getId()) { + assert.equal(permission, requested_permission) + callback(false) } - }; - session.fromPartition(webview.partition).setPermissionRequestHandler(listener); + } + session.fromPartition(webview.partition).setPermissionRequestHandler(listener) } - it('emits when using navigator.getUserMedia api', function(done) { - webview.addEventListener('ipc-message', function(e) { - assert(e.channel, 'message'); - assert(e.args, ['PermissionDeniedError']); - done(); - }); - webview.src = "file://" + fixtures + "/pages/permissions/media.html"; - webview.partition = "permissionTest"; - webview.setAttribute('nodeintegration', 'on'); - setUpRequestHandler(webview, "media"); - document.body.appendChild(webview); - }); + it('emits when using navigator.getUserMedia api', function (done) { + webview.addEventListener('ipc-message', function (e) { + assert(e.channel, 'message') + assert(e.args, ['PermissionDeniedError']) + done() + }) + webview.src = 'file://' + fixtures + '/pages/permissions/media.html' + webview.partition = 'permissionTest' + webview.setAttribute('nodeintegration', 'on') + setUpRequestHandler(webview, 'media') + document.body.appendChild(webview) + }) - it('emits when using navigator.geolocation api', function(done) { - webview.addEventListener('ipc-message', function(e) { - assert(e.channel, 'message'); - assert(e.args, ['ERROR(1): User denied Geolocation']); - done(); - }); - webview.src = "file://" + fixtures + "/pages/permissions/geolocation.html"; - webview.partition = "permissionTest"; - webview.setAttribute('nodeintegration', 'on'); - setUpRequestHandler(webview, "geolocation"); - document.body.appendChild(webview); - }); + it('emits when using navigator.geolocation api', function (done) { + webview.addEventListener('ipc-message', function (e) { + assert(e.channel, 'message') + assert(e.args, ['ERROR(1): User denied Geolocation']) + done() + }) + webview.src = 'file://' + fixtures + '/pages/permissions/geolocation.html' + webview.partition = 'permissionTest' + webview.setAttribute('nodeintegration', 'on') + setUpRequestHandler(webview, 'geolocation') + document.body.appendChild(webview) + }) - it('emits when using navigator.requestMIDIAccess api', function(done) { - webview.addEventListener('ipc-message', function(e) { - assert(e.channel, 'message'); - assert(e.args, ['SecurityError']); - done(); - }); - webview.src = "file://" + fixtures + "/pages/permissions/midi.html"; - webview.partition = "permissionTest"; - webview.setAttribute('nodeintegration', 'on'); - setUpRequestHandler(webview, "midiSysex"); - document.body.appendChild(webview); - }); - }); + it('emits when using navigator.requestMIDIAccess api', function (done) { + webview.addEventListener('ipc-message', function (e) { + assert(e.channel, 'message') + assert(e.args, ['SecurityError']) + done() + }) + webview.src = 'file://' + fixtures + '/pages/permissions/midi.html' + webview.partition = 'permissionTest' + webview.setAttribute('nodeintegration', 'on') + setUpRequestHandler(webview, 'midiSysex') + document.body.appendChild(webview) + }) + }) - describe('.getWebContents', function() { - it('can return the webcontents associated', function(done) { - webview.addEventListener('did-finish-load', function() { - const webviewContents = webview.getWebContents(); - assert(webviewContents); - assert.equal(webviewContents.getURL(), 'about:blank'); - done(); - }); - webview.src = "about:blank"; - document.body.appendChild(webview); - }); - }); -}); + describe('.getWebContents', function () { + it('can return the webcontents associated', function (done) { + webview.addEventListener('did-finish-load', function () { + const webviewContents = webview.getWebContents() + assert(webviewContents) + assert.equal(webviewContents.getURL(), 'about:blank') + done() + }) + webview.src = 'about:blank' + document.body.appendChild(webview) + }) + }) +}) diff --git a/tools/dump-version-info.js b/tools/dump-version-info.js index e76f09ba2f9..b4b44fe61aa 100644 --- a/tools/dump-version-info.js +++ b/tools/dump-version-info.js @@ -1,31 +1,31 @@ -var app = require('app'); -var fs = require('fs'); -var path = require('path'); -var request = require('request'); +var app = require('app') +var fs = require('fs') +var path = require('path') +var request = require('request') -var TARGET_URL = 'https://atom.io/download/atom-shell/index.json'; +var TARGET_URL = 'https://atom.io/download/atom-shell/index.json' -function getDate() { - var today = new Date(); - var year = today.getFullYear(); - var month = today.getMonth() + 1; +function getDate () { + var today = new Date() + var year = today.getFullYear() + var month = today.getMonth() + 1 if (month <= 9) - month = '0' + month; - var day= today.getDate(); + month = '0' + month + var day = today.getDate() if (day <= 9) - day = '0' + day; - return year + '-' + month + '-' + day; + day = '0' + day + return year + '-' + month + '-' + day } -function getInfoForCurrentVersion() { - var json = {}; - json.version = process.versions['atom-shell']; - json.date = getDate(); +function getInfoForCurrentVersion () { + var json = {} + json.version = process.versions['atom-shell'] + json.date = getDate() var names = ['node', 'v8', 'uv', 'zlib', 'openssl', 'modules', 'chrome'] for (var i in names) { - var name = names[i]; - json[name] = process.versions[name]; + var name = names[i] + json[name] = process.versions[name] } json.files = [ @@ -39,44 +39,44 @@ function getInfoForCurrentVersion() { 'win32-ia32-symbols', 'win32-x64', 'win32-x64-symbols', - ]; + ] - return json; + return json } -function getIndexJsInServer(callback) { - request(TARGET_URL, function(e, res, body) { +function getIndexJsInServer (callback) { + request(TARGET_URL, function (e, res, body) { if (e) - callback(e); + callback(e) else if (res.statusCode != 200) - callback(new Error('Server returned ' + res.statusCode)); + callback(new Error('Server returned ' + res.statusCode)) else - callback(null, JSON.parse(body)); - }); + callback(null, JSON.parse(body)) + }) } -function findObjectByVersion(all, version) { +function findObjectByVersion (all, version) { for (var i in all) if (all[i].version == version) - return i; - return -1; + return i + return -1 } -app.on('ready', function() { - getIndexJsInServer(function(e, all) { +app.on('ready', function () { + getIndexJsInServer(function (e, all) { if (e) { - console.error(e); - process.exit(1); + console.error(e) + process.exit(1) } - var current = getInfoForCurrentVersion(); - var found = findObjectByVersion(all, current.version); + var current = getInfoForCurrentVersion() + var found = findObjectByVersion(all, current.version) if (found == -1) - all.unshift(current); + all.unshift(current) else - all[found] = current; + all[found] = current - fs.writeFileSync(process.argv[2], JSON.stringify(all)); - process.exit(0); - }); -}); + fs.writeFileSync(process.argv[2], JSON.stringify(all)) + process.exit(0) + }) +}) diff --git a/tools/win/register_msdia80_dll.js b/tools/win/register_msdia80_dll.js index 5691ef9caf5..e90b9714d1f 100644 --- a/tools/win/register_msdia80_dll.js +++ b/tools/win/register_msdia80_dll.js @@ -1,12 +1,12 @@ -var fs = require('fs'); -var path = require('path'); -var runas = require('runas'); +var fs = require('fs') +var path = require('path') +var runas = require('runas') -var source = path.resolve(__dirname, '..', '..', 'vendor', 'breakpad', 'msdia80.dll'); -var target = 'C:\\Program Files\\Common Files\\Microsoft Shared\\VC\\msdia80.dll'; -if (fs.existsSync(target)) - return; +var source = path.resolve(__dirname, '..', '..', 'vendor', 'breakpad', 'msdia80.dll') +var target = 'C:\\Program Files\\Common Files\\Microsoft Shared\\VC\\msdia80.dll' -runas('cmd', - ['/K', 'copy', source, target, '&', 'regsvr32', '/s', target, '&', 'exit'], - {admin: true}); +if (!fs.existsSync(target)) { + runas('cmd', + ['/K', 'copy', source, target, '&', 'regsvr32', '/s', target, '&', 'exit'], + {admin: true}) +} From 7404b848a2141ace3a863b5640ac72f232efc452 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 25 Mar 2016 13:11:05 -0700 Subject: [PATCH 608/688] tell standard to ignore /vendor directory --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 9f22ef2ae07..42815e3a3d6 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "standard": { "ignore": [ "/lib/browser/rpc-server.js", - "/lib/common/asar.js" + "/lib/common/asar.js", + "/vendor" ] }, "private": true, From 2fb92076b615e90d43e931f32652d5f7b665494b Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 25 Mar 2016 13:16:56 -0700 Subject: [PATCH 609/688] standard-format has done its work; on to snazzy --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 42815e3a3d6..10683e0f997 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "asar": "^0.10.0", "eslint": "^2.1.0", "request": "*", - "standard-format": "^2.1.1" + "snazzy": "^3.0.0" }, "optionalDependencies": { "runas": "^3.0.0" From 67d189474c49ea0f700d902491b864105245a157 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Sun, 27 Mar 2016 10:38:32 -0700 Subject: [PATCH 610/688] autoformat more files --- default_app/default_app.js | 2 +- default_app/main.js | 31 +++++++++++++++---------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/default_app/default_app.js b/default_app/default_app.js index c2d95158cd0..eda1300f007 100644 --- a/default_app/default_app.js +++ b/default_app/default_app.js @@ -15,7 +15,7 @@ exports.load = function (appUrl) { width: 800, height: 600, autoHideMenuBar: true, - useContentSize: true, + useContentSize: true }) mainWindow.loadURL(appUrl) mainWindow.focus() diff --git a/default_app/main.js b/default_app/main.js index 49ad78f60ba..e4cdb8c8d54 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -13,23 +13,23 @@ const url = require('url') var argv = process.argv.slice(1) var option = { file: null, help: null, version: null, webdriver: null, modules: [] } for (var i = 0; i < argv.length; i++) { - if (argv[i] == '--version' || argv[i] == '-v') { + if (argv[i] === '--version' || argv[i] === '-v') { option.version = true break } else if (argv[i].match(/^--app=/)) { option.file = argv[i].split('=')[1] break - } else if (argv[i] == '--help' || argv[i] == '-h') { + } else if (argv[i] === '--help' || argv[i] === '-h') { option.help = true break - } else if (argv[i] == '--interactive' || argv[i] == '-i') { + } else if (argv[i] === '--interactive' || argv[i] === '-i') { option.interactive = true - } else if (argv[i] == '--test-type=webdriver') { + } else if (argv[i] === '--test-type=webdriver') { option.webdriver = true - } else if (argv[i] == '--require' || argv[i] == '-r') { + } else if (argv[i] === '--require' || argv[i] === '-r') { option.modules.push(argv[++i]) continue - } else if (argv[i][0] == '-') { + } else if (argv[i][0] === '-') { continue } else { option.file = argv[i] @@ -39,14 +39,14 @@ for (var i = 0; i < argv.length; i++) { // Quit when all windows are closed and no other one is listening to this. app.on('window-all-closed', function () { - if (app.listeners('window-all-closed').length == 1 && !option.interactive) + if (app.listeners('window-all-closed').length === 1 && !option.interactive) { app.quit() + } }) // Create default menu. app.once('ready', function () { - if (Menu.getApplicationMenu()) - return + if (Menu.getApplicationMenu()) return var template = [ { @@ -84,7 +84,7 @@ app.once('ready', function () { label: 'Select All', accelerator: 'CmdOrCtrl+A', role: 'selectall' - }, + } ] }, { @@ -94,14 +94,13 @@ app.once('ready', function () { label: 'Reload', accelerator: 'CmdOrCtrl+R', click: function (item, focusedWindow) { - if (focusedWindow) - focusedWindow.reload() + if (focusedWindow) focusedWindow.reload() } }, { label: 'Toggle Full Screen', accelerator: (function () { - if (process.platform == 'darwin') + if (process.platform === 'darwin') return 'Ctrl+Command+F' else return 'F11' @@ -114,7 +113,7 @@ app.once('ready', function () { { label: 'Toggle Developer Tools', accelerator: (function () { - if (process.platform == 'darwin') + if (process.platform === 'darwin') return 'Alt+Command+I' else return 'Ctrl+Shift+I' @@ -176,7 +175,7 @@ app.once('ready', function () { }, ] - if (process.platform == 'darwin') { + if (process.platform === 'darwin') { template.unshift({ label: 'Electron', submenu: [ @@ -259,7 +258,7 @@ function loadApplicationPackage (packagePath) { // Run the app. require('module')._load(packagePath, module, true) } catch(e) { - if (e.code == 'MODULE_NOT_FOUND') { + if (e.code === 'MODULE_NOT_FOUND') { app.focus() dialog.showErrorBox( 'Error opening app', From 09635ae50eb5dafb398c194ed6a16655c3ee2da0 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 13:09:03 -0700 Subject: [PATCH 611/688] reduce ignore list in favor of one-liner ignores --- lib/browser/rpc-server.js | 4 ++-- package.json | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/browser/rpc-server.js b/lib/browser/rpc-server.js index 79a52b13262..eb1d0385fa1 100644 --- a/lib/browser/rpc-server.js +++ b/lib/browser/rpc-server.js @@ -281,7 +281,7 @@ ipcMain.on('ATOM_BROWSER_CONSTRUCTOR', function (event, id, args) { // Call new with array of arguments. // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible - let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))) + let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))) // eslint-disable-line event.returnValue = valueToMeta(event.sender, obj) } catch (error) { event.returnValue = exceptionToMeta(error) @@ -304,7 +304,7 @@ ipcMain.on('ATOM_BROWSER_MEMBER_CONSTRUCTOR', function (event, id, method, args) let constructor = objectsRegistry.get(id)[method] // Call new with array of arguments. - let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))) + let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))) // eslint-disable-line event.returnValue = valueToMeta(event.sender, obj) } catch (error) { event.returnValue = exceptionToMeta(error) diff --git a/package.json b/package.json index 10683e0f997..46584638dfb 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,7 @@ "runas": "^3.0.0" }, "standard": { - "ignore": [ - "/lib/browser/rpc-server.js", - "/lib/common/asar.js", - "/vendor" - ] + "ignore": ["/vendor"], }, "private": true, "scripts": { From 3a55f0d1f709680f67e35e22657349ee98f79ce7 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 13:09:18 -0700 Subject: [PATCH 612/688] set standard.globals --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 46584638dfb..855d5155504 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ }, "standard": { "ignore": ["/vendor"], + "globals": ["afterEach", "beforeEach", "describe", "it", "location"] }, "private": true, "scripts": { From 68510cbe49b357adbee61205e182af41c8fb6aa5 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 13:19:41 -0700 Subject: [PATCH 613/688] standardize more --- default_app/main.js | 36 +++++++++++++++--------------------- tools/dump-version-info.js | 16 +++++++--------- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/default_app/main.js b/default_app/main.js index e4cdb8c8d54..dcbe2ca0c65 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -100,29 +100,21 @@ app.once('ready', function () { { label: 'Toggle Full Screen', accelerator: (function () { - if (process.platform === 'darwin') - return 'Ctrl+Command+F' - else - return 'F11' + return (process.platform === 'darwin') ? 'Ctrl+Command+F' : 'F11' })(), click: function (item, focusedWindow) { - if (focusedWindow) - focusedWindow.setFullScreen(!focusedWindow.isFullScreen()) + if (focusedWindow) focusedWindow.setFullScreen(!focusedWindow.isFullScreen()) } }, { label: 'Toggle Developer Tools', accelerator: (function () { - if (process.platform === 'darwin') - return 'Alt+Command+I' - else - return 'Ctrl+Shift+I' + return (process.platform === 'darwin') ? 'Alt+Command+I' : 'Ctrl+Shift+I' })(), click: function (item, focusedWindow) { - if (focusedWindow) - focusedWindow.toggleDevTools() + if (focusedWindow) focusedWindow.toggleDevTools() } - }, + } ] }, { @@ -138,7 +130,7 @@ app.once('ready', function () { label: 'Close', accelerator: 'CmdOrCtrl+W', role: 'close' - }, + } ] }, { @@ -172,7 +164,7 @@ app.once('ready', function () { } } ] - }, + } ] if (process.platform === 'darwin') { @@ -214,8 +206,8 @@ app.once('ready', function () { { label: 'Quit', accelerator: 'Command+Q', - click: function () { app.quit(); } - }, + click: function () { app.quit() } + } ] }) template[3].submenu.push( @@ -244,12 +236,14 @@ function loadApplicationPackage (packagePath) { var packageJsonPath = path.join(packagePath, 'package.json') if (fs.existsSync(packageJsonPath)) { var packageJson = JSON.parse(fs.readFileSync(packageJsonPath)) - if (packageJson.version) - app.setVersion(packageJson.version) - if (packageJson.productName) + if (packageJson.version) app.setVersion(packageJson.version) + + if (packageJson.productName) { app.setName(packageJson.productName) - else if (packageJson.name) + } else if (packageJson.name) { app.setName(packageJson.name) + } + app.setPath('userData', path.join(app.getPath('appData'), app.getName())) app.setPath('userCache', path.join(app.getPath('cache'), app.getName())) app.setAppPath(packagePath) diff --git a/tools/dump-version-info.js b/tools/dump-version-info.js index b4b44fe61aa..1abe2ac1398 100644 --- a/tools/dump-version-info.js +++ b/tools/dump-version-info.js @@ -1,6 +1,5 @@ var app = require('app') var fs = require('fs') -var path = require('path') var request = require('request') var TARGET_URL = 'https://atom.io/download/atom-shell/index.json' @@ -9,11 +8,9 @@ function getDate () { var today = new Date() var year = today.getFullYear() var month = today.getMonth() + 1 - if (month <= 9) - month = '0' + month + if (month <= 9) month = '0' + month var day = today.getDate() - if (day <= 9) - day = '0' + day + if (day <= 9) day = '0' + day return year + '-' + month + '-' + day } @@ -38,7 +35,7 @@ function getInfoForCurrentVersion () { 'win32-ia32', 'win32-ia32-symbols', 'win32-x64', - 'win32-x64-symbols', + 'win32-x64-symbols' ] return json @@ -46,12 +43,13 @@ function getInfoForCurrentVersion () { function getIndexJsInServer (callback) { request(TARGET_URL, function (e, res, body) { - if (e) + if (e) { callback(e) - else if (res.statusCode != 200) + } else if (res.statusCode != 200) { callback(new Error('Server returned ' + res.statusCode)) - else + } else { callback(null, JSON.parse(body)) + } }) } From f47fa25e3914cd80a994b012d55e099ab8b1ec0c Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 13:47:31 -0700 Subject: [PATCH 614/688] tiptoe --- spec/webview-spec.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 1bb18c0b5e7..4fdba97249a 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -1,3 +1,5 @@ +/* globals btoa, WebView, xdescribe */ + const assert = require('assert') const path = require('path') const http = require('http') @@ -10,7 +12,7 @@ describe(' tag', function () { var webview = null beforeEach(function () { - webview = new WebView + webview = new WebView() }) afterEach(function () { @@ -168,7 +170,8 @@ describe(' tag', function () { describe('disablewebsecurity attribute', function () { it('does not disable web security when not set', function (done) { - var src = " " + var jqueryPath = path.join(__dirname, '/static/jquery-2.0.3.min.js') + var src = ` ` var encoded = btoa(unescape(encodeURIComponent(src))) var listener = function (e) { assert(/Not allowed to load local resource/.test(e.message)) @@ -181,7 +184,8 @@ describe(' tag', function () { }) it('disables web security when set', function (done) { - var src = " " + var jqueryPath = path.join(__dirname, '/static/jquery-2.0.3.min.js') + var src = ` ` var encoded = btoa(unescape(encodeURIComponent(src))) var listener = function (e) { assert.equal(e.message, 'ok') @@ -549,8 +553,7 @@ describe(' tag', function () { describe('executeJavaScript', function () { it('should support user gesture', function (done) { - if (process.env.TRAVIS !== 'true' || process.platform == 'darwin') - return done() + if (process.env.TRAVIS !== 'true' || process.platform === 'darwin') return done() var listener = function () { webview.removeEventListener('enter-html-full-screen', listener) @@ -568,8 +571,7 @@ describe(' tag', function () { }) it('can return the result of the executed script', function (done) { - if (process.env.TRAVIS === 'true' && process.platform == 'darwin') - return done() + if (process.env.TRAVIS === 'true' && process.platform === 'darwin') return done() var listener = function () { var jsScript = "'4'+2" @@ -652,7 +654,7 @@ describe(' tag', function () { listener2() } else { activeMatchOrdinal.push(e.result.activeMatchOrdinal) - if (e.result.activeMatchOrdinal == totalMatches) { + if (e.result.activeMatchOrdinal === totalMatches) { assert.deepEqual(activeMatchOrdinal, [1, 2, 3]) webview.stopFindInPage('clearSelection') done() From c4b6cf4a8eacfa89c609910e7967d773be593d8d Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 14:00:41 -0700 Subject: [PATCH 615/688] do more manual cleanup and specify globals --- lib/common/asar.js | 2 ++ lib/renderer/inspector.js | 2 ++ package.json | 3 ++- spec/api-web-request-spec.js | 2 ++ spec/fixtures/module/fork_ping.js | 4 +++- spec/fixtures/module/function.js | 2 +- spec/fixtures/module/locale-compare.js | 2 +- spec/fixtures/pages/service-worker/service-worker.js | 2 ++ spec/node-spec.js | 2 ++ spec/static/main.js | 8 ++++---- 10 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/common/asar.js b/lib/common/asar.js index 26241281322..dbf56705025 100644 --- a/lib/common/asar.js +++ b/lib/common/asar.js @@ -1,3 +1,5 @@ +/* globals $, xit */ + (function () { const asar = process.binding('atom_common_asar') const child_process = require('child_process') diff --git a/lib/renderer/inspector.js b/lib/renderer/inspector.js index 61be586f788..2b0fcbc80c1 100644 --- a/lib/renderer/inspector.js +++ b/lib/renderer/inspector.js @@ -1,3 +1,5 @@ +/* globals InspectorFrontendHost, WebInspector, DevToolsAPI, DevToolsAPI, Blob */ + window.onload = function () { // Use menu API to show context menu. InspectorFrontendHost.showContextMenuAtPoint = createMenu diff --git a/package.json b/package.json index 855d5155504..2d5c61f494f 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ }, "standard": { "ignore": ["/vendor"], - "globals": ["afterEach", "beforeEach", "describe", "it", "location"] + "globals": ["$", "after", "afterEach", "before", + "beforeEach", "describe", "it", "location"] }, "private": true, "scripts": { diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index abc4f9568cd..8ce4bca8db1 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -1,3 +1,5 @@ +/* globals $ */ + const assert = require('assert') const http = require('http') const qs = require('querystring') diff --git a/spec/fixtures/module/fork_ping.js b/spec/fixtures/module/fork_ping.js index 76bf1b0e368..aa515333400 100644 --- a/spec/fixtures/module/fork_ping.js +++ b/spec/fixtures/module/fork_ping.js @@ -1,8 +1,10 @@ +const path = require('path') + process.on('uncaughtException', function (error) { process.send(error.stack) }) -var child = require('child_process').fork(__dirname + '/ping.js') +var child = require('child_process').fork(path.join(__dirname, '/ping.js')) process.on('message', function (msg) { child.send(msg) }) diff --git a/spec/fixtures/module/function.js b/spec/fixtures/module/function.js index 526daf76fa8..8a2bb6c421e 100644 --- a/spec/fixtures/module/function.js +++ b/spec/fixtures/module/function.js @@ -1 +1 @@ -exports.aFunction = function () { return 1127; } +exports.aFunction = function () { return 1127 } diff --git a/spec/fixtures/module/locale-compare.js b/spec/fixtures/module/locale-compare.js index 3446e2f443d..40275400443 100644 --- a/spec/fixtures/module/locale-compare.js +++ b/spec/fixtures/module/locale-compare.js @@ -2,6 +2,6 @@ process.on('message', function () { process.send([ 'a'.localeCompare('a'), 'ä'.localeCompare('z', 'de'), - 'ä'.localeCompare('a', 'sv', { sensitivity: 'base' }), + 'ä'.localeCompare('a', 'sv', { sensitivity: 'base' }) ]) }) diff --git a/spec/fixtures/pages/service-worker/service-worker.js b/spec/fixtures/pages/service-worker/service-worker.js index 7d80f45e2df..be5ecefd570 100644 --- a/spec/fixtures/pages/service-worker/service-worker.js +++ b/spec/fixtures/pages/service-worker/service-worker.js @@ -1,3 +1,5 @@ +/* globals self, URL, Response */ + self.addEventListener('fetch', function (event) { var requestUrl = new URL(event.request.url) diff --git a/spec/node-spec.js b/spec/node-spec.js index 286c4d6f916..68b328b2ab9 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -1,3 +1,5 @@ +/* globals xit */ + const assert = require('assert') const child_process = require('child_process') const fs = require('fs') diff --git a/spec/static/main.js b/spec/static/main.js index f1d2a5eafa6..d48285a5191 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -17,7 +17,7 @@ var argv = require('yargs') .argv var window = null -process.port = 0; // will be used by crash-reporter spec. +process.port = 0 // will be used by crash-reporter spec. app.commandLine.appendSwitch('js-flags', '--expose_gc') app.commandLine.appendSwitch('ignore-certificate-errors') @@ -48,7 +48,7 @@ ipcMain.on('process.exit', function (event, code) { }) ipcMain.on('eval', function (event, script) { - event.returnValue = eval(script) + event.returnValue = eval(script) // eslint-disable-line }) ipcMain.on('echo', function (event, msg) { @@ -84,10 +84,10 @@ app.on('ready', function () { height: 600, webPreferences: { javascript: true // Test whether web preferences crashes. - }, + } }) window.loadURL(url.format({ - pathname: __dirname + '/index.html', + pathname: path.join(__dirname, '/index.html'), protocol: 'file', query: { grep: argv.grep, From 9db733a4ffd0a6ada67b95232ae64aead1370550 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 16:11:00 -0700 Subject: [PATCH 616/688] mostly more globals --- spec/api-web-frame-spec.js | 2 ++ spec/asar-spec.js | 30 +++++++++++++++++------------- spec/chromium-spec.js | 13 ++++++++----- spec/fixtures/module/class.js | 4 ++-- spec/static/main.js | 5 ++--- tools/dump-version-info.js | 14 +++++++------- 6 files changed, 38 insertions(+), 30 deletions(-) diff --git a/spec/api-web-frame-spec.js b/spec/api-web-frame-spec.js index 519966c8cea..83fb4a560c5 100644 --- a/spec/api-web-frame-spec.js +++ b/spec/api-web-frame-spec.js @@ -1,3 +1,5 @@ +/* globals fetch */ + const assert = require('assert') const path = require('path') const webFrame = require('electron').webFrame diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 050d8d7deda..de235eb66ed 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -1,3 +1,5 @@ +/* globals xit */ + const assert = require('assert') const child_process = require('child_process') const fs = require('fs') @@ -560,7 +562,9 @@ describe('asar package', function () { if (process.platform !== 'darwin') { return } - ref2 = require('child_process'), execFile = ref2.execFile, execFileSync = ref2.execFileSync + ref2 = require('child_process') + execFile = ref2.execFile + execFileSync = ref2.execFileSync echo = path.join(fixtures, 'asar', 'echo.asar', 'echo') it('executes binaries', function (done) { @@ -609,18 +613,18 @@ describe('asar package', function () { it('disables asar support in sync API', function () { var file = path.join(fixtures, 'asar', 'a.asar', 'file1') var dir = path.join(fixtures, 'asar', 'a.asar', 'dir1') - assert.throws((function () { + assert.throws(function () { fs.readFileSync(file) - }), new RegExp(errorName)) - assert.throws((function () { + }, new RegExp(errorName)) + assert.throws(function () { fs.lstatSync(file) - }), new RegExp(errorName)) - assert.throws((function () { + }, new RegExp(errorName)) + assert.throws(function () { fs.realpathSync(file) - }), new RegExp(errorName)) - assert.throws((function () { + }, new RegExp(errorName)) + assert.throws(function () { fs.readdirSync(dir) - }), new RegExp(errorName)) + }, new RegExp(errorName)) }) it('disables asar support in async API', function (done) { @@ -647,9 +651,9 @@ describe('asar package', function () { var content1 = fs.readFileSync(asar) var content2 = originalFs.readFileSync(asar) assert.equal(content1.compare(content2), 0) - assert.throws((function () { + assert.throws(function () { fs.readdirSync(asar) - }), /ENOTDIR/) + }, /ENOTDIR/) }) }) }) @@ -785,9 +789,9 @@ describe('asar package', function () { it('throws error when calling inside asar archive', function () { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') - assert.throws((function () { + assert.throws(function () { mkdirp.sync(p) - }), new RegExp('ENOTDIR')) + }, new RegExp('ENOTDIR')) }) }) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 40e46dcb5ea..244f9f77a1e 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -1,3 +1,5 @@ +/* globals xdescribe, Worker, SharedWorker, WebSocket, HTMLElement */ + const assert = require('assert') const http = require('http') const path = require('path') @@ -295,15 +297,15 @@ describe('chromium feature', function () { describe('creating a Uint8Array under browser side', function () { it('does not crash', function () { var RUint8Array = remote.getGlobal('Uint8Array') - new RUint8Array + var arr = new RUint8Array() + assert(arr) }) }) describe('webgl', function () { it('can be get as context in canvas', function () { - if (process.platform === 'linux') { - return - } + if (process.platform === 'linux') return + var webgl = document.createElement('canvas').getContext('webgl') assert.notEqual(webgl, null) }) @@ -387,7 +389,8 @@ describe('chromium feature', function () { done('user agent is empty') } }) - new WebSocket('ws://127.0.0.1:' + port) + var socket = new WebSocket(`ws://127.0.0.1: ${port}`) + assert(socket) }) }) }) diff --git a/spec/fixtures/module/class.js b/spec/fixtures/module/class.js index c961dd8040c..9b971e52335 100644 --- a/spec/fixtures/module/class.js +++ b/spec/fixtures/module/class.js @@ -24,6 +24,6 @@ class DerivedClass extends BaseClass { } module.exports = { - base: new BaseClass, - derived: new DerivedClass, + base: new BaseClass(), + derived: new DerivedClass() } diff --git a/spec/static/main.js b/spec/static/main.js index d48285a5191..2707f6a686d 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -116,7 +116,7 @@ app.on('ready', function () { setImmediate(function () { try { item.getURL() - } catch(err) { + } catch (err) { window.webContents.send('download-error', url, filename, err.message) } }) @@ -132,8 +132,7 @@ app.on('ready', function () { item.getContentDisposition(), item.getFilename()) }) - if (need_cancel) - item.cancel() + if (need_cancel) item.cancel() } }) event.returnValue = 'done' diff --git a/tools/dump-version-info.js b/tools/dump-version-info.js index 1abe2ac1398..b5df69f4e9b 100644 --- a/tools/dump-version-info.js +++ b/tools/dump-version-info.js @@ -45,7 +45,7 @@ function getIndexJsInServer (callback) { request(TARGET_URL, function (e, res, body) { if (e) { callback(e) - } else if (res.statusCode != 200) { + } else if (res.statusCode !== 200) { callback(new Error('Server returned ' + res.statusCode)) } else { callback(null, JSON.parse(body)) @@ -54,9 +54,9 @@ function getIndexJsInServer (callback) { } function findObjectByVersion (all, version) { - for (var i in all) - if (all[i].version == version) - return i + for (var i in all) { + if (all[i].version === version) return i + } return -1 } @@ -69,11 +69,11 @@ app.on('ready', function () { var current = getInfoForCurrentVersion() var found = findObjectByVersion(all, current.version) - if (found == -1) + if (found === -1) { all.unshift(current) - else + } else { all[found] = current - + } fs.writeFileSync(process.argv[2], JSON.stringify(all)) process.exit(0) }) From 5e4696f4a7240106efdca6df28cdc8325745c608 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 16:19:18 -0700 Subject: [PATCH 617/688] standardize more --- spec/api-debugger-spec.js | 14 +++++++------- spec/api-native-image-spec.js | 2 +- spec/api-protocol-spec.js | 6 +++--- spec/api-session-spec.js | 4 +++- spec/asar-spec.js | 6 +++--- spec/chromium-spec.js | 10 ++++++---- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index 1648ac1c3cd..fdad013b8cf 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -30,7 +30,7 @@ describe('debugger module', function () { w.webContents.openDevTools() try { w.webContents.debugger.attach() - } catch(err) { + } catch (err) { assert(w.webContents.debugger.isAttached()) done() } @@ -41,7 +41,7 @@ describe('debugger module', function () { it('fails when protocol version is not supported', function (done) { try { w.webContents.debugger.attach('2.0') - } catch(err) { + } catch (err) { assert(!w.webContents.debugger.isAttached()) done() } @@ -50,7 +50,7 @@ describe('debugger module', function () { it('attaches when no protocol version is specified', function (done) { try { w.webContents.debugger.attach() - } catch(err) { + } catch (err) { done('unexpected error : ' + err) } assert(w.webContents.debugger.isAttached()) @@ -67,7 +67,7 @@ describe('debugger module', function () { }) try { w.webContents.debugger.attach() - } catch(err) { + } catch (err) { done('unexpected error : ' + err) } w.webContents.debugger.detach() @@ -79,7 +79,7 @@ describe('debugger module', function () { w.webContents.loadURL('about:blank') try { w.webContents.debugger.attach() - } catch(err) { + } catch (err) { done('unexpected error : ' + err) } var callback = function (err, res) { @@ -101,7 +101,7 @@ describe('debugger module', function () { w.webContents.loadURL(url) try { w.webContents.debugger.attach() - } catch(err) { + } catch (err) { done('unexpected error : ' + err) } w.webContents.debugger.on('message', function (e, method, params) { @@ -120,7 +120,7 @@ describe('debugger module', function () { w.webContents.loadURL('about:blank') try { w.webContents.debugger.attach() - } catch(err) { + } catch (err) { done('unexpected error : ' + err) } w.webContents.debugger.sendCommand('Test', function (err) { diff --git a/spec/api-native-image-spec.js b/spec/api-native-image-spec.js index 6c5092cf7c3..196ed1356d7 100644 --- a/spec/api-native-image-spec.js +++ b/spec/api-native-image-spec.js @@ -45,7 +45,7 @@ describe('nativeImage module', () => { assert.equal(nsimage.length, 8) // If all bytes are null, that's Bad - assert.equal(nsimage.reduce((acc, x) => acc || (x != 0), false), true) + assert.equal(nsimage.reduce((acc, x) => acc || (x !== 0), false), true) }) }) }) diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 001359d3850..9f2a25eb4a5 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -183,7 +183,7 @@ describe('protocol module', function () { it('fails when sending object other than string', function (done) { var handler = function (request, callback) { - callback(new Date) + callback(new Date()) } protocol.registerBufferProtocol(protocolName, handler, function (error) { if (error) { @@ -413,7 +413,7 @@ describe('protocol module', function () { it('fails when sending unsupported content', function (done) { var handler = function (request, callback) { - callback(new Date) + callback(new Date()) } protocol.registerBufferProtocol(protocolName, handler, function (error) { if (error) { @@ -491,7 +491,7 @@ describe('protocol module', function () { it('fails when sending unsupported content', function (done) { var handler = function (request, callback) { - callback(new Date) + callback(new Date()) } protocol.registerHttpProtocol(protocolName, handler, function (error) { if (error) { diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index 2f4a50f69e5..563599f1368 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -1,3 +1,5 @@ +/* globals WebView */ + const assert = require('assert') const http = require('http') const path = require('path') @@ -231,7 +233,7 @@ describe('session module', function () { downloadServer.listen(0, '127.0.0.1', function () { var port = downloadServer.address().port ipcRenderer.sendSync('set-download-option', false, false) - var webview = new WebView + var webview = new WebView() webview.src = 'file://' + fixtures + '/api/blank.html' webview.addEventListener('did-finish-load', function () { webview.downloadURL(url + ':' + port + '/') diff --git a/spec/asar-spec.js b/spec/asar-spec.js index de235eb66ed..508ce8b557b 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -18,7 +18,7 @@ describe('asar package', function () { describe('fs.readFileSync', function () { it('does not leak fd', function () { var readCalls = 1 - while(readCalls <= 10000) { + while (readCalls <= 10000) { fs.readFileSync(path.join(process.resourcesPath, 'atom.asar', 'renderer', 'api', 'ipc.js')) readCalls++ } @@ -530,9 +530,9 @@ describe('asar package', function () { describe('fs.mkdirSync', function () { it('throws error when calling inside asar archive', function () { var p = path.join(fixtures, 'asar', 'a.asar', 'not-exist') - assert.throws((function () { + assert.throws(function () { fs.mkdirSync(p) - }), new RegExp('ENOTDIR')) + }, new RegExp('ENOTDIR')) }) }) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 244f9f77a1e..a27d630b04c 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -103,10 +103,11 @@ describe('chromium feature', function () { navigator.mediaDevices.enumerateDevices().then((devices) => { const labels = devices.map((device) => device.label) const labelFound = labels.some((label) => !!label) - if (labelFound) + if (labelFound) { done() - else + } else { done('No device labels found: ' + JSON.stringify(labels)) + } }).catch(done) }) }) @@ -171,8 +172,9 @@ describe('chromium feature', function () { it('inherit options of parent window', function (done) { var b listener = function (event) { - var height, ref1, width - ref1 = remote.getCurrentWindow().getSize(), width = ref1[0], height = ref1[1] + var ref1 = remote.getCurrentWindow().getSize() + var width = ref1[0] + var height = ref1[1] assert.equal(event.data, 'size: ' + width + ' ' + height) b.close() done() From c5f70c8d9976eae97ca5d41f20a03f5d31c14a47 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 16:31:06 -0700 Subject: [PATCH 618/688] dance around error checking with this one weird trick --- spec/api-debugger-spec.js | 16 ++++++++++------ spec/api-ipc-spec.js | 6 +++--- spec/chromium-spec.js | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index fdad013b8cf..634d965a85f 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -80,24 +80,28 @@ describe('debugger module', function () { try { w.webContents.debugger.attach() } catch (err) { - done('unexpected error : ' + err) + return done('unexpected error : ' + err) } + /* eslint-disable */ + // standard expects callback errors to be handled, + // but for some reason this err is not actually null.. var callback = function (err, res) { assert(!res.wasThrown) assert.equal(res.result.value, 6) w.webContents.debugger.detach() done() } + /* eslint-enable */ const params = { - 'expression': '4+2', + 'expression': '4+2' } w.webContents.debugger.sendCommand('Runtime.evaluate', params, callback) }) it('fires message event', function (done) { - var url = process.platform != 'win32' ? - 'file://' + path.join(fixtures, 'pages', 'a.html') : - 'file:///' + path.join(fixtures, 'pages', 'a.html').replace(/\\/g, '/') + var url = process.platform !== 'win32' + ? 'file://' + path.join(fixtures, 'pages', 'a.html') + : 'file:///' + path.join(fixtures, 'pages', 'a.html').replace(/\\/g, '/') w.webContents.loadURL(url) try { w.webContents.debugger.attach() @@ -105,7 +109,7 @@ describe('debugger module', function () { done('unexpected error : ' + err) } w.webContents.debugger.on('message', function (e, method, params) { - if (method == 'Console.messageAdded') { + if (method === 'Console.messageAdded') { assert.equal(params.message.type, 'log') assert.equal(params.message.url, url) assert.equal(params.message.text, 'a') diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 862a6c99c17..0b279ef7266 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -60,7 +60,7 @@ describe('ipc module', function () { it('can construct an object from its member', function () { var call = remote.require(path.join(fixtures, 'module', 'call.js')) - var obj = new call.constructor + var obj = new call.constructor // eslint-disable-line assert.equal(obj.test, 'test') }) @@ -68,7 +68,7 @@ describe('ipc module', function () { var remoteFunctions = remote.require(path.join(fixtures, 'module', 'function.js')) assert.equal(remoteFunctions.aFunction(), 1127) - remoteFunctions.aFunction = function () { return 1234; } + remoteFunctions.aFunction = function () { return 1234 } assert.equal(remoteFunctions.aFunction(), 1234) assert.equal(delete remoteFunctions.aFunction, true) @@ -106,7 +106,7 @@ describe('ipc module', function () { it('can return same object with different getters', function () { var contents1 = remote.getCurrentWindow().webContents var contents2 = remote.getCurrentWebContents() - assert(contents1 == contents2) + assert(contents1 === contents2) }) }) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index a27d630b04c..87140be7c80 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -391,7 +391,7 @@ describe('chromium feature', function () { done('user agent is empty') } }) - var socket = new WebSocket(`ws://127.0.0.1: ${port}`) + var socket = new WebSocket(`ws://127.0.0.1:${port}`) assert(socket) }) }) From 14fb3c4598a919d58c641b4ded5d55e2888a962f Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 16:33:16 -0700 Subject: [PATCH 619/688] throw error if it exists --- spec/api-crash-reporter-spec.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index 708daeab956..2e49fdc36c5 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -40,9 +40,8 @@ describe('crash-reporter module', function () { server.close() var form = new multiparty.Form() form.parse(req, function (error, fields) { - if (called) { - return - } + if (error) throw error + if (called) return called = true assert.equal(fields['prod'], 'Electron') assert.equal(fields['ver'], process.versions['electron']) From fd0f9519f104438866fc601e63d1ad72abc2f595 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 16:36:08 -0700 Subject: [PATCH 620/688] remove useless constructors --- lib/renderer/web-view/guest-view-internal.js | 4 +++- lib/renderer/web-view/web-view-attributes.js | 10 ++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/renderer/web-view/guest-view-internal.js b/lib/renderer/web-view/guest-view-internal.js index 48ddf5ea10b..6c5a499ca9d 100644 --- a/lib/renderer/web-view/guest-view-internal.js +++ b/lib/renderer/web-view/guest-view-internal.js @@ -1,3 +1,5 @@ +/* globals Event */ + 'use strict' const ipcRenderer = require('electron').ipcRenderer @@ -102,5 +104,5 @@ module.exports = { }, setSize: function (guestInstanceId, params) { return ipcRenderer.send('ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', guestInstanceId, params) - }, + } } diff --git a/lib/renderer/web-view/web-view-attributes.js b/lib/renderer/web-view/web-view-attributes.js index 712973cea85..922aaa8c017 100644 --- a/lib/renderer/web-view/web-view-attributes.js +++ b/lib/renderer/web-view/web-view-attributes.js @@ -1,3 +1,5 @@ +/* globals MutationObserver */ + 'use strict' const WebViewImpl = require('./web-view') @@ -60,10 +62,6 @@ class WebViewAttribute { // An attribute that is treated as a Boolean. class BooleanAttribute extends WebViewAttribute { - constructor (name, webViewImpl) { - super(name, webViewImpl) - } - getValue () { return this.webViewImpl.webviewNode.hasAttribute(this.name) } @@ -79,10 +77,6 @@ class BooleanAttribute extends WebViewAttribute { // Attribute used to define the demension limits of autosizing. class AutosizeDimensionAttribute extends WebViewAttribute { - constructor (name, webViewImpl) { - super(name, webViewImpl) - } - getValue () { return parseInt(this.webViewImpl.webviewNode.getAttribute(this.name)) || 0 } From cfdfdc8cccc753ce16c9fb1b19096d5d5b36227a Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 17:16:08 -0700 Subject: [PATCH 621/688] standardize by hand --- lib/renderer/web-view/web-view.js | 10 ++++++---- spec/api-browser-window-spec.js | 24 ++++++++++-------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index f03427e5b5f..55d94824c24 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -1,3 +1,5 @@ +/* globals Event, HTMLObjectElement */ + 'use strict' const deprecate = require('electron').deprecate @@ -72,7 +74,7 @@ var WebViewImpl = (function () { this.beforeFirstNavigation = true this.attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId = true } - return this.internalInstanceId = 0 + this.internalInstanceId = 0 } // Sets the .request property. @@ -267,7 +269,7 @@ var registerBrowserPluginElement = function () { this.setAttribute('id', 'browser-plugin-' + getNextId()) // The node fills in the container. - return this.style.flex = '1 1 auto' + this.style.flex = '1 1 auto' } proto.attributeChangedCallback = function (name, oldValue, newValue) { var internal @@ -374,7 +376,7 @@ var registerWebViewElement = function () { 'downloadURL', 'inspectServiceWorker', 'print', - 'printToPDF', + 'printToPDF' ] nonblockMethods = [ 'insertCSS', @@ -383,7 +385,7 @@ var registerWebViewElement = function () { 'sendInputEvent', 'setZoomFactor', 'setZoomLevel', - 'setZoomLevelLimits', + 'setZoomLevelLimits' ] // Forward proto.foo* method calls to WebViewImpl.foo*. diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 77e8b004bfe..a5b14c17425 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -87,9 +87,9 @@ describe('browser-window module', function () { it('prevents users to access methods of webContents', function () { var webContents = w.webContents w.destroy() - assert.throws((function () { + assert.throws(function () { webContents.getId() - }), /Object has been destroyed/) + }, /Object has been destroyed/) }) }) @@ -522,8 +522,7 @@ describe('browser-window module', function () { w.loadURL('file://' + fixtures + '/api/blank.html') w.webContents.beginFrameSubscription(function (data) { // This callback might be called twice. - if (called) - return + if (called) return called = true assert.notEqual(data.length, 0) @@ -595,8 +594,7 @@ describe('browser-window module', function () { describe('window states (excluding Linux)', function () { // Not implemented on Linux. - if (process.platform == 'linux') - return + if (process.platform === 'linux') return describe('movable state', function () { it('can be changed with movable option', function () { @@ -657,8 +655,7 @@ describe('browser-window module', function () { describe('fullscreenable state', function () { // Only implemented on OS X. - if (process.platform != 'darwin') - return + if (process.platform !== 'darwin') return it('can be changed with fullscreenable option', function () { w.destroy() @@ -696,14 +693,13 @@ describe('browser-window module', function () { // dynamically. it('can be changed with hasShadow option', function () { w.destroy() - let hasShadow = process.platform == 'darwin' ? false : true + let hasShadow = process.platform !== 'darwin' w = new BrowserWindow({show: false, hasShadow: hasShadow}) assert.equal(w.hasShadow(), hasShadow) }) it('can be changed with setHasShadow method', function () { - if (process.platform != 'darwin') - return + if (process.platform !== 'darwin') return assert.equal(w.hasShadow(), true) w.setHasShadow(false) @@ -763,19 +759,19 @@ describe('browser-window module', function () { describe('deprecated options', function () { it('throws a deprecation error for option keys using hyphens instead of camel case', function () { assert.throws(function () { - new BrowserWindow({'min-width': 500}) + new BrowserWindow({'min-width': 500}) // eslint-disable-line }, 'min-width is deprecated. Use minWidth instead.') }) it('throws a deprecation error for webPreference keys using hyphens instead of camel case', function () { assert.throws(function () { - new BrowserWindow({webPreferences: {'node-integration': false}}) + new BrowserWindow({webPreferences: {'node-integration': false}}) // eslint-disable-line }, 'node-integration is deprecated. Use nodeIntegration instead.') }) it('throws a deprecation error for option keys that should be set on webPreferences', function () { assert.throws(function () { - new BrowserWindow({zoomFactor: 1}) + new BrowserWindow({zoomFactor: 1}) // eslint-disable-line }, 'options.zoomFactor is deprecated. Use options.webPreferences.zoomFactor instead.') }) }) From e6698102c9588a5bdf4a65dfd75a3e063c95f881 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 17:35:49 -0700 Subject: [PATCH 622/688] standardize by hand --- lib/browser/api/navigation-controller.js | 10 +++++----- lib/browser/api/web-contents.js | 13 ++++++++----- lib/browser/init.js | 2 +- lib/common/api/callbacks-registry.js | 2 +- lib/common/api/deprecate.js | 6 +++--- lib/common/asar.js | 2 +- lib/renderer/api/ipc.js | 2 +- lib/renderer/api/remote.js | 17 +++++++---------- lib/renderer/init.js | 2 +- lib/renderer/override.js | 4 +++- lib/renderer/web-view/web-view-attributes.js | 2 +- lib/renderer/web-view/web-view.js | 3 +-- spec/api-app-spec.js | 2 +- 13 files changed, 34 insertions(+), 33 deletions(-) diff --git a/lib/browser/api/navigation-controller.js b/lib/browser/api/navigation-controller.js index 21d885c738c..d9dedc91e34 100644 --- a/lib/browser/api/navigation-controller.js +++ b/lib/browser/api/navigation-controller.js @@ -5,12 +5,12 @@ const ipcMain = require('electron').ipcMain // The history operation in renderer is redirected to browser. ipcMain.on('ATOM_SHELL_NAVIGATION_CONTROLLER', function (event, method, ...args) { var ref - return (ref = event.sender)[method].apply(ref, args) + (ref = event.sender)[method].apply(ref, args) }) ipcMain.on('ATOM_SHELL_SYNC_NAVIGATION_CONTROLLER', function (event, method, ...args) { var ref - return event.returnValue = (ref = event.sender)[method].apply(ref, args) + event.returnValue = (ref = event.sender)[method].apply(ref, args) }) // JavaScript implementation of Chromium's NavigationController. @@ -41,10 +41,10 @@ var NavigationController = (function () { // Go to index. this.currentIndex = this.pendingIndex this.pendingIndex = -1 - return this.history[this.currentIndex] = url + this.history[this.currentIndex] = url } else if (replaceEntry) { // Non-user initialized navigation. - return this.history[this.currentIndex] = url + this.history[this.currentIndex] = url } else { // Normal navigation. Clear history. this.history = this.history.slice(0, this.currentIndex + 1) @@ -111,7 +111,7 @@ var NavigationController = (function () { this.history = [] this.currentIndex = -1 this.pendingIndex = -1 - return this.inPageIndex = -1 + this.inPageIndex = -1 } NavigationController.prototype.goBack = function () { diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index acdd8da7275..9187c87bfcc 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -87,7 +87,7 @@ let wrapWebContents = function (webContents) { method = ref1[name] if (method instanceof Function) { (function (name, method) { - return webContents[name] = function () { + webContents[name] = function () { return method.apply(controller, arguments) } })(name, method) @@ -104,8 +104,7 @@ let wrapWebContents = function (webContents) { const asyncWebFrameMethods = function (requestId, method, callback, ...args) { this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', requestId, method, args) ipcMain.once(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, function (event, result) { - if (callback) - callback(result) + if (callback) callback(result) }) } @@ -117,10 +116,11 @@ let wrapWebContents = function (webContents) { callback = hasUserGesture hasUserGesture = false } - if (this.getURL() && !this.isLoading()) + if (this.getURL() && !this.isLoading()) { return asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture) - else + } else { return this.once('did-finish-load', asyncWebFrameMethods.bind(this, requestId, 'executeJavaScript', callback, code, hasUserGesture)) + } } // Dispatch IPC messages to the ipc module. @@ -128,11 +128,14 @@ let wrapWebContents = function (webContents) { return ipcMain.emit.apply(ipcMain, [channel, event].concat(args)) }) webContents.on('ipc-message-sync', function (event, [channel, ...args]) { + /* eslint-disable */ + // standard complains: Getter is not present Object.defineProperty(event, 'returnValue', { set: function (value) { return event.sendReply(JSON.stringify(value)) } }) + /* eslint-enable */ return ipcMain.emit.apply(ipcMain, [channel, event].concat(args)) }) diff --git a/lib/browser/init.js b/lib/browser/init.js index ad871cd7153..d04b174adb6 100644 --- a/lib/browser/init.js +++ b/lib/browser/init.js @@ -46,7 +46,7 @@ if (process.platform === 'win32') { // Always returns EOF for stdin stream. var Readable = require('stream').Readable - var stdin = new Readable + var stdin = new Readable() stdin.push(null) process.__defineGetter__('stdin', function () { return stdin diff --git a/lib/common/api/callbacks-registry.js b/lib/common/api/callbacks-registry.js index c8b8579601d..3e71899df29 100644 --- a/lib/common/api/callbacks-registry.js +++ b/lib/common/api/callbacks-registry.js @@ -20,7 +20,7 @@ class CallbacksRegistry { // Capture the location of the function and put it in the ID string, // so that release errors can be tracked down easily. regexp = /at (.*)/gi - stackString = (new Error).stack + stackString = (new Error()).stack while ((match = regexp.exec(stackString)) !== null) { location = match[1] if (location.indexOf('(native)') !== -1) { diff --git a/lib/common/api/deprecate.js b/lib/common/api/deprecate.js index f272915167f..ff34a2bdfe7 100644 --- a/lib/common/api/deprecate.js +++ b/lib/common/api/deprecate.js @@ -23,9 +23,9 @@ deprecate.rename = function (object, oldName, newName) { return this[newName].apply(this, arguments) } if (typeof object === 'function') { - return object.prototype[oldName] = newMethod + object.prototype[oldName] = newMethod } else { - return object[oldName] = newMethod + object[oldName] = newMethod } } @@ -33,7 +33,7 @@ deprecate.rename = function (object, oldName, newName) { deprecate.member = function (object, method, member) { var warned warned = false - return object.prototype[method] = function () { + object.prototype[method] = function () { if (!(warned || process.noDeprecation)) { warned = true deprecate.warn(method, member + '.' + method) diff --git a/lib/common/asar.js b/lib/common/asar.js index dbf56705025..f79075ce23d 100644 --- a/lib/common/asar.js +++ b/lib/common/asar.js @@ -1,4 +1,4 @@ -/* globals $, xit */ +/* globals $ */ (function () { const asar = process.binding('atom_common_asar') diff --git a/lib/renderer/api/ipc.js b/lib/renderer/api/ipc.js index bda68f7bedb..25519a308da 100644 --- a/lib/renderer/api/ipc.js +++ b/lib/renderer/api/ipc.js @@ -6,7 +6,7 @@ const EventEmitter = require('events').EventEmitter deprecate.warn('ipc module', 'require("electron").ipcRenderer') // Routes events of ipcRenderer. -var ipc = new EventEmitter +var ipc = new EventEmitter() ipcRenderer.emit = function (channel, event, ...args) { ipc.emit.apply(ipc, [channel].concat(args)) diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index 0028a6191cd..5f60a970ff3 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -5,11 +5,11 @@ const CallbacksRegistry = require('electron').CallbacksRegistry const v8Util = process.atomBinding('v8_util') const IDWeakMap = process.atomBinding('id_weak_map').IDWeakMap -const callbacksRegistry = new CallbacksRegistry +const callbacksRegistry = new CallbacksRegistry() var includes = [].includes -var remoteObjectCache = new IDWeakMap +var remoteObjectCache = new IDWeakMap() // Check for circular reference. var isCircular = function (field, visited) { @@ -48,7 +48,7 @@ var wrapArgs = function (args, visited) { } else if ((value != null ? value.constructor.name : void 0) === 'Promise') { return { type: 'promise', - then: valueToMeta(function (v) { value.then(v); }) + then: valueToMeta(function (v) { value.then(v) }) } } else if ((value != null) && typeof value === 'object' && v8Util.getHiddenValue(value, 'atomId')) { return { @@ -94,8 +94,7 @@ var wrapArgs = function (args, visited) { // This matches |getObjectMemebers| in rpc-server. let setObjectMembers = function (object, metaId, members) { for (let member of members) { - if (object.hasOwnProperty(member.name)) - continue + if (object.hasOwnProperty(member.name)) continue let descriptor = { enumerable: member.enumerable } if (member.type === 'method') { @@ -134,8 +133,7 @@ let setObjectMembers = function (object, metaId, members) { // Populate object's prototype from descriptor. // This matches |getObjectPrototype| in rpc-server. let setObjectPrototype = function (object, metaId, descriptor) { - if (descriptor === null) - return + if (descriptor === null) return let proto = {} setObjectMembers(proto, metaId, descriptor.members) setObjectPrototype(proto, metaId, descriptor.proto) @@ -169,8 +167,7 @@ let metaToValue = function (meta) { case 'exception': throw new Error(meta.message + '\n' + meta.stack) default: - if (remoteObjectCache.has(meta.id)) - return remoteObjectCache.get(meta.id) + if (remoteObjectCache.has(meta.id)) return remoteObjectCache.get(meta.id) if (meta.type === 'function') { // A shadow class to represent the remote function object. @@ -220,7 +217,7 @@ var metaToPlainObject = function (meta) { obj = (function () { switch (meta.type) { case 'error': - return new Error + return new Error() default: return {} } diff --git a/lib/renderer/init.js b/lib/renderer/init.js index 511f9e57e8f..a005261c570 100644 --- a/lib/renderer/init.js +++ b/lib/renderer/init.js @@ -26,7 +26,7 @@ globalPaths.push(path.join(__dirname, 'api', 'exports')) // The global variable will be used by ipc for event dispatching var v8Util = process.atomBinding('v8_util') -v8Util.setHiddenValue(global, 'ipc', new events.EventEmitter) +v8Util.setHiddenValue(global, 'ipc', new events.EventEmitter()) // Use electron module after everything is ready. const electron = require('electron') diff --git a/lib/renderer/override.js b/lib/renderer/override.js index ddabf793ff7..e1fa947000f 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -1,3 +1,5 @@ +/* globals Event */ + 'use strict' const ipcRenderer = require('electron').ipcRenderer @@ -199,7 +201,7 @@ if (process.openerId != null) { } ipcRenderer.on('ATOM_RENDERER_WINDOW_VISIBILITY_CHANGE', function (event, isVisible, isMinimized) { - var hasChanged = _isVisible != isVisible || _isMinimized != isMinimized + var hasChanged = _isVisible !== isVisible || _isMinimized !== isMinimized if (hasChanged) { _isVisible = isVisible diff --git a/lib/renderer/web-view/web-view-attributes.js b/lib/renderer/web-view/web-view-attributes.js index 922aaa8c017..72395fe4a2c 100644 --- a/lib/renderer/web-view/web-view-attributes.js +++ b/lib/renderer/web-view/web-view-attributes.js @@ -40,7 +40,7 @@ class WebViewAttribute { setValueIgnoreMutation (value) { this.ignoreMutation = true this.setValue(value) - return this.ignoreMutation = false + this.ignoreMutation = false } // Defines this attribute as a property on the webview node. diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index 55d94824c24..d5b57c65149 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -423,8 +423,7 @@ var registerWebViewElement = function () { let requestId = getNextId() ipcRenderer.send('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', requestId, internal.guestInstanceId, 'executeJavaScript', code, hasUserGesture) ipcRenderer.once(`ATOM_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, function (event, result) { - if (callback) - callback(result) + if (callback) callback(result) }) } diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 2a5417b9c50..c237ef17238 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -18,7 +18,7 @@ describe('electron module', function () { electron.hideInternalModules() try { require('clipboard') - } catch(err) { + } catch (err) { assert.equal(err.message, "Cannot find module 'clipboard'") done() } From 2c3cacdc087e58135818d6a82e5c468b816c3cf6 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 17:40:40 -0700 Subject: [PATCH 623/688] standardize by hand --- lib/browser/api/menu.js | 8 ++++---- lib/browser/api/session.js | 2 +- lib/browser/api/tray.js | 2 +- lib/browser/api/web-contents.js | 2 +- lib/browser/chrome-extension.js | 5 +++-- lib/browser/desktop-capturer.js | 2 +- lib/browser/guest-view-manager.js | 4 ++-- lib/browser/guest-window-manager.js | 6 +++--- 8 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index 7330b89dd74..892f7a250fc 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -93,7 +93,7 @@ Menu.prototype._init = function () { this.commandsMap = {} this.groupsMap = {} this.items = [] - return this.delegate = { + this.delegate = { isCommandIdChecked: (commandId) => { var command = this.commandsMap[commandId] return command != null ? command.checked : undefined @@ -142,7 +142,7 @@ Menu.prototype._init = function () { } Menu.prototype.popup = function (window, x, y, positioningItem) { - if (typeof window != 'object' || window.constructor !== BrowserWindow) { + if (typeof window !== 'object' || window.constructor !== BrowserWindow) { // Shift. positioningItem = y y = x @@ -224,7 +224,7 @@ Menu.prototype.insert = function (pos, item) { // Remember the items. this.items.splice(pos, 0, item) - return this.commandsMap[item.commandId] = item + this.commandsMap[item.commandId] = item } // Force menuWillShow to be called @@ -284,7 +284,7 @@ Menu.buildFromTemplate = function (template) { } positionedTemplate.splice(insertIndex, 0, item) } - menu = new Menu + menu = new Menu() for (k = 0, len1 = positionedTemplate.length; k < len1; k++) { item = positionedTemplate[k] if (typeof item !== 'object') { diff --git a/lib/browser/api/session.js b/lib/browser/api/session.js index 01814774fdc..f0ff786cf2b 100644 --- a/lib/browser/api/session.js +++ b/lib/browser/api/session.js @@ -27,7 +27,7 @@ Object.defineProperty(exports, 'defaultSession', { var wrapSession = function (session) { // session is an EventEmitter. - return session.__proto__ = EventEmitter.prototype + session.__proto__ = EventEmitter.prototype } bindings._setWrapSession(wrapSession) diff --git a/lib/browser/api/tray.js b/lib/browser/api/tray.js index 1f9f5881b28..293825200e4 100644 --- a/lib/browser/api/tray.js +++ b/lib/browser/api/tray.js @@ -17,7 +17,7 @@ Tray.prototype.setContextMenu = function (menu) { this._setContextMenu(menu) // Keep a strong reference of menu. - return this.menu = menu + this.menu = menu } module.exports = Tray diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index 9187c87bfcc..60c159467ff 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -168,7 +168,7 @@ let wrapWebContents = function (webContents) { deprecate.event(webContents, 'page-title-set', 'page-title-updated', function (...args) { return this.emit.apply(this, ['page-title-set'].concat(args)) }) - return webContents.printToPDF = function (options, callback) { + webContents.printToPDF = function (options, callback) { var printingSetting printingSetting = { pageRage: [], diff --git a/lib/browser/chrome-extension.js b/lib/browser/chrome-extension.js index db3e4e9f9a5..562e77a1150 100644 --- a/lib/browser/chrome-extension.js +++ b/lib/browser/chrome-extension.js @@ -71,7 +71,8 @@ app.on('will-quit', function () { // We can not use protocol or BrowserWindow until app is ready. app.once('ready', function () { var BrowserWindow, chromeExtensionHandler, i, init, len, protocol, srcDirectory - protocol = electron.protocol, BrowserWindow = electron.BrowserWindow + protocol = electron.protocol + BrowserWindow = electron.BrowserWindow // Load persisted extensions. loadedExtensionsPath = path.join(app.getPath('userData'), 'DevTools Extensions') @@ -133,7 +134,7 @@ app.once('ready', function () { // Load persisted extensions when devtools is opened. init = BrowserWindow.prototype._init - return BrowserWindow.prototype._init = function () { + BrowserWindow.prototype._init = function () { init.call(this) return this.on('devtools-opened', function () { return this._loadDevToolsExtensions(Object.keys(extensionInfoMap).map(function (key) { diff --git a/lib/browser/desktop-capturer.js b/lib/browser/desktop-capturer.js index fd234437ff5..5ba64fcddb1 100644 --- a/lib/browser/desktop-capturer.js +++ b/lib/browser/desktop-capturer.js @@ -29,7 +29,7 @@ ipcMain.on('ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', function (event, capture // If the WebContents is destroyed before receiving result, just remove the // reference from requestsQueue to make the module not send the result to it. return event.sender.once('destroyed', function () { - return request.webContents = null + request.webContents = null }) }) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index 0526e6a1361..ee633cf2901 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -131,7 +131,7 @@ var createGuest = function (embedder, params) { } this.loadURL(params.src, opts) } - return guest.allowPopups = params.allowpopups + guest.allowPopups = params.allowpopups }) // Dispatch events to embedder. @@ -188,7 +188,7 @@ var attachGuest = function (embedder, elementInstanceId, guestInstanceId, params webViewManager.addGuest(guestInstanceId, elementInstanceId, embedder, guest, webPreferences) guest.attachParams = params embedderElementsMap[key] = guestInstanceId - return reverseEmbedderElementsMap[guestInstanceId] = key + reverseEmbedderElementsMap[guestInstanceId] = key } // Destroy an existing guest instance. diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index 94805a4c1fb..bc88337eb06 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -84,9 +84,9 @@ ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, options = mergeBrowserWindowOptions(event.sender, options) event.sender.emit('new-window', event, url, frameName, 'new-window', options) if ((event.sender.isGuest() && !event.sender.allowPopups) || event.defaultPrevented) { - return event.returnValue = null + event.returnValue = null } else { - return event.returnValue = createGuest(event.sender, url, frameName, options) + event.returnValue = createGuest(event.sender, url, frameName, options) } }) @@ -97,7 +97,7 @@ ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', function (event, gues ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_METHOD', function (event, guestId, method, ...args) { var ref1 - return event.returnValue = (ref1 = BrowserWindow.fromId(guestId)) != null ? ref1[method].apply(ref1, args) : void 0 + event.returnValue = (ref1 = BrowserWindow.fromId(guestId)) != null ? ref1[method].apply(ref1, args) : void 0 }) ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', function (event, guestId, message, targetOrigin, sourceOrigin) { From 4e2f1311e099aa977589c2e620c702f8777a8cab Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 17:51:11 -0700 Subject: [PATCH 624/688] replace __proto__ with Object.setPrototype --- lib/browser/api/app.js | 4 ++-- lib/browser/api/auto-updater/auto-updater-native.js | 2 +- lib/browser/api/browser-window.js | 2 +- lib/browser/api/menu.js | 2 +- lib/browser/api/power-monitor.js | 2 +- lib/browser/api/screen.js | 2 +- lib/browser/api/session.js | 2 +- lib/browser/api/tray.js | 2 +- lib/browser/api/web-contents.js | 4 ++-- lib/renderer/api/web-frame.js | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/browser/api/app.js b/lib/browser/api/app.js index ac2cf608414..c2e2899e77c 100644 --- a/lib/browser/api/app.js +++ b/lib/browser/api/app.js @@ -9,7 +9,7 @@ const bindings = process.atomBinding('app') const downloadItemBindings = process.atomBinding('download_item') const app = bindings.app -app.__proto__ = EventEmitter.prototype +Object.setPrototypeOf(app, EventEmitter.prototype) app.setApplicationMenu = function (menu) { return Menu.setApplicationMenu(menu) @@ -102,7 +102,7 @@ deprecate.event(app, 'select-certificate', 'select-client-certificate') // Wrappers for native classes. var wrapDownloadItem = function (downloadItem) { // downloadItem is an EventEmitter. - downloadItem.__proto__ = EventEmitter.prototype + Object.setPrototypeOf(downloadItem, EventEmitter.prototype) // Deprecated. deprecate.property(downloadItem, 'url', 'getURL') diff --git a/lib/browser/api/auto-updater/auto-updater-native.js b/lib/browser/api/auto-updater/auto-updater-native.js index 86a1e63503c..1fff05dbd65 100644 --- a/lib/browser/api/auto-updater/auto-updater-native.js +++ b/lib/browser/api/auto-updater/auto-updater-native.js @@ -1,6 +1,6 @@ const EventEmitter = require('events').EventEmitter const autoUpdater = process.atomBinding('auto_updater').autoUpdater -autoUpdater.__proto__ = EventEmitter.prototype +Object.setPrototypeOf(autoUpdater, EventEmitter.prototype) module.exports = autoUpdater diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index d29f4c74314..a00fef3b453 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -5,7 +5,7 @@ const deprecate = require('electron').deprecate const EventEmitter = require('events').EventEmitter const {BrowserWindow, _setDeprecatedOptionsCheck} = process.atomBinding('window') -BrowserWindow.prototype.__proto__ = EventEmitter.prototype +Object.setPrototypeOf(BrowserWindow.prototype, EventEmitter.prototype) BrowserWindow.prototype._init = function () { // avoid recursive require. diff --git a/lib/browser/api/menu.js b/lib/browser/api/menu.js index 892f7a250fc..e05637e79e7 100644 --- a/lib/browser/api/menu.js +++ b/lib/browser/api/menu.js @@ -87,7 +87,7 @@ var indexToInsertByPosition = function (items, position) { const Menu = bindings.Menu -Menu.prototype.__proto__ = EventEmitter.prototype +Object.setPrototypeOf(Menu.prototype, EventEmitter.prototype) Menu.prototype._init = function () { this.commandsMap = {} diff --git a/lib/browser/api/power-monitor.js b/lib/browser/api/power-monitor.js index e09a36e6608..02afeb5ba11 100644 --- a/lib/browser/api/power-monitor.js +++ b/lib/browser/api/power-monitor.js @@ -1,6 +1,6 @@ const EventEmitter = require('events').EventEmitter const powerMonitor = process.atomBinding('power_monitor').powerMonitor -powerMonitor.__proto__ = EventEmitter.prototype +Object.setPrototypeOf(powerMonitor, EventEmitter.prototype) module.exports = powerMonitor diff --git a/lib/browser/api/screen.js b/lib/browser/api/screen.js index 42f6ad1a51a..9326ace2c4f 100644 --- a/lib/browser/api/screen.js +++ b/lib/browser/api/screen.js @@ -1,6 +1,6 @@ const EventEmitter = require('events').EventEmitter const screen = process.atomBinding('screen').screen -screen.__proto__ = EventEmitter.prototype +Object.setPrototypeOf(screen, EventEmitter.prototype) module.exports = screen diff --git a/lib/browser/api/session.js b/lib/browser/api/session.js index f0ff786cf2b..47e00bd0462 100644 --- a/lib/browser/api/session.js +++ b/lib/browser/api/session.js @@ -27,7 +27,7 @@ Object.defineProperty(exports, 'defaultSession', { var wrapSession = function (session) { // session is an EventEmitter. - session.__proto__ = EventEmitter.prototype + Object.setPrototypeOf(session, EventEmitter.prototype) } bindings._setWrapSession(wrapSession) diff --git a/lib/browser/api/tray.js b/lib/browser/api/tray.js index 293825200e4..ce67dbe117a 100644 --- a/lib/browser/api/tray.js +++ b/lib/browser/api/tray.js @@ -2,7 +2,7 @@ const deprecate = require('electron').deprecate const EventEmitter = require('events').EventEmitter const Tray = process.atomBinding('tray').Tray -Tray.prototype.__proto__ = EventEmitter.prototype +Object.setPrototypeOf(Tray.prototype, EventEmitter.prototype) Tray.prototype._init = function () { // Deprecated. diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index 60c159467ff..ef3d703dee7 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -66,7 +66,7 @@ const webFrameMethods = [ let wrapWebContents = function (webContents) { // webContents is an EventEmitter. var controller, method, name, ref1 - webContents.__proto__ = EventEmitter.prototype + Object.setPrototypeOf(webContents, EventEmitter.prototype) // Every remote callback from renderer process would add a listenter to the // render-view-deleted event, so ignore the listenters warning. @@ -217,7 +217,7 @@ let wrapWebContents = function (webContents) { // Wrapper for native class. let wrapDebugger = function (webContentsDebugger) { // debugger is an EventEmitter. - webContentsDebugger.__proto__ = EventEmitter.prototype + Object.setPrototypeOf(webContentsDebugger, EventEmitter.prototype) } binding._setWrapWebContents(wrapWebContents) diff --git a/lib/renderer/api/web-frame.js b/lib/renderer/api/web-frame.js index 7f48f1eabbd..4a152d4f364 100644 --- a/lib/renderer/api/web-frame.js +++ b/lib/renderer/api/web-frame.js @@ -6,7 +6,7 @@ const EventEmitter = require('events').EventEmitter const webFrame = process.atomBinding('web_frame').webFrame // webFrame is an EventEmitter. -webFrame.__proto__ = EventEmitter.prototype +Object.setPrototypeOf(webFrame, EventEmitter.prototype) // Lots of webview would subscribe to webFrame's events. webFrame.setMaxListeners(0) From 42e7ee2b4aef6de396927d16e6429a6ec44dd681 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 18:00:30 -0700 Subject: [PATCH 625/688] finish standardizing! --- default_app/main.js | 7 ++++--- lib/browser/api/app.js | 2 +- lib/browser/api/auto-updater/squirrel-update-win.js | 4 ++-- lib/browser/api/browser-window.js | 7 +++---- lib/browser/api/menu-item.js | 13 ++++++++++++- lib/common/asar.js | 2 -- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/default_app/main.js b/default_app/main.js index dcbe2ca0c65..43c8d729804 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -243,7 +243,7 @@ function loadApplicationPackage (packagePath) { } else if (packageJson.name) { app.setName(packageJson.name) } - + app.setPath('userData', path.join(app.getPath('appData'), app.getName())) app.setPath('userCache', path.join(app.getPath('cache'), app.getName())) app.setAppPath(packagePath) @@ -251,7 +251,7 @@ function loadApplicationPackage (packagePath) { // Run the app. require('module')._load(packagePath, module, true) - } catch(e) { + } catch (e) { if (e.code === 'MODULE_NOT_FOUND') { app.focus() dialog.showErrorBox( @@ -319,5 +319,6 @@ if (option.file && !option.webdriver) { } else if (option.interactive) { startRepl() } else { - loadApplicationByUrl('file://' + __dirname + '/index.html') + var indexPath = path.join(__dirname, '/index.html') + loadApplicationByUrl(`file://${indexPath}`) } diff --git a/lib/browser/api/app.js b/lib/browser/api/app.js index c2e2899e77c..48a27cfc648 100644 --- a/lib/browser/api/app.js +++ b/lib/browser/api/app.js @@ -45,7 +45,7 @@ if (process.platform === 'darwin') { var appPath = null app.setAppPath = function (path) { - return appPath = path + appPath = path } app.getAppPath = function () { diff --git a/lib/browser/api/auto-updater/squirrel-update-win.js b/lib/browser/api/auto-updater/squirrel-update-win.js index d4f2d98ca50..da27e02aab6 100644 --- a/lib/browser/api/auto-updater/squirrel-update-win.js +++ b/lib/browser/api/auto-updater/squirrel-update-win.js @@ -30,10 +30,10 @@ var spawnUpdate = function (args, detached, callback) { stdout = '' stderr = '' spawnedProcess.stdout.on('data', function (data) { - return stdout += data + stdout += data }) spawnedProcess.stderr.on('data', function (data) { - return stderr += data + stderr += data }) errorEmitted = false spawnedProcess.on('error', function (error) { diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index a00fef3b453..7bbf898dafb 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -53,12 +53,11 @@ BrowserWindow.prototype._init = function () { this.webContents.on('page-title-updated', (event, title) => { // The page-title-updated event is not emitted immediately (see #3645), so // when the callback is called the BrowserWindow might have been closed. - if (this.isDestroyed()) - return + if (this.isDestroyed()) return + // Route the event to BrowserWindow. this.emit('page-title-updated', event, title) - if (!event.defaultPrevented) - this.setTitle(title) + if (!event.defaultPrevented) this.setTitle(title) }) // Sometimes the webContents doesn't get focus when window is shown, so we have diff --git a/lib/browser/api/menu-item.js b/lib/browser/api/menu-item.js index 62622317bbb..20666b0f36e 100644 --- a/lib/browser/api/menu-item.js +++ b/lib/browser/api/menu-item.js @@ -29,7 +29,18 @@ MenuItem = (function () { function MenuItem (options) { var click, ref const Menu = require('electron').Menu - click = options.click, this.selector = options.selector, this.type = options.type, this.role = options.role, this.label = options.label, this.sublabel = options.sublabel, this.accelerator = options.accelerator, this.icon = options.icon, this.enabled = options.enabled, this.visible = options.visible, this.checked = options.checked, this.submenu = options.submenu + click = options.click + this.selector = options.selector + this.type = options.type + this.role = options.role + this.label = options.label + this.sublabel = options.sublabel + this.accelerator = options.accelerator + this.icon = options.icon + this.enabled = options.enabled + this.visible = options.visible + this.checked = options.checked + this.submenu = options.submenu if ((this.submenu != null) && this.submenu.constructor !== Menu) { this.submenu = Menu.buildFromTemplate(this.submenu) } diff --git a/lib/common/asar.js b/lib/common/asar.js index f79075ce23d..26241281322 100644 --- a/lib/common/asar.js +++ b/lib/common/asar.js @@ -1,5 +1,3 @@ -/* globals $ */ - (function () { const asar = process.binding('atom_common_asar') const child_process = require('child_process') From 98b4353ef80f2dd55d7fe907d2cbb066d832f3e8 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 28 Mar 2016 22:10:27 -0700 Subject: [PATCH 626/688] replace snazzy with standard; autoformat package.json --- package.json | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 2d5c61f494f..efdaaa9163e 100644 --- a/package.json +++ b/package.json @@ -5,15 +5,25 @@ "asar": "^0.10.0", "eslint": "^2.1.0", "request": "*", - "snazzy": "^3.0.0" + "standard": "^6.0.8" }, "optionalDependencies": { "runas": "^3.0.0" }, "standard": { - "ignore": ["/vendor"], - "globals": ["$", "after", "afterEach", "before", - "beforeEach", "describe", "it", "location"] + "ignore": [ + "/vendor" + ], + "globals": [ + "$", + "after", + "afterEach", + "before", + "beforeEach", + "describe", + "it", + "location" + ] }, "private": true, "scripts": { From 6f845373a7cdb95e6de51aa07661a1fc674725d3 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Tue, 29 Mar 2016 10:33:17 -0700 Subject: [PATCH 627/688] do not return and assign --- lib/common/asar_init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/asar_init.js b/lib/common/asar_init.js index 1b24cd57aa4..0f728200880 100644 --- a/lib/common/asar_init.js +++ b/lib/common/asar_init.js @@ -9,7 +9,7 @@ // Make graceful-fs work with asar. var source = process.binding('natives') source['original-fs'] = source.fs - return source['fs'] = ` + source['fs'] = ` var nativeModule = new process.NativeModule('original-fs') nativeModule.cache() nativeModule.compile() From e156faea5c6d076d91c8d81bc82f1c022e247527 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Tue, 29 Mar 2016 10:43:41 -0700 Subject: [PATCH 628/688] replace eslint with standard --- package.json | 2 +- script/eslint.py | 36 ------------------------------------ script/eslintrc-base.json | 36 ------------------------------------ script/eslintrc-spec.json | 7 ------- 4 files changed, 1 insertion(+), 80 deletions(-) delete mode 100755 script/eslint.py delete mode 100644 script/eslintrc-base.json delete mode 100644 script/eslintrc-spec.json diff --git a/package.json b/package.json index efdaaa9163e..332578e6ce5 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "scripts": { "bootstrap": "python ./script/bootstrap.py", "build": "python ./script/build.py -c D", - "lint": "python ./script/eslint.py && python ./script/cpplint.py", + "lint": "standard && python ./script/cpplint.py", "preinstall": "node -e 'process.exit(0)'", "repl": "python ./script/start.py --interactive", "start": "python ./script/start.py", diff --git a/script/eslint.py b/script/eslint.py deleted file mode 100755 index 4fbc5788570..00000000000 --- a/script/eslint.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python - -import glob -import os -import sys - -from lib.config import PLATFORM -from lib.util import execute - - -SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) - - -def main(): - os.chdir(SOURCE_ROOT) - - # Skip eslint on our Windows build machine for now. - if PLATFORM == 'win32' and os.getenv('JANKY_SHA1'): - return - - eslint = os.path.join(SOURCE_ROOT, 'node_modules', '.bin', 'eslint') - if sys.platform in ['win32', 'cygwin']: - eslint += '.cmd' - settings = ['--quiet', '--config'] - - sourceConfig = os.path.join('script', 'eslintrc-base.json') - sourceFiles = ['lib'] - execute([eslint] + settings + [sourceConfig] + sourceFiles) - - specConfig = os.path.join('script', 'eslintrc-spec.json') - specFiles = glob.glob('spec/*.js') - execute([eslint] + settings + [specConfig] + specFiles) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/script/eslintrc-base.json b/script/eslintrc-base.json deleted file mode 100644 index f968a2d20c7..00000000000 --- a/script/eslintrc-base.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "rules": { - "indent": [ - 2, - 2, - { - "SwitchCase": 1 - } - ], - "quotes": [ - 0, - "single" - ], - "semi": [ - 2, - "always" - ], - "comma-dangle": 0, - "linebreak-style": 0, - "no-console": 0, - "no-undef": 2, - "no-unused-vars": 2 - }, - "env": { - "es6": true, - "node": true, - "browser": true - }, - "extends": "eslint:recommended", - "globals": { - "DevToolsAPI": false, - "InspectorFrontendHost": false, - "WebInspector": false, - "WebView": false - } -} diff --git a/script/eslintrc-spec.json b/script/eslintrc-spec.json deleted file mode 100644 index 5aa9df265d6..00000000000 --- a/script/eslintrc-spec.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "env": { - "jquery": true, - "mocha": true - }, - "extends": "./eslintrc-base.json" -} From 71f8ba6f7aa714fc1850162b0ff1e20b7947a7d2 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Tue, 29 Mar 2016 10:44:01 -0700 Subject: [PATCH 629/688] update CONTRIBUTING doc --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 67c1323205e..c7c221863dc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,7 +28,7 @@ possible with your report. If you can, please include: ## Submitting Pull Requests * Include screenshots and animated GIFs in your pull request whenever possible. -* Follow the CoffeeScript, JavaScript, C++ and Python [coding style defined in docs](/docs/development/coding-style.md). +* Follow the JavaScript, C++, and Python [coding style defined in docs](/docs/development/coding-style.md). * Write documentation in [Markdown](https://daringfireball.net/projects/markdown). See the [Documentation Styleguide](/docs/styleguide.md). * Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages). From 0fd0887407744e89f7945c4c988c73557531cc3f Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 13:17:04 -0700 Subject: [PATCH 630/688] use standard.env.mocha instead of a list of globals --- package.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 332578e6ce5..c4b49cd3c7a 100644 --- a/package.json +++ b/package.json @@ -14,14 +14,11 @@ "ignore": [ "/vendor" ], + "env": { + "mocha": true + }, "globals": [ "$", - "after", - "afterEach", - "before", - "beforeEach", - "describe", - "it", "location" ] }, From 1a18151effcc2a6a0925585fdc1666fa71b60baa Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 13:30:30 -0700 Subject: [PATCH 631/688] remove eslint from devDependencies --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index c4b49cd3c7a..29085205956 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "version": "0.37.3", "devDependencies": { "asar": "^0.10.0", - "eslint": "^2.1.0", "request": "*", "standard": "^6.0.8" }, From b5afad9da707b7ba597b72d067d4ffbeb86cf4f5 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 14:06:50 -0700 Subject: [PATCH 632/688] avoid using eslint comment exceptions --- lib/browser/api/web-contents.js | 6 +++--- lib/browser/rpc-server.js | 4 ++-- spec/api-browser-window-spec.js | 6 +++--- spec/api-debugger-spec.js | 5 +---- spec/api-ipc-spec.js | 2 +- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index ef3d703dee7..2ec7c14bae1 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -128,14 +128,14 @@ let wrapWebContents = function (webContents) { return ipcMain.emit.apply(ipcMain, [channel, event].concat(args)) }) webContents.on('ipc-message-sync', function (event, [channel, ...args]) { - /* eslint-disable */ - // standard complains: Getter is not present Object.defineProperty(event, 'returnValue', { set: function (value) { return event.sendReply(JSON.stringify(value)) + }, + get: function () { + return undefined } }) - /* eslint-enable */ return ipcMain.emit.apply(ipcMain, [channel, event].concat(args)) }) diff --git a/lib/browser/rpc-server.js b/lib/browser/rpc-server.js index eb1d0385fa1..79a52b13262 100644 --- a/lib/browser/rpc-server.js +++ b/lib/browser/rpc-server.js @@ -281,7 +281,7 @@ ipcMain.on('ATOM_BROWSER_CONSTRUCTOR', function (event, id, args) { // Call new with array of arguments. // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible - let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))) // eslint-disable-line + let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))) event.returnValue = valueToMeta(event.sender, obj) } catch (error) { event.returnValue = exceptionToMeta(error) @@ -304,7 +304,7 @@ ipcMain.on('ATOM_BROWSER_MEMBER_CONSTRUCTOR', function (event, id, method, args) let constructor = objectsRegistry.get(id)[method] // Call new with array of arguments. - let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))) // eslint-disable-line + let obj = new (Function.prototype.bind.apply(constructor, [null].concat(args))) event.returnValue = valueToMeta(event.sender, obj) } catch (error) { event.returnValue = exceptionToMeta(error) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index a5b14c17425..468586eb7bb 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -759,19 +759,19 @@ describe('browser-window module', function () { describe('deprecated options', function () { it('throws a deprecation error for option keys using hyphens instead of camel case', function () { assert.throws(function () { - new BrowserWindow({'min-width': 500}) // eslint-disable-line + return new BrowserWindow({'min-width': 500}) }, 'min-width is deprecated. Use minWidth instead.') }) it('throws a deprecation error for webPreference keys using hyphens instead of camel case', function () { assert.throws(function () { - new BrowserWindow({webPreferences: {'node-integration': false}}) // eslint-disable-line + return new BrowserWindow({webPreferences: {'node-integration': false}}) }, 'node-integration is deprecated. Use nodeIntegration instead.') }) it('throws a deprecation error for option keys that should be set on webPreferences', function () { assert.throws(function () { - new BrowserWindow({zoomFactor: 1}) // eslint-disable-line + return new BrowserWindow({zoomFactor: 1}) }, 'options.zoomFactor is deprecated. Use options.webPreferences.zoomFactor instead.') }) }) diff --git a/spec/api-debugger-spec.js b/spec/api-debugger-spec.js index 634d965a85f..27aacc7671c 100644 --- a/spec/api-debugger-spec.js +++ b/spec/api-debugger-spec.js @@ -82,16 +82,13 @@ describe('debugger module', function () { } catch (err) { return done('unexpected error : ' + err) } - /* eslint-disable */ - // standard expects callback errors to be handled, - // but for some reason this err is not actually null.. var callback = function (err, res) { + assert(!err.message) assert(!res.wasThrown) assert.equal(res.result.value, 6) w.webContents.debugger.detach() done() } - /* eslint-enable */ const params = { 'expression': '4+2' } diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index 0b279ef7266..be4f788fb0d 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -60,7 +60,7 @@ describe('ipc module', function () { it('can construct an object from its member', function () { var call = remote.require(path.join(fixtures, 'module', 'call.js')) - var obj = new call.constructor // eslint-disable-line + var obj = new call.constructor() assert.equal(obj.test, 'test') }) From 6425ef42610bd8a1476cdeb041ab0f042d655cb9 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 14:07:16 -0700 Subject: [PATCH 633/688] restrict mocha scope to /spec; break out link tasks --- package.json | 13 +++++-------- spec/package.json | 5 +++++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 29085205956..4b4691abb3b 100644 --- a/package.json +++ b/package.json @@ -11,21 +11,18 @@ }, "standard": { "ignore": [ + "/out", + "/spec", "/vendor" - ], - "env": { - "mocha": true - }, - "globals": [ - "$", - "location" ] }, "private": true, "scripts": { "bootstrap": "python ./script/bootstrap.py", "build": "python ./script/build.py -c D", - "lint": "standard && python ./script/cpplint.py", + "lint": "npm run lint-js && npm run lint-cpp", + "lint-js": "standard && standard spec", + "lint-cpp": "python ./script/cpplint.py", "preinstall": "node -e 'process.exit(0)'", "repl": "python ./script/start.py --interactive", "start": "python ./script/start.py", diff --git a/spec/package.json b/spec/package.json index 6d49f0da8b8..a6ca81c5ee9 100644 --- a/spec/package.json +++ b/spec/package.json @@ -18,5 +18,10 @@ "optionalDependencies": { "ffi": "2.0.0", "runas": "3.x" + }, + "standard": { + "env": { + "mocha": true + } } } From 47a61e9f2705b0e346117a26d375781029b7ed93 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 14:07:27 -0700 Subject: [PATCH 634/688] use window.location instead of location --- lib/renderer/chrome-api.js | 4 ++-- lib/renderer/init.js | 4 ++-- lib/renderer/override.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/renderer/chrome-api.js b/lib/renderer/chrome-api.js index eca791057c3..719066a6fae 100644 --- a/lib/renderer/chrome-api.js +++ b/lib/renderer/chrome-api.js @@ -4,9 +4,9 @@ const chrome = window.chrome = window.chrome || {} chrome.extension = { getURL: function (path) { return url.format({ - protocol: location.protocol, + protocol: window.location.protocol, slashes: true, - hostname: location.hostname, + hostname: window.location.hostname, pathname: path }) } diff --git a/lib/renderer/init.js b/lib/renderer/init.js index a005261c570..85b3a627fd3 100644 --- a/lib/renderer/init.js +++ b/lib/renderer/init.js @@ -65,11 +65,11 @@ for (i = 0, len = ref.length; i < len; i++) { } } -if (location.protocol === 'chrome-devtools:') { +if (window.location.protocol === 'chrome-devtools:') { // Override some inspector APIs. require('./inspector') nodeIntegration = 'true' -} else if (location.protocol === 'chrome-extension:') { +} else if (window.location.protocol === 'chrome-extension:') { // Add implementations of chrome API. require('./chrome-api') nodeIntegration = 'true' diff --git a/lib/renderer/override.js b/lib/renderer/override.js index e1fa947000f..a0177b70f84 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -70,7 +70,7 @@ var BrowserWindowProxy = (function () { if (targetOrigin == null) { targetOrigin = '*' } - return ipcRenderer.send('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, targetOrigin, location.origin) + return ipcRenderer.send('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, targetOrigin, window.location.origin) } BrowserWindowProxy.prototype['eval'] = function (...args) { From afbc914f8b97f326b9027b98ccb23ba6be012d3d Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 14:12:59 -0700 Subject: [PATCH 635/688] try to fix CI linting --- script/cibuild | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script/cibuild b/script/cibuild index 391b859a3d2..2ecc417eaf5 100755 --- a/script/cibuild +++ b/script/cibuild @@ -62,8 +62,8 @@ def main(): args += ['--dev'] run_script('bootstrap.py', args) - run_script('cpplint.py') - run_script('eslint.py') + execute([npm, 'run', 'lint']) + if PLATFORM != 'win32': run_script('pylint.py') if is_release: From 0d11b755db474a053b5945e8b82733caec0b06a2 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 14:16:16 -0700 Subject: [PATCH 636/688] say we are linting --- script/cibuild | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script/cibuild b/script/cibuild index 2ecc417eaf5..437f4e27c66 100755 --- a/script/cibuild +++ b/script/cibuild @@ -62,6 +62,8 @@ def main(): args += ['--dev'] run_script('bootstrap.py', args) + sys.stderr.write('\nRunning `npm run lint`\n') + sys.stderr.flush() execute([npm, 'run', 'lint']) if PLATFORM != 'win32': From aadc0bee2547bc60444b9a8c29474b9b72442804 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 14:21:07 -0700 Subject: [PATCH 637/688] do not lint on windows CI --- script/cibuild | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/script/cibuild b/script/cibuild index 437f4e27c66..54cfa508910 100755 --- a/script/cibuild +++ b/script/cibuild @@ -62,11 +62,10 @@ def main(): args += ['--dev'] run_script('bootstrap.py', args) - sys.stderr.write('\nRunning `npm run lint`\n') - sys.stderr.flush() - execute([npm, 'run', 'lint']) - if PLATFORM != 'win32': + sys.stderr.write('\nRunning `npm run lint`\n') + sys.stderr.flush() + execute([npm, 'run', 'lint']) run_script('pylint.py') if is_release: run_script('build.py', ['-c', 'R']) From 7c58f7fb0294e5109af3a2ed310eddd5eae998f2 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 14:56:30 -0700 Subject: [PATCH 638/688] eradicate all per-file eslint globals --- lib/renderer/inspector.js | 11 +++++------ lib/renderer/override.js | 2 -- lib/renderer/web-view/guest-view-internal.js | 2 -- lib/renderer/web-view/web-view-attributes.js | 2 -- lib/renderer/web-view/web-view.js | 2 -- package.json | 5 ++++- spec/api-session-spec.js | 2 -- spec/api-web-frame-spec.js | 4 +--- spec/api-web-request-spec.js | 2 -- spec/asar-spec.js | 2 -- spec/chromium-spec.js | 1 - spec/fixtures/pages/service-worker/service-worker.js | 2 -- spec/node-spec.js | 2 -- spec/package.json | 9 +++++++-- spec/webview-spec.js | 2 -- 15 files changed, 17 insertions(+), 33 deletions(-) diff --git a/lib/renderer/inspector.js b/lib/renderer/inspector.js index 2b0fcbc80c1..d7ef7e1a935 100644 --- a/lib/renderer/inspector.js +++ b/lib/renderer/inspector.js @@ -1,11 +1,10 @@ -/* globals InspectorFrontendHost, WebInspector, DevToolsAPI, DevToolsAPI, Blob */ - window.onload = function () { + // Use menu API to show context menu. - InspectorFrontendHost.showContextMenuAtPoint = createMenu + window.InspectorFrontendHost.showContextMenuAtPoint = createMenu // Use dialog API to override file chooser dialog. - return (WebInspector.createFileSelectorElement = createFileSelectorElement) + return (window.WebInspector.createFileSelectorElement = createFileSelectorElement) } var convertToMenuTemplate = function (items) { @@ -32,8 +31,8 @@ var convertToMenuTemplate = function (items) { } if (item.id != null) { transformed.click = function () { - DevToolsAPI.contextMenuItemSelected(item.id) - return DevToolsAPI.contextMenuCleared() + window.DevToolsAPI.contextMenuItemSelected(item.id) + return window.DevToolsAPI.contextMenuCleared() } } return template.push(transformed) diff --git a/lib/renderer/override.js b/lib/renderer/override.js index a0177b70f84..4bce0c6b770 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -1,5 +1,3 @@ -/* globals Event */ - 'use strict' const ipcRenderer = require('electron').ipcRenderer diff --git a/lib/renderer/web-view/guest-view-internal.js b/lib/renderer/web-view/guest-view-internal.js index 6c5a499ca9d..f4023d22701 100644 --- a/lib/renderer/web-view/guest-view-internal.js +++ b/lib/renderer/web-view/guest-view-internal.js @@ -1,5 +1,3 @@ -/* globals Event */ - 'use strict' const ipcRenderer = require('electron').ipcRenderer diff --git a/lib/renderer/web-view/web-view-attributes.js b/lib/renderer/web-view/web-view-attributes.js index 72395fe4a2c..c76e0d26f95 100644 --- a/lib/renderer/web-view/web-view-attributes.js +++ b/lib/renderer/web-view/web-view-attributes.js @@ -1,5 +1,3 @@ -/* globals MutationObserver */ - 'use strict' const WebViewImpl = require('./web-view') diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index d5b57c65149..0e96d0c0643 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -1,5 +1,3 @@ -/* globals Event, HTMLObjectElement */ - 'use strict' const deprecate = require('electron').deprecate diff --git a/package.json b/package.json index 4b4691abb3b..c12f3d37c42 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,10 @@ "/out", "/spec", "/vendor" - ] + ], + "env": { + "browser": true + } }, "private": true, "scripts": { diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index 563599f1368..d655788c79b 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -1,5 +1,3 @@ -/* globals WebView */ - const assert = require('assert') const http = require('http') const path = require('path') diff --git a/spec/api-web-frame-spec.js b/spec/api-web-frame-spec.js index 83fb4a560c5..450bf1c33ec 100644 --- a/spec/api-web-frame-spec.js +++ b/spec/api-web-frame-spec.js @@ -1,5 +1,3 @@ -/* globals fetch */ - const assert = require('assert') const path = require('path') const webFrame = require('electron').webFrame @@ -10,7 +8,7 @@ describe('webFrame module', function () { it('supports fetch api', function (done) { webFrame.registerURLSchemeAsPrivileged('file') var url = 'file://' + fixtures + '/assets/logo.png' - fetch(url).then(function (response) { + window.fetch(url).then(function (response) { assert(response.ok) done() }).catch(function (err) { diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index 8ce4bca8db1..abc4f9568cd 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -1,5 +1,3 @@ -/* globals $ */ - const assert = require('assert') const http = require('http') const qs = require('querystring') diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 508ce8b557b..45c4c119ca9 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -1,5 +1,3 @@ -/* globals xit */ - const assert = require('assert') const child_process = require('child_process') const fs = require('fs') diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 87140be7c80..b6e9a775ed0 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -1,4 +1,3 @@ -/* globals xdescribe, Worker, SharedWorker, WebSocket, HTMLElement */ const assert = require('assert') const http = require('http') diff --git a/spec/fixtures/pages/service-worker/service-worker.js b/spec/fixtures/pages/service-worker/service-worker.js index be5ecefd570..7d80f45e2df 100644 --- a/spec/fixtures/pages/service-worker/service-worker.js +++ b/spec/fixtures/pages/service-worker/service-worker.js @@ -1,5 +1,3 @@ -/* globals self, URL, Response */ - self.addEventListener('fetch', function (event) { var requestUrl = new URL(event.request.url) diff --git a/spec/node-spec.js b/spec/node-spec.js index 68b328b2ab9..286c4d6f916 100644 --- a/spec/node-spec.js +++ b/spec/node-spec.js @@ -1,5 +1,3 @@ -/* globals xit */ - const assert = require('assert') const child_process = require('child_process') const fs = require('fs') diff --git a/spec/package.json b/spec/package.json index a6ca81c5ee9..0439f4b0ec0 100644 --- a/spec/package.json +++ b/spec/package.json @@ -21,7 +21,12 @@ }, "standard": { "env": { - "mocha": true - } + "mocha": true, + "jquery": true, + "serviceworker": true + }, + "globals": [ + "WebView" + ] } } diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 4fdba97249a..e5116293563 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -1,5 +1,3 @@ -/* globals btoa, WebView, xdescribe */ - const assert = require('assert') const path = require('path') const http = require('http') From d5e8bb7f120c55374bd06927b7359e1412dcc4db Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 14:59:39 -0700 Subject: [PATCH 639/688] derp --- lib/renderer/inspector.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/renderer/inspector.js b/lib/renderer/inspector.js index d7ef7e1a935..df151cf1b5e 100644 --- a/lib/renderer/inspector.js +++ b/lib/renderer/inspector.js @@ -1,5 +1,4 @@ window.onload = function () { - // Use menu API to show context menu. window.InspectorFrontendHost.showContextMenuAtPoint = createMenu From 9efd29d059d30ae7b4d6cbccc9bdf6229b51a391 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 15:15:33 -0700 Subject: [PATCH 640/688] fix a minor style issue --- lib/renderer/override.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 4bce0c6b770..896103b6c1f 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -154,7 +154,7 @@ window.open = function (url, frameName, features) { } // Use the dialog API to implement alert(). -window.alert = function(message, title) { +window.alert = function (message, title) { var buttons if (arguments.length === 0) { message = '' From 252121ac7022136ca842b3088476495ac3858725 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 30 Mar 2016 16:29:30 -0700 Subject: [PATCH 641/688] give anonymous function a name --- lib/renderer/override.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 896103b6c1f..07f02566bcc 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -6,12 +6,13 @@ const remote = require('electron').remote // Cache browser window visibility var _isVisible = true var _isMinimized = false -;(function () { +var initWindow = function initWindow () { var currentWindow currentWindow = remote.getCurrentWindow() _isVisible = currentWindow.isVisible() _isMinimized = currentWindow.isMinimized() -})() +} +initWindow() // Helper function to resolve relative url. var a = window.top.document.createElement('a') From afb82fcc1fca8712b9228327fb0c98e8c3ed7655 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 31 Mar 2016 10:21:21 +0900 Subject: [PATCH 642/688] Update native-mate for #4892 --- vendor/native_mate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/native_mate b/vendor/native_mate index 38834cb9974..553326b0069 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 38834cb9974da9ddbc06c36f9ff23d7fa1918b03 +Subproject commit 553326b00696fcda106a8866872a8f2ad6caff0d From cfd2cdb9c4f1b5d6094a56de6be7789a96e2004b Mon Sep 17 00:00:00 2001 From: Andrew Plotkin Date: Wed, 30 Mar 2016 23:57:28 -0400 Subject: [PATCH 643/688] Added information about the enabled, visible, and checked properties -- when they can be set and what they mean. Also tidied up the grammar and clarified wording. --- docs/api/menu-item.md | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/docs/api/menu-item.md b/docs/api/menu-item.md index af945e8aca4..fb12e251153 100644 --- a/docs/api/menu-item.md +++ b/docs/api/menu-item.md @@ -14,7 +14,7 @@ Create a new `MenuItem` with the following method: * `options` Object * `click` Function - Will be called with `click(menuItem, browserWindow)` when the menu item is clicked - * `role` String - Define the action of the menu item, when specified the + * `role` String - Define the action of the menu item; when specified the `click` property will be ignored * `type` String - Can be `normal`, `separator`, `submenu`, `checkbox` or `radio` @@ -22,21 +22,22 @@ Create a new `MenuItem` with the following method: * `sublabel` String * `accelerator` [Accelerator](accelerator.md) * `icon` [NativeImage](native-image.md) - * `enabled` Boolean - * `visible` Boolean - * `checked` Boolean - * `submenu` Menu - Should be specified for `submenu` type menu item, when - it's specified the `type: 'submenu'` can be omitted for the menu item. - If the value is not a `Menu` then it will be automatically converted to one - using `Menu.buildFromTemplate`. + * `enabled` Boolean - If false, the menu item will be greyed out and unclickable. + * `visible` Boolean - If false, the menu item will be entirely hidden. + * `checked` Boolean - Should only be specified for `checkbox` or `radio` type + menu items. + * `submenu` Menu - Should be specified for `submenu` type menu items. If + `submenu` is specified, the `type: 'submenu'` can be omitted. If the value + is not a `Menu` then it will be automatically converted to one using + `Menu.buildFromTemplate`. * `id` String - Unique within a single menu. If defined then it can be used as a reference to this item by the position attribute. * `position` String - This field allows fine-grained definition of the specific location within a given menu. -When creating menu items, it is recommended to specify `role` instead of -manually implementing the behavior if there is matching action, so menu can have -best native experience. +It is best to specify `role` for any menu item that matches a standard role, +rather than trying to manually implement the behavior in a `click` function. +The built-in `role` behavior will give the best native experience. The `role` property can have following values: @@ -59,3 +60,21 @@ On OS X `role` can also have following additional values: * `window` - The submenu is a "Window" menu * `help` - The submenu is a "Help" menu * `services` - The submenu is a "Services" menu + +## Instance Properties + +The following properties (and no others) can be updated on an existing `MenuItem`: + + * `enabled` Boolean + * `visible` Boolean + * `checked` Boolean + +Their meanings are as described above. + +A `checkbox` menu item will toggle its `checked` property on and off when +selected. You can add a `click` function to do additional work. + +A `radio` menu item will turn on its `checked` property when clicked, and +will turn off that property for all adjacent items in the same menu. Again, +you can add a `click` function for additional behavior. + From f7e5c65802248127faf779a80ed46e0b72494c92 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 31 Mar 2016 14:03:35 +0900 Subject: [PATCH 644/688] :memo: Update Korean docs as upstream [ci skip] --- docs-translations/ko-KR/api/app.md | 27 +++++++++++++++++++ docs-translations/ko-KR/api/auto-updater.md | 3 +++ docs-translations/ko-KR/api/browser-window.md | 10 +++++++ 3 files changed, 40 insertions(+) diff --git a/docs-translations/ko-KR/api/app.md b/docs-translations/ko-KR/api/app.md index 0924e284c31..ff4269ea829 100644 --- a/docs-translations/ko-KR/api/app.md +++ b/docs-translations/ko-KR/api/app.md @@ -366,6 +366,32 @@ npm 모듈 규칙에 따라 대부분의 경우 `package.json`의 `name` 필드 최근 문서 목록을 모두 비웁니다. +### `app.setAsDefaultProtocolClient(protocol)` _OS X_ _Windows_ + +* `protocol` String - 프로토콜의 이름, `://` 제외. 만약 앱을 통해 `electron://`과 + 같은 링크를 처리하고 싶다면, 이 메서드에 `electron` 인수를 담아 호출하면 됩니다. + +이 메서드는 지정한 프로토콜(URI scheme)에 대해 현재 실행파일을 기본 핸들러로 +등록합니다. 이를 통해 운영체제와 더 가깝게 통합할 수 있습니다. 한 번 등록되면, +`your-protocol://`과 같은 모든 링크에 대해 호출시 현재 실행 파일이 실행됩니다. +모든 링크, 프로토콜을 포함하여 어플리케이션의 인수로 전달됩니다. + +**참고:** OS X에선, 어플리케이션의 `info.plist`에 등록해둔 프로토콜만 사용할 수 +있습니다. 이는 런타임에서 변경될 수 없습니다. 이 파일은 간단히 텍스트 에디터를 +사용하거나, 어플리케이션을 빌드할 때 스크립트가 생성되도록 할 수 있습니다. 자세한 +내용은 [Apple의 참조 문서를][CFBundleURLTypes] 확인하세요. + +이 API는 내부적으로 Windows 레지스트리와 LSSetDefaultHandlerForURLScheme를 사용합니다. + +### `app.removeAsDefaultProtocolClient(protocol)` _Windows_ + +* `protocol` String - 프로토콜의 이름, `://` 제외. + +이 메서드는 현재 실행파일이 지정한 프로토콜(URI scheme)에 대해 기본 핸들러인지를 +확인합니다. 만약 그렇다면, 이 메서드는 앱을 기본 핸들러에서 제거합니다. + +**참고:** OS X에서는 앱을 제거하면 자동으로 기본 프로토콜 핸들러에서 제거됩니다. + ### `app.setUserTasks(tasks)` _Windows_ * `tasks` Array - `Task` 객체의 배열 @@ -556,3 +582,4 @@ dock 아이콘의 `image`를 설정합니다. [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx +[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115 diff --git a/docs-translations/ko-KR/api/auto-updater.md b/docs-translations/ko-KR/api/auto-updater.md index 04593ee5760..e5121d0f9b1 100644 --- a/docs-translations/ko-KR/api/auto-updater.md +++ b/docs-translations/ko-KR/api/auto-updater.md @@ -2,6 +2,9 @@ 이 모듈은 `Squirrel` 자동 업데이트 프레임워크의 인터페이스를 제공합니다. +[electron-release-server](https://github.com/ArekSredzki/electron-release-server)를 +포크하면 어플리케이션을 배포하기 위한 멀티 플랫폼 릴리즈 서버를 손쉽게 구축할 수 있습니다. + ## 플랫폼별 참고 사항 `autoUpdater`는 기본적으로 모든 플랫폼에 대해 같은 API를 제공하지만, 여전히 플랫폼별로 diff --git a/docs-translations/ko-KR/api/browser-window.md b/docs-translations/ko-KR/api/browser-window.md index 1ebf7743c2f..06e31e9fba5 100644 --- a/docs-translations/ko-KR/api/browser-window.md +++ b/docs-translations/ko-KR/api/browser-window.md @@ -318,6 +318,16 @@ someWindow.on('app-command', function(e, cmd) { 스크롤 휠 이벤트가 동작을 멈췄을 때 발생하는 이벤트입니다. +### Event: 'swipe' _OS X_ + +Returns: + +* `event` Event +* `direction` String + +3-손가락 스와이프가 작동할 때 발생하는 이벤트입니다. 방향은 `up`, `right`, `down`, +`left`가 될 수 있습니다. + ## Methods `BrowserWindow` 객체는 다음과 같은 메서드를 가지고 있습니다: From 346ef9df0c202dba181ff7099053b09c8013b4e5 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 31 Mar 2016 14:16:14 +0900 Subject: [PATCH 645/688] :memo: Update docs styles * Adjust line length to `80` * Normalize whitespaces [ci skip] --- docs/api/app.md | 18 +++++++++--------- docs/api/auto-updater.md | 4 +++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index 903668c7f2b..8a7cdace3ea 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -356,16 +356,16 @@ Clears the recent documents list. ### `app.setAsDefaultProtocolClient(protocol)` _OS X_ _Windows_ - * `protocol` String - The name of your protocol, without `://`. If you want your - app to handle `electron://` links, call this method with `electron` as the - parameter. - +* `protocol` String - The name of your protocol, without `://`. If you want your + app to handle `electron://` links, call this method with `electron` as the + parameter. + This method sets the current executable as the default handler for a protocol (aka URI scheme). It allows you to integrate your app deeper into the operating system. Once registered, all links with `your-protocol://` will be openend with the current executable. The whole link, including protocol, will be passed to your application as a parameter. - + **Note:** On OS X, you can only register protocols that have been added to your app's `info.plist`, which can not be modified at runtime. You can however change the file with a simple text editor or script during build time. @@ -375,11 +375,11 @@ The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally ### `app.removeAsDefaultProtocolClient(protocol)` _Windows_ - * `protocol` String - The name of your protocol, without `://`. - +* `protocol` String - The name of your protocol, without `://`. + This method checks if the current executable as the default handler for a protocol (aka URI scheme). If so, it will remove the app as the default handler. - + **Note:** On OS X, removing the app will automatically remove the app as the default protocol handler. @@ -576,4 +576,4 @@ Sets the `image` associated with this dock icon. [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx -[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115 \ No newline at end of file +[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115 diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index f82520518c8..5987f1a215e 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -2,7 +2,8 @@ This module provides an interface for the `Squirrel` auto-updater framework. -You can quickly launch a multi-platform release server for distributing your application by forking [electron-release-server](https://github.com/ArekSredzki/electron-release-server). +You can quickly launch a multi-platform release server for distributing your +application by forking [electron-release-server][electron-release-server]. ## Platform notices @@ -101,3 +102,4 @@ should only be called after `update-downloaded` has been emitted. [squirrel-windows]: https://github.com/Squirrel/Squirrel.Windows [installer]: https://github.com/atom/grunt-electron-installer [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx +[electron-release-server]: https://github.com/ArekSredzki/electron-release-server From a648528f43b1923e6a91753e5b0017b3c645c05d Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 31 Mar 2016 14:17:50 +0900 Subject: [PATCH 646/688] :memo: Normailze note markers * Normalize note markers syntax `__` to `**` [ci skip] --- docs/api/tray.md | 2 +- docs/development/setting-up-symbol-server.md | 2 +- docs/tutorial/debugging-main-process.md | 2 +- docs/tutorial/desktop-environment-integration.md | 2 +- docs/tutorial/mac-app-store-submission-guide.md | 4 ++-- docs/tutorial/using-widevine-cdm-plugin.md | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/api/tray.md b/docs/api/tray.md index 22ab9aea5b7..aa972c57cd9 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -75,7 +75,7 @@ labeled as such. Emitted when the tray icon is clicked. -__Note:__ The `bounds` payload is only implemented on OS X and Windows. +**Note:** The `bounds` payload is only implemented on OS X and Windows. ### Event: 'right-click' _OS X_ _Windows_ diff --git a/docs/development/setting-up-symbol-server.md b/docs/development/setting-up-symbol-server.md index 1dc31f7056d..073c752cbf4 100644 --- a/docs/development/setting-up-symbol-server.md +++ b/docs/development/setting-up-symbol-server.md @@ -25,7 +25,7 @@ appropriate cache directory on your machine. The Windbg symbol path is configured with a string value delimited with asterisk characters. To use only the Electron symbol server, add the following entry to -your symbol path (__Note:__ you can replace `c:\code\symbols` with any writable +your symbol path (**Note:** you can replace `c:\code\symbols` with any writable directory on your computer, if you'd prefer a different location for downloaded symbols): diff --git a/docs/tutorial/debugging-main-process.md b/docs/tutorial/debugging-main-process.md index 67f349d9f27..ee7fc4c5fa4 100644 --- a/docs/tutorial/debugging-main-process.md +++ b/docs/tutorial/debugging-main-process.md @@ -19,7 +19,7 @@ Like `--debug` but pauses the script on the first line. ## Use node-inspector for Debugging -__Note:__ Electron doesn't currently work very well +**Note:** Electron doesn't currently work very well with node-inspector, and the main process will crash if you inspect the `process` object under node-inspector's console. diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 04e8066ef72..1186918799b 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -15,7 +15,7 @@ to the user. Electron conveniently allows developers to send notifications with the [HTML5 Notification API](https://notifications.spec.whatwg.org/), using the currently running operating system's native notification APIs to display it. -__Note:__ Since this is an HTML5 API it is only available in the renderer process. +**Note:** Since this is an HTML5 API it is only available in the renderer process. ```javascript var myNotification = new Notification('Title', { diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index e94a4310618..91a10d40eb1 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -4,11 +4,11 @@ Since v0.34.0, Electron allows submitting packaged apps to the Mac App Store (MAS). This guide provides information on: how to submit your app and the limitations of the MAS build. -__Note:__ From v0.36.0 there was a bug preventing GPU process to start after +**Note:** From v0.36.0 there was a bug preventing GPU process to start after the app being sandboxed, so it is recommended to use v0.35.x before this bug gets fixed. You can find more about this in [issue #3871][issue-3871]. -__Note:__ Submitting an app to Mac App Store requires enrolling [Apple Developer +**Note:** Submitting an app to Mac App Store requires enrolling [Apple Developer Program][developer-program], which costs money. ## How to Submit Your App diff --git a/docs/tutorial/using-widevine-cdm-plugin.md b/docs/tutorial/using-widevine-cdm-plugin.md index 630c18ab8e5..fa288bab0ff 100644 --- a/docs/tutorial/using-widevine-cdm-plugin.md +++ b/docs/tutorial/using-widevine-cdm-plugin.md @@ -8,7 +8,7 @@ Electron doesn't ship with the Widevine CDM plugin for license reasons, to get it, you need to install the official Chrome browser first, which should match the architecture and Chrome version of the Electron build you use. -__Note:__ The major version of Chrome browser has to be the same with the Chrome +**Note:** The major version of Chrome browser has to be the same with the Chrome version used by Electron, otherwise the plugin will not work even though `navigator.plugins` would show it has been loaded. @@ -41,7 +41,7 @@ After getting the plugin files, you should pass the `widevinecdmadapter`'s path to Electron with `--widevine-cdm-path` command line switch, and the plugin's version with `--widevine-cdm-version` switch. -__Note:__ Though only the `widevinecdmadapter` binary is passed to Electron, the +**Note:** Though only the `widevinecdmadapter` binary is passed to Electron, the `widevinecdm` binary has to be put aside it. The command line switches have to be passed before the `ready` event of `app` From 546ad643e4cefb9465b0ba41f1b998179d53fd58 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Thu, 31 Mar 2016 14:30:14 +0900 Subject: [PATCH 647/688] :memo: Add missing docs [ci skip] --- docs/api/ipc-renderer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index f17843702b5..46a2331af43 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -69,7 +69,7 @@ hence no functions or prototype chain will be included. The main process handles it by listening for `channel` with `ipcMain` module, and replies by setting `event.returnValue`. -__Note:__ Sending a synchronous message will block the whole renderer process, +**Note:** Sending a synchronous message will block the whole renderer process, unless you know what you are doing you should never use it. ### `ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])` From d4a14bc215340c1a82c405d30ba643cba028e452 Mon Sep 17 00:00:00 2001 From: James Wheare Date: Thu, 31 Mar 2016 08:56:49 +0100 Subject: [PATCH 648/688] Improve app-command docs, list arguments and explain command string --- docs/api/browser-window.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 76343f967b1..e42b2d9bd09 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -301,10 +301,18 @@ Emitted when the window leaves full screen state triggered by html api. ### Event: 'app-command' _Windows_ +Returns: + +* `event` Event +* `command` String + Emitted when an [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx) is invoked. These are typically related to keyboard media keys or browser commands, as well as the "Back" button built into some mice on Windows. +Commands are lowercased with underscores replaced with hyphens and the `APPCOMMAND_` prefix stripped off. +e.g. `APPCOMMAND_BROWSER_BACKWARD` is emitted as `browser-backward`. + ```js someWindow.on('app-command', function(e, cmd) { // Navigate the window back when the user hits their mouse back button From e23faceba05db7dfa82c06d8ee6185ca779d88c9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 31 Mar 2016 17:22:09 +0900 Subject: [PATCH 649/688] docs: Add notes on app.getLocale --- docs/api/app.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/api/app.md b/docs/api/app.md index 903668c7f2b..5df9e83b27a 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -341,6 +341,11 @@ Overrides the current application's name. Returns the current application locale. +**Note:** When distributing your packaged app, you have to also ship the +`locales` folder. + +**Note:** On Windows you have to call it after the `ready` events gets emitted. + ### `app.addRecentDocument(path)` _OS X_ _Windows_ * `path` String @@ -576,4 +581,4 @@ Sets the `image` associated with this dock icon. [dock-menu]:https://developer.apple.com/library/mac/documentation/Carbon/Conceptual/customizing_docktile/concepts/dockconcepts.html#//apple_ref/doc/uid/TP30000986-CH2-TPXREF103 [tasks]:http://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx -[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115 \ No newline at end of file +[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115 From daa09ea9e7d4f8c4a7f52ceaa7eb63f6aaeb2279 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 30 Mar 2016 11:10:43 -0700 Subject: [PATCH 650/688] Remove path for nodeIntgration value of 'disable' --- atom/browser/web_contents_preferences.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index 3939c59b8cd..bcdbd736676 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -97,11 +97,6 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( // Check if we have node integration specified. bool node_integration = true; web_preferences.GetBoolean(options::kNodeIntegration, &node_integration); - // Be compatible with old API of "node-integration" option. - std::string old_token; - if (web_preferences.GetString(options::kNodeIntegration, &old_token) && - old_token != "disable") - node_integration = true; command_line->AppendSwitchASCII(switches::kNodeIntegration, node_integration ? "true" : "false"); From f033f259b4dda91679be0221933a49c011db1f50 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 31 Mar 2016 08:26:11 -0700 Subject: [PATCH 651/688] Only check for nodeIntegration being true --- lib/renderer/init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/renderer/init.js b/lib/renderer/init.js index 45ea2d45654..128963a63cb 100644 --- a/lib/renderer/init.js +++ b/lib/renderer/init.js @@ -84,7 +84,7 @@ if (location.protocol === 'chrome-devtools:') { } } -if (nodeIntegration === 'true' || nodeIntegration === 'all' || nodeIntegration === 'except-iframe' || nodeIntegration === 'manual-enable-iframe') { +if (nodeIntegration === 'true') { // Export node bindings to global. global.require = require; global.module = module; From ae5a6e61c503c0d68715096fff401b07ee4b9447 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 31 Mar 2016 09:54:01 -0700 Subject: [PATCH 652/688] :memo: Add "remote" note to dialog docs Ref #4943 --- docs/api/dialog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 84a22ef692b..9fbc20dd830 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -12,6 +12,12 @@ const dialog = require('electron').dialog; console.log(dialog.showOpenDialog({ properties: [ 'openFile', 'openDirectory', 'multiSelections' ]})); ``` +The Dialog is opened from Electron's main thread. If you want to use the dialog object from a renderer process, remember to access it using the remote: + +```javascript +const dialog = require('electron').remote.dialog; +``` + **Note for OS X**: If you want to present dialogs as sheets, the only thing you have to do is provide a `BrowserWindow` reference in the `browserWindow` parameter. From 7016fbe258cd4b94b64b4ca3a023632f4e08a865 Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 25 Mar 2016 08:47:33 +0530 Subject: [PATCH 653/688] browser: fix disposition value for new-window event --- atom/browser/api/atom_api_web_contents.cc | 6 ++++-- lib/browser/api/browser-window.js | 4 ++-- lib/browser/guest-window-manager.js | 4 ++-- lib/renderer/override.js | 3 ++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index db561708086..bd48cac0157 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -326,10 +326,12 @@ bool WebContents::ShouldCreateWebContents( const GURL& target_url, const std::string& partition_id, content::SessionStorageNamespace* session_storage_namespace) { + auto disposition = (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) + ? "background-tab" : "new-window"; if (type_ == BROWSER_WINDOW) - Emit("-new-window", target_url, frame_name, NEW_FOREGROUND_TAB); + Emit("-new-window", target_url, frame_name, disposition); else - Emit("new-window", target_url, frame_name, NEW_FOREGROUND_TAB); + Emit("new-window", target_url, frame_name, disposition); return false; } diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index 7bbf898dafb..33aea5da4d0 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -21,14 +21,14 @@ BrowserWindow.prototype._init = function () { } // Make new windows requested by links behave like "window.open" - this.webContents.on('-new-window', (event, url, frameName) => { + this.webContents.on('-new-window', (event, url, frameName, disposition) => { var options options = { show: true, width: 800, height: 600 } - return ipcMain.emit('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, options) + return ipcMain.emit('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', event, url, frameName, disposition, options) }) // window.resizeTo(...) diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index bc88337eb06..0426ea51583 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -80,9 +80,9 @@ var createGuest = function (embedder, url, frameName, options) { } // Routed window.open messages. -ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, frameName, options) { +ipcMain.on('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', function (event, url, frameName, disposition, options) { options = mergeBrowserWindowOptions(event.sender, options) - event.sender.emit('new-window', event, url, frameName, 'new-window', options) + event.sender.emit('new-window', event, url, frameName, disposition, options) if ((event.sender.isGuest() && !event.sender.allowPopups) || event.defaultPrevented) { event.returnValue = null } else { diff --git a/lib/renderer/override.js b/lib/renderer/override.js index 07f02566bcc..20c993d0bc5 100644 --- a/lib/renderer/override.js +++ b/lib/renderer/override.js @@ -100,6 +100,7 @@ window.open = function (url, frameName, features) { // TODO remove hyphenated options in both of the following arrays for 1.0 const ints = ['x', 'y', 'width', 'height', 'min-width', 'minWidth', 'max-width', 'maxWidth', 'min-height', 'minHeight', 'max-height', 'maxHeight', 'zoom-factor', 'zoomFactor'] const webPreferences = ['zoom-factor', 'zoomFactor', 'node-integration', 'nodeIntegration', 'preload'] + const disposition = 'new-window' // Make sure to get rid of excessive whitespace in the property name ref1 = features.split(/,\s*/) @@ -146,7 +147,7 @@ window.open = function (url, frameName, features) { options[name] = parseInt(options[name], 10) } } - guestId = ipcRenderer.sendSync('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, options) + guestId = ipcRenderer.sendSync('ATOM_SHELL_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, frameName, disposition, options) if (guestId) { return BrowserWindowProxy.getOrCreate(guestId) } else { From e0fe478ae701c09b0124ff39c525f34b92d6446f Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Thu, 31 Mar 2016 06:28:23 +0530 Subject: [PATCH 654/688] decide early on render initiated window creations --- atom/browser/api/atom_api_app.cc | 48 +++++++++++++++++++++++ atom/browser/api/atom_api_app.h | 21 ++++++++++ atom/browser/api/atom_api_web_contents.cc | 16 ++------ atom/browser/api/atom_api_web_contents.h | 15 +++---- atom/browser/atom_browser_client.cc | 39 ++++++++++++++++++ atom/browser/atom_browser_client.h | 16 ++++++++ 6 files changed, 132 insertions(+), 23 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index ad5b7214ccd..03f2437edd5 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -27,6 +27,7 @@ #include "base/path_service.h" #include "brightray/browser/brightray_paths.h" #include "chrome/common/chrome_paths.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/render_frame_host.h" @@ -275,6 +276,53 @@ void App::SelectClientCertificate( cert_request_info->client_certs[0].get()); } +bool App::CanCreateWindow(const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const GURL& source_origin, + WindowContainerType container_type, + const std::string& frame_name, + const GURL& target_url, + const content::Referrer& referrer, + WindowOpenDisposition disposition, + const blink::WebWindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + content::ResourceContext* context, + int render_process_id, + int opener_render_view_id, + int opener_render_frame_id, + bool* no_javascript_access) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&App::OnCreateWindow, + base::Unretained(this), + target_url, + frame_name, + disposition, + render_process_id, + opener_render_frame_id)); + + return false; +} + +void App::OnCreateWindow(const GURL& target_url, + const std::string& frame_name, + WindowOpenDisposition disposition, + int render_process_id, + int render_frame_id) { + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + content::RenderFrameHost* rfh = + content::RenderFrameHost::FromID(render_process_id, render_frame_id); + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(rfh); + if (web_contents) { + auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents); + api_web_contents->CreateWindow(target_url, frame_name, disposition); + } +} + void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) { Emit("gpu-process-crashed"); } diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 5faf8ebb10e..3cf442c9e6e 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -66,6 +66,22 @@ class App : public AtomBrowserClient::Delegate, content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, scoped_ptr delegate) override; + bool CanCreateWindow(const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const GURL& source_origin, + WindowContainerType container_type, + const std::string& frame_name, + const GURL& target_url, + const content::Referrer& referrer, + WindowOpenDisposition disposition, + const blink::WebWindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + content::ResourceContext* context, + int render_process_id, + int opener_render_view_id, + int opener_render_frame_id, + bool* no_javascript_access) override; // content::GpuDataManagerObserver: void OnGpuProcessCrashed(base::TerminationStatus exit_code) override; @@ -90,6 +106,11 @@ class App : public AtomBrowserClient::Delegate, bool MakeSingleInstance( const ProcessSingleton::NotificationCallback& callback); std::string GetLocale(); + void OnCreateWindow(const GURL& target_url, + const std::string& frame_name, + WindowOpenDisposition disposition, + int render_process_id, + int render_frame_id); #if defined(OS_WIN) bool IsAeroGlassEnabled(); diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index bd48cac0157..115926c8a93 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -316,23 +316,13 @@ bool WebContents::AddMessageToConsole(content::WebContents* source, } } -bool WebContents::ShouldCreateWebContents( - content::WebContents* web_contents, - int32_t route_id, - int32_t main_frame_route_id, - int32_t main_frame_widget_route_id, - WindowContainerType window_container_type, - const std::string& frame_name, - const GURL& target_url, - const std::string& partition_id, - content::SessionStorageNamespace* session_storage_namespace) { - auto disposition = (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) - ? "background-tab" : "new-window"; +void WebContents::CreateWindow(const GURL& target_url, + const std::string& frame_name, + WindowOpenDisposition disposition) { if (type_ == BROWSER_WINDOW) Emit("-new-window", target_url, frame_name, disposition); else Emit("new-window", target_url, frame_name, disposition); - return false; } content::WebContents* WebContents::OpenURLFromTab( diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index b734dc304df..d305172c33d 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -138,6 +138,11 @@ class WebContents : public mate::TrackableObject, const GURL& origin, bool allowed); + // Create window with the given disposition. + void CreateWindow(const GURL& target_url, + const std::string& frame_name, + WindowOpenDisposition disposition); + // Returns the web preferences of current WebContents. v8::Local GetWebPreferences(v8::Isolate* isolate); @@ -165,16 +170,6 @@ class WebContents : public mate::TrackableObject, const base::string16& message, int32_t line_no, const base::string16& source_id) override; - bool ShouldCreateWebContents( - content::WebContents* web_contents, - int32_t route_id, - int32_t main_frame_route_id, - int32_t main_frame_widget_route_id, - WindowContainerType window_container_type, - const std::string& frame_name, - const GURL& target_url, - const std::string& partition_id, - content::SessionStorageNamespace* session_storage_namespace) override; content::WebContents* OpenURLFromTab( content::WebContents* source, const content::OpenURLParams& params) override; diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 63a1ea46b16..ec58777d9c9 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -264,6 +264,45 @@ void AtomBrowserClient::ResourceDispatcherHostCreated() { resource_dispatcher_host_delegate_.get()); } +bool AtomBrowserClient::CanCreateWindow( + const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const GURL& source_origin, + WindowContainerType container_type, + const std::string& frame_name, + const GURL& target_url, + const content::Referrer& referrer, + WindowOpenDisposition disposition, + const blink::WebWindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + content::ResourceContext* context, + int render_process_id, + int opener_render_view_id, + int opener_render_frame_id, + bool* no_javascript_access) { + if (delegate_) { + return delegate_->CanCreateWindow(opener_url, + opener_top_level_frame_url, + source_origin, + container_type, + frame_name, + target_url, + referrer, + disposition, + features, + user_gesture, + opener_suppressed, + context, + render_process_id, + opener_render_view_id, + opener_render_frame_id, + no_javascript_access); + } else { + return false; + } +} + brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( const content::MainFunctionParams&) { v8::V8::Initialize(); // Init V8 before creating main parts. diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index 8f62887ff68..5354e14cc61 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -76,6 +76,22 @@ class AtomBrowserClient : public brightray::BrowserClient, net::SSLCertRequestInfo* cert_request_info, scoped_ptr delegate) override; void ResourceDispatcherHostCreated() override; + bool CanCreateWindow(const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const GURL& source_origin, + WindowContainerType container_type, + const std::string& frame_name, + const GURL& target_url, + const content::Referrer& referrer, + WindowOpenDisposition disposition, + const blink::WebWindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + content::ResourceContext* context, + int render_process_id, + int opener_render_view_id, + int opener_render_frame_id, + bool* no_javascript_access) override; // brightray::BrowserClient: brightray::BrowserMainParts* OverrideCreateBrowserMainParts( From 7e366dd5c8efa75efc29e383f5c6dc726a399ae5 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Thu, 31 Mar 2016 18:37:47 +0530 Subject: [PATCH 655/688] Update libchromiumcontent --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index fb1a4b89f27..83960e68e2c 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -8,7 +8,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = 'b06d4c307b861cdb091f4ba26b1a185333889033' +LIBCHROMIUMCONTENT_COMMIT = 'd41c1e48f428257d99abcf29fd9f26928e9fc53e' PLATFORM = { 'cygwin': 'win32', From e14c91771becf66c5598f108f9f1c3851235a977 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Thu, 31 Mar 2016 19:51:18 +0530 Subject: [PATCH 656/688] removed redundant delegation --- atom/browser/api/atom_api_app.cc | 65 ++++++++--------------------- atom/browser/api/atom_api_app.h | 28 ++++--------- atom/browser/atom_browser_client.cc | 31 ++++++-------- 3 files changed, 37 insertions(+), 87 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 03f2437edd5..de1272e03e8 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -27,7 +27,6 @@ #include "base/path_service.h" #include "brightray/browser/brightray_paths.h" #include "chrome/common/chrome_paths.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/render_frame_host.h" @@ -230,6 +229,23 @@ void App::OnLogin(LoginHandler* login_handler) { login_handler->CancelAuth(); } +void App::OnCreateWindow(const GURL& target_url, + const std::string& frame_name, + WindowOpenDisposition disposition, + int render_process_id, + int render_frame_id) { + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); + content::RenderFrameHost* rfh = + content::RenderFrameHost::FromID(render_process_id, render_frame_id); + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(rfh); + if (web_contents) { + auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents); + api_web_contents->CreateWindow(target_url, frame_name, disposition); + } +} + void App::AllowCertificateError( content::WebContents* web_contents, int cert_error, @@ -276,53 +292,6 @@ void App::SelectClientCertificate( cert_request_info->client_certs[0].get()); } -bool App::CanCreateWindow(const GURL& opener_url, - const GURL& opener_top_level_frame_url, - const GURL& source_origin, - WindowContainerType container_type, - const std::string& frame_name, - const GURL& target_url, - const content::Referrer& referrer, - WindowOpenDisposition disposition, - const blink::WebWindowFeatures& features, - bool user_gesture, - bool opener_suppressed, - content::ResourceContext* context, - int render_process_id, - int opener_render_view_id, - int opener_render_frame_id, - bool* no_javascript_access) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(&App::OnCreateWindow, - base::Unretained(this), - target_url, - frame_name, - disposition, - render_process_id, - opener_render_frame_id)); - - return false; -} - -void App::OnCreateWindow(const GURL& target_url, - const std::string& frame_name, - WindowOpenDisposition disposition, - int render_process_id, - int render_frame_id) { - v8::Locker locker(isolate()); - v8::HandleScope handle_scope(isolate()); - content::RenderFrameHost* rfh = - content::RenderFrameHost::FromID(render_process_id, render_frame_id); - content::WebContents* web_contents = - content::WebContents::FromRenderFrameHost(rfh); - if (web_contents) { - auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents); - api_web_contents->CreateWindow(target_url, frame_name, disposition); - } -} - void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) { Emit("gpu-process-crashed"); } diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 3cf442c9e6e..5025a3869dd 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -34,6 +34,13 @@ class App : public AtomBrowserClient::Delegate, public: static mate::Handle Create(v8::Isolate* isolate); + // Called when window with disposition needs to be created. + void OnCreateWindow(const GURL& target_url, + const std::string& frame_name, + WindowOpenDisposition disposition, + int render_process_id, + int render_frame_id); + protected: App(); virtual ~App(); @@ -66,22 +73,6 @@ class App : public AtomBrowserClient::Delegate, content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, scoped_ptr delegate) override; - bool CanCreateWindow(const GURL& opener_url, - const GURL& opener_top_level_frame_url, - const GURL& source_origin, - WindowContainerType container_type, - const std::string& frame_name, - const GURL& target_url, - const content::Referrer& referrer, - WindowOpenDisposition disposition, - const blink::WebWindowFeatures& features, - bool user_gesture, - bool opener_suppressed, - content::ResourceContext* context, - int render_process_id, - int opener_render_view_id, - int opener_render_frame_id, - bool* no_javascript_access) override; // content::GpuDataManagerObserver: void OnGpuProcessCrashed(base::TerminationStatus exit_code) override; @@ -106,11 +97,6 @@ class App : public AtomBrowserClient::Delegate, bool MakeSingleInstance( const ProcessSingleton::NotificationCallback& callback); std::string GetLocale(); - void OnCreateWindow(const GURL& target_url, - const std::string& frame_name, - WindowOpenDisposition disposition, - int render_process_id, - int render_frame_id); #if defined(OS_WIN) bool IsAeroGlassEnabled(); diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index ec58777d9c9..9a59c3f9d41 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -8,6 +8,7 @@ #include #endif +#include "atom/browser/api/atom_api_app.h" #include "atom/browser/atom_access_token_store.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" @@ -281,26 +282,20 @@ bool AtomBrowserClient::CanCreateWindow( int opener_render_view_id, int opener_render_frame_id, bool* no_javascript_access) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (delegate_) { - return delegate_->CanCreateWindow(opener_url, - opener_top_level_frame_url, - source_origin, - container_type, - frame_name, - target_url, - referrer, - disposition, - features, - user_gesture, - opener_suppressed, - context, - render_process_id, - opener_render_view_id, - opener_render_frame_id, - no_javascript_access); - } else { - return false; + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&api::App::OnCreateWindow, + base::Unretained(static_cast(delegate_)), + target_url, + frame_name, + disposition, + render_process_id, + opener_render_frame_id)); } + + return false; } brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( From f36851fcffc5cf2e0415f618961ec2e740a830bc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 1 Apr 2016 14:50:33 +0900 Subject: [PATCH 657/688] spec: Remote object should be referenced by its members --- spec/api-ipc-spec.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index be4f788fb0d..da4acf887e4 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -73,6 +73,12 @@ describe('ipc module', function () { assert.equal(delete remoteFunctions.aFunction, true) }) + + it('is referenced by its members', function () { + let stringify = remote.getGlobal('JSON').stringify + gc(); + stringify({}) + }); }) describe('remote value in browser', function () { From 4ebb01f8c9642103276d7e88bb81fcabc0a656f8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 1 Apr 2016 15:26:30 +0900 Subject: [PATCH 658/688] Remote object's members should reference itself --- lib/renderer/api/remote.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index 5f60a970ff3..30341c0f77b 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -109,9 +109,16 @@ let setObjectMembers = function (object, metaId, members) { return metaToValue(ret) } } - descriptor.writable = true + descriptor.get = function () { + remoteMemberFunction.ref = object // The member should reference its object. + return remoteMemberFunction + } + // Enable monkey-patch the method + descriptor.set = function (value) { + remoteMemberFunction = value + return value + } descriptor.configurable = true - descriptor.value = remoteMemberFunction } else if (member.type === 'get') { descriptor.get = function () { return metaToValue(ipcRenderer.sendSync('ATOM_BROWSER_MEMBER_GET', metaId, member.name)) From b9ead472a55719c3e6fd295df9b165450c44642d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 1 Apr 2016 15:35:34 +0900 Subject: [PATCH 659/688] spec: Remote object should be referenced by methods in its prototype chain --- spec/api-ipc-spec.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/api-ipc-spec.js b/spec/api-ipc-spec.js index da4acf887e4..c98689287ce 100644 --- a/spec/api-ipc-spec.js +++ b/spec/api-ipc-spec.js @@ -149,6 +149,13 @@ describe('ipc module', function () { assert(!proto.hasOwnProperty('method')) assert(Object.getPrototypeOf(proto).hasOwnProperty('method')) }) + + it('is referenced by methods in prototype chain', function () { + let method = derived.method + derived = null + gc() + assert.equal(method(), 'method') + }); }) describe('ipc.sender.send', function () { From 39d2b95a33c72321bd5418030daa9392366df527 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 1 Apr 2016 15:45:36 +0900 Subject: [PATCH 660/688] Reference the remote object in its prototype chain's methods --- lib/renderer/api/remote.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index 30341c0f77b..30b66983a7d 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -91,8 +91,9 @@ var wrapArgs = function (args, visited) { } // Populate object's members from descriptors. +// The |ref| will be kept referenced by |members|. // This matches |getObjectMemebers| in rpc-server. -let setObjectMembers = function (object, metaId, members) { +let setObjectMembers = function (ref, object, metaId, members) { for (let member of members) { if (object.hasOwnProperty(member.name)) continue @@ -110,7 +111,7 @@ let setObjectMembers = function (object, metaId, members) { } } descriptor.get = function () { - remoteMemberFunction.ref = object // The member should reference its object. + remoteMemberFunction.ref = ref // The member should reference its object. return remoteMemberFunction } // Enable monkey-patch the method @@ -139,11 +140,11 @@ let setObjectMembers = function (object, metaId, members) { // Populate object's prototype from descriptor. // This matches |getObjectPrototype| in rpc-server. -let setObjectPrototype = function (object, metaId, descriptor) { +let setObjectPrototype = function (ref, object, metaId, descriptor) { if (descriptor === null) return let proto = {} - setObjectMembers(proto, metaId, descriptor.members) - setObjectPrototype(proto, metaId, descriptor.proto) + setObjectMembers(ref, proto, metaId, descriptor.members) + setObjectPrototype(ref, proto, metaId, descriptor.proto) Object.setPrototypeOf(object, proto) } @@ -198,9 +199,9 @@ let metaToValue = function (meta) { } // Populate delegate members. - setObjectMembers(ret, meta.id, meta.members) + setObjectMembers(ret, ret, meta.id, meta.members) // Populate delegate prototype. - setObjectPrototype(ret, meta.id, meta.proto) + setObjectPrototype(ret, ret, meta.id, meta.proto) // Set constructor.name to object's name. Object.defineProperty(ret.constructor, 'name', { value: meta.name }) From 576b54320a1baa202f8d0f448dd7e18ecd216144 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 1 Apr 2016 16:34:20 +0900 Subject: [PATCH 661/688] Fix compilation errors on Windows --- atom/browser/api/atom_api_app.cc | 2 +- atom/browser/api/atom_api_web_contents.cc | 6 +++--- atom/browser/api/atom_api_web_contents.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index de1272e03e8..52d6ec3d338 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -242,7 +242,7 @@ void App::OnCreateWindow(const GURL& target_url, content::WebContents::FromRenderFrameHost(rfh); if (web_contents) { auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents); - api_web_contents->CreateWindow(target_url, frame_name, disposition); + api_web_contents->OnCreateWindow(target_url, frame_name, disposition); } } diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 115926c8a93..8c0f7d571f3 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -316,9 +316,9 @@ bool WebContents::AddMessageToConsole(content::WebContents* source, } } -void WebContents::CreateWindow(const GURL& target_url, - const std::string& frame_name, - WindowOpenDisposition disposition) { +void WebContents::OnCreateWindow(const GURL& target_url, + const std::string& frame_name, + WindowOpenDisposition disposition) { if (type_ == BROWSER_WINDOW) Emit("-new-window", target_url, frame_name, disposition); else diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index d305172c33d..5fb1947f579 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -139,9 +139,9 @@ class WebContents : public mate::TrackableObject, bool allowed); // Create window with the given disposition. - void CreateWindow(const GURL& target_url, - const std::string& frame_name, - WindowOpenDisposition disposition); + void OnCreateWindow(const GURL& target_url, + const std::string& frame_name, + WindowOpenDisposition disposition); // Returns the web preferences of current WebContents. v8::Local GetWebPreferences(v8::Isolate* isolate); From 247b3f36057ed3465bac646b607a5205ce94914f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 1 Apr 2016 16:35:19 +0900 Subject: [PATCH 662/688] Fix the background color in test app --- spec/static/index.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/static/index.html b/spec/static/index.html index e31fcffebb8..3c57f94d144 100644 --- a/spec/static/index.html +++ b/spec/static/index.html @@ -3,6 +3,11 @@ + From b35f4c1805db66f5add4fb6a35bf90285cf80a2f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 1 Apr 2016 16:42:44 +0900 Subject: [PATCH 663/688] spec: Fix failing test due to path delimiter --- spec/chromium-spec.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index b6e9a775ed0..27660156e32 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -199,7 +199,10 @@ describe('chromium feature', function () { it('defines a window.location getter', function (done) { var b, targetURL - targetURL = 'file://' + fixtures + '/pages/base-page.html' + if (process.platform == 'win32') + targetURL = 'file:///' + fixtures.replace(/\\/g, '/') + '/pages/base-page.html' + else + targetURL = 'file://' + fixtures + '/pages/base-page.html' b = window.open(targetURL) BrowserWindow.fromId(b.guestId).webContents.once('did-finish-load', function () { assert.equal(b.location, targetURL) From 464dad31354cb633c77f085bf0ebb7910eaa11bf Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 30 Mar 2016 11:50:17 -0700 Subject: [PATCH 664/688] Store default_app in .asar archive --- atom.gyp | 51 +++++++++++++++++++++++++++++---------------- filenames.gypi | 6 ++++++ lib/browser/init.js | 2 +- tools/js2asar.py | 18 ++++++++-------- 4 files changed, 49 insertions(+), 28 deletions(-) diff --git a/atom.gyp b/atom.gyp index bfcfb39bab1..501cc3ab777 100644 --- a/atom.gyp +++ b/atom.gyp @@ -29,6 +29,7 @@ 'type': 'executable', 'dependencies': [ 'js2asar', + 'app2asar', '<(project_name)_lib', ], 'sources': [ @@ -66,12 +67,6 @@ '<(PRODUCT_DIR)/<(product_name) Framework.framework', ], }, - { - 'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Resources', - 'files': [ - 'default_app', - ], - }, ], 'postbuilds': [ { @@ -167,12 +162,6 @@ 'external_binaries/vccorlib120.dll', ], }, - { - 'destination': '<(PRODUCT_DIR)/resources', - 'files': [ - 'default_app', - ] - }, ], }, { 'dependencies': [ @@ -208,12 +197,6 @@ '<(libchromiumcontent_dir)/snapshot_blob.bin', ], }, - { - 'destination': '<(PRODUCT_DIR)/resources', - 'files': [ - 'default_app', - ] - }, ], }], # OS=="linux" ], @@ -376,11 +359,43 @@ 'python', 'tools/js2asar.py', '<@(_outputs)', + 'lib', '<@(_inputs)', ], } ], }, # target js2asar + { + 'target_name': 'app2asar', + 'type': 'none', + 'actions': [ + { + 'action_name': 'app2asar', + 'variables': { + 'conditions': [ + ['OS=="mac"', { + 'resources_path': '<(PRODUCT_DIR)/<(product_name).app/Contents/Resources', + },{ + 'resources_path': '<(PRODUCT_DIR)/resources', + }], + ], + }, + 'inputs': [ + '<@(default_app_sources)', + ], + 'outputs': [ + '<(resources_path)/default_app.asar', + ], + 'action': [ + 'python', + 'tools/js2asar.py', + '<@(_outputs)', + 'default_app', + '<@(_inputs)', + ], + } + ], + }, # target app2asar { 'target_name': 'atom_js2c', 'type': 'none', diff --git a/filenames.gypi b/filenames.gypi index baf0202f3ec..97c2c0e6c52 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -67,6 +67,12 @@ 'lib/common/asar.js', 'lib/common/asar_init.js', ], + 'default_app_sources': [ + 'default_app/default_app.js', + 'default_app/index.html', + 'default_app/main.js', + 'default_app/package.json', + ], 'lib_sources': [ 'atom/app/atom_content_client.cc', 'atom/app/atom_content_client.h', diff --git a/lib/browser/init.js b/lib/browser/init.js index d04b174adb6..fc4f90c399b 100644 --- a/lib/browser/init.js +++ b/lib/browser/init.js @@ -117,7 +117,7 @@ require('./guest-window-manager') // Now we try to load app's package.json. var packageJson = null -var searchPaths = ['app', 'app.asar', 'default_app'] +var searchPaths = ['app', 'app.asar', 'default_app.asar'] var i, len, packagePath for (i = 0, len = searchPaths.length; i < len; i++) { packagePath = searchPaths[i] diff --git a/tools/js2asar.py b/tools/js2asar.py index cb02e33de65..fe33edbba74 100755 --- a/tools/js2asar.py +++ b/tools/js2asar.py @@ -12,26 +12,26 @@ SOURCE_ROOT = os.path.dirname(os.path.dirname(__file__)) def main(): archive = sys.argv[1] - js_source_files = sys.argv[2:] + folder_name = sys.argv[2] + source_files = sys.argv[3:] output_dir = tempfile.mkdtemp() - copy_js(js_source_files, output_dir) - call_asar(archive, output_dir) + copy_files(source_files, output_dir) + call_asar(archive, os.path.join(output_dir, folder_name)) shutil.rmtree(output_dir) -def copy_js(js_source_files, output_dir): - for source_file in js_source_files: - output_filename = os.path.splitext(source_file)[0] + '.js' - output_path = os.path.join(output_dir, output_filename) +def copy_files(source_files, output_dir): + for source_file in source_files: + output_path = os.path.join(output_dir, source_file) safe_mkdir(os.path.dirname(output_path)) shutil.copy2(source_file, output_path) def call_asar(archive, output_dir): - js_dir = os.path.join(output_dir, 'lib') + print(output_dir) asar = os.path.join(SOURCE_ROOT, 'node_modules', 'asar', 'bin', 'asar') - subprocess.check_call([find_node(), asar, 'pack', js_dir, archive]) + subprocess.check_call([find_node(), asar, 'pack', output_dir, archive]) def find_node(): From 5221154653eaee8f0ff573dcb502235af3b02455 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 30 Mar 2016 11:53:14 -0700 Subject: [PATCH 665/688] Remove logging --- tools/js2asar.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/js2asar.py b/tools/js2asar.py index fe33edbba74..7860176c93c 100755 --- a/tools/js2asar.py +++ b/tools/js2asar.py @@ -29,7 +29,6 @@ def copy_files(source_files, output_dir): def call_asar(archive, output_dir): - print(output_dir) asar = os.path.join(SOURCE_ROOT, 'node_modules', 'asar', 'bin', 'asar') subprocess.check_call([find_node(), asar, 'pack', output_dir, archive]) From 400efa1b7dc6f44ce8252d1603ca8a9405454269 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 31 Mar 2016 09:07:56 -0700 Subject: [PATCH 666/688] Fallback to using the last argument as the callback --- lib/browser/api/dialog.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 378822c6fb3..6669d8cab89 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -20,18 +20,25 @@ var messageBoxOptions = { noLink: 1 << 0 } -var parseArgs = function (window, options, callback) { +var parseArgs = function (window, options, callback, ...args) { if (!(window === null || (window != null ? window.constructor : void 0) === BrowserWindow)) { // Shift. callback = options options = window window = null } + if ((callback == null) && typeof options === 'function') { // Shift. callback = options options = null } + + // Fallback to using very last argument as the callback function + if ((callback == null) && typeof args[args.length - 1] === 'function') { + callback = args[args.length - 1] + } + return [window, options, callback] } From 2853356b10f0d6946c330eabe5cf26e4be04113e Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 1 Apr 2016 15:48:12 -0700 Subject: [PATCH 667/688] use alt, not option --- docs/api/accelerator.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/api/accelerator.md b/docs/api/accelerator.md index 93d1f244c6b..f952d0b1ba8 100644 --- a/docs/api/accelerator.md +++ b/docs/api/accelerator.md @@ -14,6 +14,9 @@ On Linux and Windows, the `Command` key does not have any effect so use `CommandOrControl` which represents `Command` on OS X and `Control` on Linux and Windows to define some accelerators. +Use `Alt` instead of `Option`. The `Option` key only exists on OS X, whereas +the `Alt` key is available on all platforms. + The `Super` key is mapped to the `Windows` key on Windows and Linux and `Cmd` on OS X. From c036986cc49c5dc79b3651881ffc1f53eeff09e6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 31 Mar 2016 09:23:04 -0700 Subject: [PATCH 668/688] atom.gyp -> electron.gyp --- atom.gyp => electron.gyp | 0 script/bump-version.py | 4 ++-- script/lib/util.py | 2 +- script/update.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename atom.gyp => electron.gyp (100%) diff --git a/atom.gyp b/electron.gyp similarity index 100% rename from atom.gyp rename to electron.gyp diff --git a/script/bump-version.py b/script/bump-version.py index e2c22e8cd9d..5c70d4494e8 100755 --- a/script/bump-version.py +++ b/script/bump-version.py @@ -44,13 +44,13 @@ def increase_version(versions, index): def update_atom_gyp(version): pattern = re.compile(" *'version%' *: *'[0-9.]+'") - with open('atom.gyp', 'r') as f: + with open('electron.gyp', 'r') as f: lines = f.readlines() for i in range(0, len(lines)): if pattern.match(lines[i]): lines[i] = " 'version%': '{0}',\n".format(version) - with open('atom.gyp', 'w') as f: + with open('electron.gyp', 'w') as f: f.write(''.join(lines)) return diff --git a/script/lib/util.py b/script/lib/util.py index fc52d316d30..4e5fb90988d 100644 --- a/script/lib/util.py +++ b/script/lib/util.py @@ -180,7 +180,7 @@ def execute_stdout(argv, env=os.environ): def atom_gyp(): SOURCE_ROOT = os.path.abspath(os.path.join(__file__, '..', '..', '..')) - gyp = os.path.join(SOURCE_ROOT, 'atom.gyp') + gyp = os.path.join(SOURCE_ROOT, 'electron.gyp') with open(gyp) as f: obj = eval(f.read()); return obj['variables'] diff --git a/script/update.py b/script/update.py index e91e8401cbf..33a4cff50f6 100755 --- a/script/update.py +++ b/script/update.py @@ -68,7 +68,7 @@ def run_gyp(target_arch, component): '-Dmas_build={0}'.format(mas_build), ] return subprocess.call([python, gyp, '-f', 'ninja', '--depth', '.', - 'atom.gyp', '-Icommon.gypi'] + defines, env=env) + 'electron.gyp', '-Icommon.gypi'] + defines, env=env) if __name__ == '__main__': From ce95747a255775574e6bbabdfd45ca343e35081e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 31 Mar 2016 09:26:11 -0700 Subject: [PATCH 669/688] atom.asar -> electron.asar --- atom/common/node_bindings.cc | 2 +- electron.gyp | 4 ++-- lib/common/api/callbacks-registry.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index b0b4148c7ba..ce3b9a70815 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -161,7 +161,7 @@ node::Environment* NodeBindings::CreateEnvironment( FILE_PATH_LITERAL("browser") : FILE_PATH_LITERAL("renderer"); base::FilePath resources_path = GetResourcesPath(is_browser_); base::FilePath script_path = - resources_path.Append(FILE_PATH_LITERAL("atom.asar")) + resources_path.Append(FILE_PATH_LITERAL("electron.asar")) .Append(process_type) .Append(FILE_PATH_LITERAL("init.js")); std::string script_path_str = script_path.AsUTF8Unsafe(); diff --git a/electron.gyp b/electron.gyp index 501cc3ab777..9652bd662c7 100644 --- a/electron.gyp +++ b/electron.gyp @@ -87,7 +87,7 @@ }, # The application doesn't have real localizations, it just has # empty .lproj directories, which is enough to convince Cocoa - # atom-shell supports those languages. + # that Electron supports those languages. { 'postbuild_name': 'Make Empty Localizations', 'variables': { @@ -353,7 +353,7 @@ '<@(js_sources)', ], 'outputs': [ - '<(resources_path)/atom.asar', + '<(resources_path)/electron.asar', ], 'action': [ 'python', diff --git a/lib/common/api/callbacks-registry.js b/lib/common/api/callbacks-registry.js index 3e71899df29..7a9bf534f72 100644 --- a/lib/common/api/callbacks-registry.js +++ b/lib/common/api/callbacks-registry.js @@ -26,7 +26,7 @@ class CallbacksRegistry { if (location.indexOf('(native)') !== -1) { continue } - if (location.indexOf('atom.asar') !== -1) { + if (location.indexOf('electron.asar') !== -1) { continue } ref = /([^\/^\)]*)\)?$/gi.exec(location) From ee9128268eb1a83d457146d214dd4d7cb436604d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 31 Mar 2016 14:07:28 -0700 Subject: [PATCH 670/688] Rename atom.icns to electron.icns --- atom/browser/resources/mac/Info.plist | 2 +- .../resources/mac/{atom.icns => electron.icns} | Bin filenames.gypi | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename atom/browser/resources/mac/{atom.icns => electron.icns} (100%) diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index f7bd068e8f4..e2afa33f7df 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleIconFile - atom.icns + electron.icns CFBundleVersion 0.37.3 CFBundleShortVersionString diff --git a/atom/browser/resources/mac/atom.icns b/atom/browser/resources/mac/electron.icns similarity index 100% rename from atom/browser/resources/mac/atom.icns rename to atom/browser/resources/mac/electron.icns diff --git a/filenames.gypi b/filenames.gypi index 97c2c0e6c52..2c39a8dccef 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -5,7 +5,7 @@ 'atom/app/atom_main.h', ], 'bundle_sources': [ - 'atom/browser/resources/mac/atom.icns', + 'atom/browser/resources/mac/electron.icns', ], 'js_sources': [ 'lib/browser/api/app.js', From 3c96d7b72651d21dccd43c70bdf2bb70d50a2650 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 31 Mar 2016 15:46:41 -0700 Subject: [PATCH 671/688] Rename atom.asar to electron.asar in specs --- spec/asar-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/asar-spec.js b/spec/asar-spec.js index 45c4c119ca9..a0cb7b4aabd 100644 --- a/spec/asar-spec.js +++ b/spec/asar-spec.js @@ -17,7 +17,7 @@ describe('asar package', function () { it('does not leak fd', function () { var readCalls = 1 while (readCalls <= 10000) { - fs.readFileSync(path.join(process.resourcesPath, 'atom.asar', 'renderer', 'api', 'ipc.js')) + fs.readFileSync(path.join(process.resourcesPath, 'electron.asar', 'renderer', 'api', 'ipc.js')) readCalls++ } }) From 777704e6593e9fca4b34fc1d3d405eda5df07167 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 23 Mar 2016 16:53:20 -0700 Subject: [PATCH 672/688] Add failing spec for nodeIntegration inheritance --- spec/chromium-spec.js | 21 +++++++++++++++++++ .../window-opener-no-node-integration.html | 15 +++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 spec/fixtures/pages/window-opener-no-node-integration.html diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 27660156e32..bb76cfb2a8e 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -182,6 +182,27 @@ describe('chromium feature', function () { b = window.open('file://' + fixtures + '/pages/window-open-size.html', '', 'show=no') }) + it('disables node integration when it is disabled on the parent window', function (done) { + var b + listener = function (event) { + assert.equal(event.data, 'undefined') + b.close() + done() + } + window.addEventListener('message', listener) + + var windowUrl = require('url').format({ + pathname: fixtures + "/pages/window-opener-no-node-integration.html", + protocol: 'file', + query: { + p: fixtures + "/pages/window-opener-node.html" + }, + slashes: true + }) + console.log(windowUrl) + b = window.open(windowUrl, 'nodeIntegration=no,show=no') + }) + it('does not override child options', function (done) { var b, size size = { diff --git a/spec/fixtures/pages/window-opener-no-node-integration.html b/spec/fixtures/pages/window-opener-no-node-integration.html new file mode 100644 index 00000000000..e146a2804ae --- /dev/null +++ b/spec/fixtures/pages/window-opener-no-node-integration.html @@ -0,0 +1,15 @@ + + + + + From 463e077c3af77f47312ec736206d886e9089a47c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 23 Mar 2016 17:36:26 -0700 Subject: [PATCH 673/688] Disable node on child when disabled on parent --- lib/browser/guest-window-manager.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index 0426ea51583..467e819fa82 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -28,6 +28,11 @@ var mergeBrowserWindowOptions = function (embedder, options) { if (embedder.browserWindowOptions != null) { // Inherit the original options if it is a BrowserWindow. mergeOptions(options, embedder.browserWindowOptions) + + // Disable node integration on child window if disabled on parent window + if (!embedder.browserWindowOptions.webPreferences.nodeIntegration) { + options.webPreferences.nodeIntegration = false + } } else { // Or only inherit web-preferences if it is a webview. if (options.webPreferences == null) { From 2713580d09aacee4fa352dbab26ee55781bdee01 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 23 Mar 2016 17:38:30 -0700 Subject: [PATCH 674/688] Remove stray log --- spec/chromium-spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index bb76cfb2a8e..9a2ba80fb07 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -199,7 +199,6 @@ describe('chromium feature', function () { }, slashes: true }) - console.log(windowUrl) b = window.open(windowUrl, 'nodeIntegration=no,show=no') }) From d7b1792503753fde417f47772e6d21ebd97f512f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 23 Mar 2016 17:40:25 -0700 Subject: [PATCH 675/688] Use template strings --- spec/chromium-spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 9a2ba80fb07..507101dc93b 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -192,10 +192,10 @@ describe('chromium feature', function () { window.addEventListener('message', listener) var windowUrl = require('url').format({ - pathname: fixtures + "/pages/window-opener-no-node-integration.html", + pathname: `${fixtures}/pages/window-opener-no-node-integration.html`, protocol: 'file', query: { - p: fixtures + "/pages/window-opener-node.html" + p: `${fixtures}/pages/window-opener-node.html` }, slashes: true }) From 9e66df23d0bbee093d7b32327cb6bf5e044d394c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 24 Mar 2016 12:29:54 -0700 Subject: [PATCH 676/688] Add clearer assertion of process being undefined --- spec/chromium-spec.js | 4 ++-- spec/fixtures/pages/window-opener-node.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 507101dc93b..aa4e5c5fdaf 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -160,7 +160,7 @@ describe('chromium feature', function () { it('accepts "nodeIntegration" as feature', function (done) { var b listener = function (event) { - assert.equal(event.data, 'undefined') + assert.equal(event.data.isProcessGlobalUndefined, true) b.close() done() } @@ -185,7 +185,7 @@ describe('chromium feature', function () { it('disables node integration when it is disabled on the parent window', function (done) { var b listener = function (event) { - assert.equal(event.data, 'undefined') + assert.equal(event.data.isProcessGlobalUndefined, true) b.close() done() } diff --git a/spec/fixtures/pages/window-opener-node.html b/spec/fixtures/pages/window-opener-node.html index 118603c82d3..13036072876 100644 --- a/spec/fixtures/pages/window-opener-node.html +++ b/spec/fixtures/pages/window-opener-node.html @@ -1,7 +1,7 @@ From dbe1c1d4e42ef87bd87090db05eb42ad2499fd71 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 24 Mar 2016 13:22:13 -0700 Subject: [PATCH 677/688] Check nodeIntegration on embedder's webPreferences --- lib/browser/guest-window-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index 467e819fa82..f27bb8329fa 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -30,7 +30,7 @@ var mergeBrowserWindowOptions = function (embedder, options) { mergeOptions(options, embedder.browserWindowOptions) // Disable node integration on child window if disabled on parent window - if (!embedder.browserWindowOptions.webPreferences.nodeIntegration) { + if (!embedder.getWebPreferences().nodeIntegration) { options.webPreferences.nodeIntegration = false } } else { From e5164d2255d82cd8a33e7ce91a28d5e2f5df96e3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 24 Mar 2016 13:27:03 -0700 Subject: [PATCH 678/688] Check of nodeIntegration is strictly equal to false --- lib/browser/guest-window-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index f27bb8329fa..5782670ac63 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -30,7 +30,7 @@ var mergeBrowserWindowOptions = function (embedder, options) { mergeOptions(options, embedder.browserWindowOptions) // Disable node integration on child window if disabled on parent window - if (!embedder.getWebPreferences().nodeIntegration) { + if (embedder.getWebPreferences().nodeIntegration === false) { options.webPreferences.nodeIntegration = false } } else { From 4890734f66fc358c004a719d39ac247ae2327b33 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 24 Mar 2016 14:12:46 -0700 Subject: [PATCH 679/688] Add missing title param --- spec/chromium-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index aa4e5c5fdaf..1d37d0fe051 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -199,7 +199,7 @@ describe('chromium feature', function () { }, slashes: true }) - b = window.open(windowUrl, 'nodeIntegration=no,show=no') + b = window.open(windowUrl, '', 'nodeIntegration=no,show=no') }) it('does not override child options', function (done) { From fd12e1f50653df17eb6fd6d5918c2bca1138eb1f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 30 Mar 2016 10:33:15 -0700 Subject: [PATCH 680/688] Add failing spec for webview nodeIntegration inheritance --- .../webview-opener-no-node-integration.html | 9 ++++++ spec/webview-spec.js | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 spec/fixtures/pages/webview-opener-no-node-integration.html diff --git a/spec/fixtures/pages/webview-opener-no-node-integration.html b/spec/fixtures/pages/webview-opener-no-node-integration.html new file mode 100644 index 00000000000..cd95f9bb9fb --- /dev/null +++ b/spec/fixtures/pages/webview-opener-no-node-integration.html @@ -0,0 +1,9 @@ + + + + + diff --git a/spec/webview-spec.js b/spec/webview-spec.js index e5116293563..3d45d51e6ac 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -3,6 +3,9 @@ const path = require('path') const http = require('http') const url = require('url') +const {remote} = require('electron') +const {BrowserWindow} = remote + describe(' tag', function () { this.timeout(10000) @@ -74,6 +77,32 @@ describe(' tag', function () { document.body.appendChild(webview) }) + + it('disables node integration on child windows when it is disabled on the webview', function (done) { + webview.addEventListener('console-message', function (e) { + assert.equal(e.message, 'window opened') + const sourceId = remote.getCurrentWindow().id + const windows = BrowserWindow.getAllWindows().filter(function (window) { + return window.id !== sourceId + }) + assert.equal(windows.length, 1) + assert.equal(windows[0].webContents.getWebPreferences().nodeIntegration, false) + done() + }) + + webview.setAttribute('allowpopups', 'on') + + webview.src = require('url').format({ + pathname: `${fixtures}/pages/webview-opener-no-node-integration.html`, + protocol: 'file', + query: { + p: `${fixtures}/pages/window-opener-node.html` + }, + slashes: true + }) + document.body.appendChild(webview) + }) + if (process.platform !== 'win32' || process.execPath.toLowerCase().indexOf('\\out\\d\\') === -1) { it('loads native modules when navigation happens', function (done) { var listener = function () { From eafe9c245b6b8c74fb1e49b0a458f546696176d3 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 30 Mar 2016 10:51:56 -0700 Subject: [PATCH 681/688] Disable guest node integration when embedder has it disabled --- lib/browser/guest-window-manager.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/browser/guest-window-manager.js b/lib/browser/guest-window-manager.js index 5782670ac63..7508b6f16a2 100644 --- a/lib/browser/guest-window-manager.js +++ b/lib/browser/guest-window-manager.js @@ -28,11 +28,6 @@ var mergeBrowserWindowOptions = function (embedder, options) { if (embedder.browserWindowOptions != null) { // Inherit the original options if it is a BrowserWindow. mergeOptions(options, embedder.browserWindowOptions) - - // Disable node integration on child window if disabled on parent window - if (embedder.getWebPreferences().nodeIntegration === false) { - options.webPreferences.nodeIntegration = false - } } else { // Or only inherit web-preferences if it is a webview. if (options.webPreferences == null) { @@ -40,6 +35,12 @@ var mergeBrowserWindowOptions = function (embedder, options) { } mergeOptions(options.webPreferences, embedder.getWebPreferences()) } + + // Disable node integration on child window if disabled on parent window + if (embedder.getWebPreferences().nodeIntegration === false) { + options.webPreferences.nodeIntegration = false + } + return options } From 55b12c184b1c3c4b2d5d32a8944d7234d88e709a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 30 Mar 2016 10:55:16 -0700 Subject: [PATCH 682/688] Doc node integration inheritance --- docs/api/web-view-tag.md | 3 +++ docs/api/window-open.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index ff9013023c1..47e23dc9943 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -84,6 +84,9 @@ than the minimum values or greater than the maximum. If "on", the guest page in `webview` will have node integration and can use node APIs like `require` and `process` to access low level system resources. +**Note:** Node integration will always be disabled in the `webview` if it is +disabled on the parent window. + ### `plugins` ```html diff --git a/docs/api/window-open.md b/docs/api/window-open.md index 5d298e61e75..46e74327741 100644 --- a/docs/api/window-open.md +++ b/docs/api/window-open.md @@ -23,6 +23,9 @@ Creates a new window and returns an instance of `BrowserWindowProxy` class. The `features` string follows the format of standard browser, but each feature has to be a field of `BrowserWindow`'s options. +**Note:** Node integration will always be disabled in the opened `window` if it +is disabled on the parent window. + ### `window.opener.postMessage(message, targetOrigin)` * `message` String From ef2a28ca8643a88546f42fb39d4851f7a421f90d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 30 Mar 2016 11:17:24 -0700 Subject: [PATCH 683/688] Listen for browser-window-created event for asserts --- spec/webview-spec.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 3d45d51e6ac..122c22ad289 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -4,7 +4,7 @@ const http = require('http') const url = require('url') const {remote} = require('electron') -const {BrowserWindow} = remote +const {app} = remote describe(' tag', function () { this.timeout(10000) @@ -79,14 +79,8 @@ describe(' tag', function () { it('disables node integration on child windows when it is disabled on the webview', function (done) { - webview.addEventListener('console-message', function (e) { - assert.equal(e.message, 'window opened') - const sourceId = remote.getCurrentWindow().id - const windows = BrowserWindow.getAllWindows().filter(function (window) { - return window.id !== sourceId - }) - assert.equal(windows.length, 1) - assert.equal(windows[0].webContents.getWebPreferences().nodeIntegration, false) + app.once('browser-window-created', function (event, window) { + assert.equal(window.webContents.getWebPreferences().nodeIntegration, false) done() }) From 230ed78dd677204d03c5b278690ab23825f2e1b9 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 30 Mar 2016 11:56:31 -0700 Subject: [PATCH 684/688] Remove lint warnings --- spec/webview-spec.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 122c22ad289..e47c7182883 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -2,9 +2,7 @@ const assert = require('assert') const path = require('path') const http = require('http') const url = require('url') - -const {remote} = require('electron') -const {app} = remote +const {app, session} = require('electron') describe(' tag', function () { this.timeout(10000) @@ -704,7 +702,6 @@ describe(' tag', function () { describe('permission-request event', function () { function setUpRequestHandler (webview, requested_permission) { - const session = require('electron').remote.session var listener = function (webContents, permission, callback) { if (webContents.getId() === webview.getId()) { assert.equal(permission, requested_permission) From 909ed54befd25e8b070d283467c7a90c3d4c121d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 1 Apr 2016 16:52:28 -0700 Subject: [PATCH 685/688] Remove stray log --- spec/fixtures/pages/webview-opener-no-node-integration.html | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/fixtures/pages/webview-opener-no-node-integration.html b/spec/fixtures/pages/webview-opener-no-node-integration.html index cd95f9bb9fb..1275a99b0bf 100644 --- a/spec/fixtures/pages/webview-opener-no-node-integration.html +++ b/spec/fixtures/pages/webview-opener-no-node-integration.html @@ -3,7 +3,6 @@ From 7734f6af621a56993f0698b3165316552c83dd16 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 1 Apr 2016 16:52:55 -0700 Subject: [PATCH 686/688] Remove semicolons --- spec/fixtures/pages/window-opener-no-node-integration.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/fixtures/pages/window-opener-no-node-integration.html b/spec/fixtures/pages/window-opener-no-node-integration.html index e146a2804ae..b587e979227 100644 --- a/spec/fixtures/pages/window-opener-no-node-integration.html +++ b/spec/fixtures/pages/window-opener-no-node-integration.html @@ -5,11 +5,11 @@ var opened = window.open('file://' + windowUrl, '', 'nodeIntegration=yes,show=no') window.addEventListener('message', function (event) { try { - opened.close(); + opened.close() } finally { - window.opener.postMessage(event.data, '*'); + window.opener.postMessage(event.data, '*') } - }); + }) From 3695e3871930a2be17e106511b2beedf48f6f5a9 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 1 Apr 2016 16:53:44 -0700 Subject: [PATCH 687/688] Remove duplicate require --- spec/webview-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index e47c7182883..583d98131d4 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -84,7 +84,7 @@ describe(' tag', function () { webview.setAttribute('allowpopups', 'on') - webview.src = require('url').format({ + webview.src = url.format({ pathname: `${fixtures}/pages/webview-opener-no-node-integration.html`, protocol: 'file', query: { From 527ff66115dcbab596067593fe436457d1cd62c2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 1 Apr 2016 16:59:13 -0700 Subject: [PATCH 688/688] Pull app/session from remote --- spec/webview-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 583d98131d4..0d32138906e 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -2,7 +2,7 @@ const assert = require('assert') const path = require('path') const http = require('http') const url = require('url') -const {app, session} = require('electron') +const {app, session} = require('electron').remote describe(' tag', function () { this.timeout(10000)