From 3c6e9332315c94b933c63271059224bf7cb571d9 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Wed, 13 Apr 2016 15:39:05 -0700 Subject: [PATCH 001/141] :memo: Add Debugging Instructions for Windows Ref #5140 --- docs/README.md | 1 + .../development/debug-instructions-windows.md | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 docs/development/debug-instructions-windows.md diff --git a/docs/README.md b/docs/README.md index 19ec51343d4e..428d2f8bd7b1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -89,4 +89,5 @@ an issue: * [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) +* [Debug Instructions (Windows)](development/debug-instructions-windows.md) * [Setting Up Symbol Server in debugger](development/setting-up-symbol-server.md) diff --git a/docs/development/debug-instructions-windows.md b/docs/development/debug-instructions-windows.md new file mode 100644 index 000000000000..3070bf33443a --- /dev/null +++ b/docs/development/debug-instructions-windows.md @@ -0,0 +1,38 @@ +# Debugging Electron in Windows +If you experience crashes or issues in Electron that you believe are not caused by your JavaScript application, but instead by Electron itself, debugging can be a little bit tricky, especially for developers not used to native/C++ debugging. However, using Visual Studio, GitHub's hosted Electron Symbol Server, and the Electron source code, it is fairly easy to enable step-through debugging with breakpoints inside Electron's source code. + +### Requirements + * **A debug build of Electron**: The easiest way is usually building it yourself, using the tools and prerequisites listed in the [build instructions for Windows](build-instructions-osx.md). While you can easily attach to and debug Electron as you can download it directly, you will find that it is heavily optimized, making debugging substantially more difficult: The debugger will not be able to show you the content of all variables and the execution path can seem strange because of inlining, tail calls, and other compiler optimizations. + + * **Visual Studio with C++ Tools**: The free community editions of [Visual Studio 2013]() and [Visual Studio 2015]() both work. + + Once installed, [configure Visual Studio to use GitHub's Electron Symbol server](setting-up-symbol-server.md). It will enable Visual Studio to gain a better understanding of what happens inside Electron, making it easier to present variables in a human-readable format. + + * **ProcMon**: The [free SysInternals tool](https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx) allows you to inspect a processes parameters, file handles, and registry operations. + +# Attaching to and Debugging Electron +To start a debugging session, open up PowerShell/CMD and execute your debug build of Electron, using the application to open as a parameter. + +``` +./out/D/electron.exe ~/my-electron-app/ +``` + +## Setting Breakpoints +Then, open up Visual Studio. Electron is not built with Visual Studio and hence does not contain a project file - you can however open up the source code files "As File", meaning that Visual Studio will open them up by themselves. You can still set breakpoints - Visual Studio will automatically figure out that the source code matches the code running in the attached process and break accordingly. + +Relevant code files can be found in `./atom/` as well as in Brightray, found in `./vendor/brightray/browser` and `./vendor/brightray/common`. If you're hardcore, you can also debug Chromium directly, which is obviously found in `chromium_src`. + +## Attaching +You can attach the Visual Studio debugger to a running process on a local or remote computer. After the process is running, click Debug / Attach to Process (or press `CTRL+ALT+P`) to open the "Attach to Process" dialog box. You can use this capability to debug apps that are running on a local or remote computer, debug multiple processes simultaneously. + +If Electron is running under a different user account, select the `Show processes from all users` check box. Notice that depending on how many BrowserWindows your app opened, you will see multiple processes. A typical one-window app will result in Visual Studio presenting you with two `Electron.exe` entries - one for the main process and one for the renderer process. Since the list only gives you names, there's currently no reliable way of figuring out which is which. + +#### Which Process Should I Attach to? +Code executed within the main process (that is, code found in or eventually run by your main JavaScript file) as well as code called using the remote (`require('electron').remote`) will run inside the main process, while other code will execute inside its respective renderer process. + +You can be attached to multiple programs when you are debugging, but only one program is active in the debugger at any time. You can set the active program in the `Debug Location` toolbar or the `Processes window`. + +## Using ProcMon to Observe a Process +While Visual Studio is fantastic for inspecting specific code paths, ProcMon's strength is really in observing everything your application is doing with the operating system - it captures File, Registry, Network, Process, and Profiling details of processes. It attempts to log *all* events occurring and can be quite overwhelming, but if you seek to understand what and how your application is doing to the operating system, it can be a valuable resource. + +For an introduction to ProcMon's basic and advanced debugging features, go check out [this video tutorial](https://channel9.msdn.com/shows/defrag-tools/defrag-tools-4-process-monitor) provided by Microsoft. \ No newline at end of file From 7d96f3d720f32b3bc6166c01cbe04152d93e8b39 Mon Sep 17 00:00:00 2001 From: Jessica Lord Date: Thu, 14 Apr 2016 15:53:34 -0700 Subject: [PATCH 002/141] Add new line so that the list is styled correctly on website --- docs/api/desktop-capturer.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/api/desktop-capturer.md b/docs/api/desktop-capturer.md index 7863622e372a..3babe0e16383 100644 --- a/docs/api/desktop-capturer.md +++ b/docs/api/desktop-capturer.md @@ -65,6 +65,7 @@ Starts a request to get all desktop sources, `callback` will be called with The `sources` is an array of `Source` objects, each `Source` represents a captured screen or individual window, and has following properties: + * `id` String - The id of the captured window or screen used in `navigator.webkitGetUserMedia`. The format looks like `window:XX` or `screen:XX` where `XX` is a random generated number. From 4dd2716865f6944606f8dffd27ab68434f30643b Mon Sep 17 00:00:00 2001 From: Jessica Lord Date: Thu, 14 Apr 2016 20:55:43 -0700 Subject: [PATCH 003/141] Fix headers --- docs/api/session.md | 56 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/api/session.md b/docs/api/session.md index 9cccefcbdb66..758082fa621b 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -48,11 +48,11 @@ const session = require('electron').session; var ses = session.fromPartition('persist:name'); ``` -### Instance Events +## Instance Events The following events are available on instances of `Session`: -#### Event: 'will-download' +### Event: 'will-download' * `event` Event * `item` [DownloadItem](download-item.md) @@ -72,11 +72,11 @@ session.defaultSession.on('will-download', function(event, item, webContents) { }); ``` -### Instance Methods +## Instance Methods The following methods are available on instances of `Session`: -#### `ses.cookies` +### `session.cookies` The `cookies` gives you ability to query and modify cookies. For example: @@ -100,7 +100,7 @@ session.defaultSession.cookies.set(cookie, function(error) { }); ``` -#### `ses.cookies.get(filter, callback)` +### `session.cookies.get(filter, callback)` * `filter` Object * `url` String (optional) - Retrieves cookies which are associated with @@ -132,7 +132,7 @@ with `callback(error, cookies)` on complete. the number of seconds since the UNIX epoch. Not provided for session cookies. -#### `ses.cookies.set(details, callback)` +### `session.cookies.set(details, callback)` * `details` Object * `url` String - Retrieves cookies which are associated with `url` @@ -151,7 +151,7 @@ with `callback(error, cookies)` on complete. Sets the cookie with `details`, `callback` will be called with `callback(error)` on complete. -#### `ses.cookies.remove(url, name, callback)` +### `session.cookies.remove(url, name, callback)` * `url` String - The URL associated with the cookie. * `name` String - The name of cookie to remove. @@ -160,20 +160,20 @@ on complete. Removes the cookies matching `url` and `name`, `callback` will called with `callback()` on complete. -#### `ses.getCacheSize(callback)` +### `session.getCacheSize(callback)` * `callback` Function * `size` Integer - Cache size used in bytes. Returns the session's current cache size. -#### `ses.clearCache(callback)` +### `session.clearCache(callback)` * `callback` Function - Called when operation is done Clears the session’s HTTP cache. -#### `ses.clearStorageData([options, ]callback)` +### `session.clearStorageData([options, ]callback)` * `options` Object (optional) * `origin` String - Should follow `window.location.origin`’s representation @@ -187,11 +187,11 @@ Clears the session’s HTTP cache. Clears the data of web storages. -#### `ses.flushStorageData()` +### `session.flushStorageData()` Writes any unwritten DOMStorage data to disk. -#### `ses.setProxy(config, callback)` +### `session.setProxy(config, callback)` * `config` Object * `pacScript` String - The URL associated with the PAC file. @@ -228,7 +228,7 @@ For example: * `http=foopy;socks=foopy2` - Use HTTP proxy `foopy` for http URLs, and use `socks4://foopy2` for all other URLs. -### `ses.resolveProxy(url, callback)` +### `session.resolveProxy(url, callback)` * `url` URL * `callback` Function @@ -236,14 +236,14 @@ For example: Resolves the proxy information for `url`. The `callback` will be called with `callback(proxy)` when the request is performed. -#### `ses.setDownloadPath(path)` +### `session.setDownloadPath(path)` * `path` String - The download location Sets download saving directory. By default, the download directory will be the `Downloads` under the respective app folder. -#### `ses.enableNetworkEmulation(options)` +### `session.enableNetworkEmulation(options)` * `options` Object * `offline` Boolean - Whether to emulate network outage. @@ -265,12 +265,12 @@ window.webContents.session.enableNetworkEmulation({ window.webContents.session.enableNetworkEmulation({offline: true}); ``` -#### `ses.disableNetworkEmulation()` +### `session.disableNetworkEmulation()` Disables any network emulation already active for the `session`. Resets to the original network configuration. -#### `ses.setCertificateVerifyProc(proc)` +### `session.setCertificateVerifyProc(proc)` * `proc` Function @@ -291,7 +291,7 @@ myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, c }); ``` -#### `ses.setPermissionRequestHandler(handler)` +### `session.setPermissionRequestHandler(handler)` * `handler` Function * `webContents` Object - [WebContents](web-contents.md) requesting the permission. @@ -314,13 +314,13 @@ session.fromPartition(partition).setPermissionRequestHandler(function(webContent }); ``` -#### `ses.clearHostResolverCache([callback])` +### `session.clearHostResolverCache([callback])` * `callback` Function (optional) - Called when operation is done. Clears the host resolver cache. -#### `ses.webRequest` +### `session.webRequest` The `webRequest` API set allows to intercept and modify contents of a request at various stages of its lifetime. @@ -349,7 +349,7 @@ session.defaultSession.webRequest.onBeforeSendHeaders(filter, function(details, }); ``` -#### `ses.webRequest.onBeforeRequest([filter, ]listener)` +### `session.webRequest.onBeforeRequest([filter, ]listener)` * `filter` Object * `listener` Function @@ -379,7 +379,7 @@ The `callback` has to be called with an `response` object: * `redirectURL` String (optional) - The original request is prevented from being sent or completed, and is instead redirected to the given URL. -#### `ses.webRequest.onBeforeSendHeaders([filter, ]listener)` +### `session.webRequest.onBeforeSendHeaders([filter, ]listener)` * `filter` Object * `listener` Function @@ -404,7 +404,7 @@ The `callback` has to be called with an `response` object: * `requestHeaders` Object (optional) - When provided, request will be made with these headers. -#### `ses.webRequest.onSendHeaders([filter, ]listener)` +### `session.webRequest.onSendHeaders([filter, ]listener)` * `filter` Object * `listener` Function @@ -421,7 +421,7 @@ response are visible by the time this listener is fired. * `timestamp` Double * `requestHeaders` Object -#### `ses.webRequest.onHeadersReceived([filter,] listener)` +### `session.webRequest.onHeadersReceived([filter,] listener)` * `filter` Object * `listener` Function @@ -449,7 +449,7 @@ The `callback` has to be called with an `response` object: * `statusLine` String (optional) - Should be provided when overriding `responseHeaders` to change header status otherwise original response header's status will be used. -#### `ses.webRequest.onResponseStarted([filter, ]listener)` +### `session.webRequest.onResponseStarted([filter, ]listener)` * `filter` Object * `listener` Function @@ -470,7 +470,7 @@ and response headers are available. * `statusCode` Integer * `statusLine` String -#### `ses.webRequest.onBeforeRedirect([filter, ]listener)` +### `session.webRequest.onBeforeRedirect([filter, ]listener)` * `filter` Object * `listener` Function @@ -491,7 +491,7 @@ redirect is about to occur. * `fromCache` Boolean * `responseHeaders` Object -#### `ses.webRequest.onCompleted([filter, ]listener)` +### `session.webRequest.onCompleted([filter, ]listener)` * `filter` Object * `listener` Function @@ -510,7 +510,7 @@ completed. * `statusCode` Integer * `statusLine` String -#### `ses.webRequest.onErrorOccurred([filter, ]listener)` +### `session.webRequest.onErrorOccurred([filter, ]listener)` * `filter` Object * `listener` Function From c87c49f4c8f48668d7913f7da8b81e495dd4692e Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Sat, 26 Mar 2016 18:12:25 -0700 Subject: [PATCH 004/141] Allow sheets to be attached at a custom offset #4679 Adds a new "setSheetOffset" API to the `dialog` module, which allows you to change the attachment point for sheets on Mac OS X. I put the API on the dialog module, even though Mac OS X requires that the native window hold and return the desired offset. 1. I was originally hoping to make this an argument on the actual dialog.show* calls, but it seems the parameter set is defined in `libchromiumcontent` and I wasn't sure it would be appropriate to add there? 2. The API could also be on the BrowserWindow (eg `BrowserWindow.setSheetOffset`). I don't have a strong preference, but I think it's more discoverable on the `dialog` module. --- atom/browser/api/atom_api_dialog.cc | 5 +++++ atom/browser/native_window.cc | 8 ++++++++ atom/browser/native_window.h | 6 ++++++ atom/browser/native_window_mac.mm | 6 ++++++ docs/api/dialog.md | 28 ++++++++++++++++++++++++---- lib/browser/api/dialog.js | 6 +++++- 6 files changed, 54 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 0a544c56468c..965b92878351 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -66,6 +66,10 @@ void ShowMessageBox(int type, } } +void SetSheetOffset(atom::NativeWindow* window, const double offset) { + window->SetSheetOffset(offset); +} + void ShowOpenDialog(const std::string& title, const base::FilePath& default_path, const file_dialog::Filters& filters, @@ -112,6 +116,7 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("showMessageBox", &ShowMessageBox); dict.SetMethod("showErrorBox", &atom::ShowErrorBox); dict.SetMethod("showOpenDialog", &ShowOpenDialog); + dict.SetMethod("setSheetOffset", &SetSheetOffset); dict.SetMethod("showSaveDialog", &ShowSaveDialog); } diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index d7ed86165b9f..37bf8f687ed8 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -201,6 +201,14 @@ gfx::Size NativeWindow::GetContentSize() { return WindowSizeToContentSize(GetSize()); } +void NativeWindow::SetSheetOffset(const double offset) { + sheet_offset_ = offset; +} + +double NativeWindow::GetSheetOffset() { + return sheet_offset_; +} + void NativeWindow::SetSizeConstraints( const extensions::SizeConstraints& window_constraints) { extensions::SizeConstraints content_constraints; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index f91d041c057e..d60ac209d8a0 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -190,6 +190,9 @@ class NativeWindow : public base::SupportsUserData, gfx::Size GetAspectRatioExtraSize(); void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size); + void SetSheetOffset(const double offset); + double GetSheetOffset(); + base::WeakPtr GetWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -326,6 +329,9 @@ class NativeWindow : public base::SupportsUserData, // it should be cancelled when we can prove that the window is responsive. base::CancelableClosure window_unresposive_closure_; + // Used to display sheets at the appropriate vertical offset + double sheet_offset_; + // Used to maintain the aspect ratio of a view which is inside of the // content view. double aspect_ratio_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index b24e828e578d..dc2929f82ecd 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -243,6 +243,12 @@ bool ScopedDisableResize::disable_resize_ = false; return NO; } +- (NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet usingRect:(NSRect)rect { + rect.origin.y = window.contentView.frame.size.height - shell_->GetSheetOffset(); + return rect; +} + + @end @interface AtomNSWindow : NSWindow { diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 9fbc20dd8305..f36850f310a0 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -18,10 +18,6 @@ The Dialog is opened from Electron's main thread. If you want to use the dialog 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. - ## Methods The `dialog` module has the following methods: @@ -125,3 +121,27 @@ This API can be called safely before the `ready` event the `app` module emits, it is usually used to report errors in early stage of startup. If called before the app `ready`event on Linux, the message will be emitted to stderr, and no GUI dialog will appear. + + +## Sheets + +On Mac OS X, dialogs are presented as sheets attached to a window if you provide +a `BrowserWindow` reference in the `browserWindow` parameter, or modals if no +window is provided. + +### `dialog.setSheetOffset(browserWindow, offset)` + +* `browserWindow` BrowserWindow (optional) + +Changes the attachment point for sheets on Mac OS X. By default, sheets are attached +just below the window frame, but you may want to display them beneath a HTML-rendered +toolbar. For example: +``` +const {remote} = require('electron'); +const browserWindow = remote.getCurrentWindow(); + +var toolbarRect = document.getElementById('toolbar').getBoundingClientRect(); +remote.dialog.setSheetOffset(browserWindow, toolbarRect.height); + +... show dialog ... +``` diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index 6669d8cab89a..f88d25cfbb3f 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -49,7 +49,11 @@ var checkAppInitialized = function () { } module.exports = { - showOpenDialog: function (...args) { + setSheetOffset: function(window, offset) { + return binding.setSheetOffset(window, offset) + }, + + showOpenDialog: function(...args) { var prop, properties, value, wrappedCallback checkAppInitialized() let [window, options, callback] = parseArgs.apply(null, args) From 65c37fe64bc1140813fad22c47b7519f9865ba2e Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Sat, 16 Apr 2016 10:57:39 -0400 Subject: [PATCH 005/141] Create local variable to typecast `view` --- atom/browser/native_window_mac.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index dc2929f82ecd..c35c177ac298 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -244,7 +244,8 @@ bool ScopedDisableResize::disable_resize_ = false; } - (NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet usingRect:(NSRect)rect { - rect.origin.y = window.contentView.frame.size.height - shell_->GetSheetOffset(); + NSView * view = window.contentView; + rect.origin.y = view.frame.size.height - shell_->GetSheetOffset(); return rect; } From 1976c271ec39362e9f800cac5a2a4be0a2d0b302 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Sat, 16 Apr 2016 11:04:48 -0400 Subject: [PATCH 006/141] Fix JS linter errors --- lib/browser/api/dialog.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index f88d25cfbb3f..ed7ab063ed84 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -49,11 +49,11 @@ var checkAppInitialized = function () { } module.exports = { - setSheetOffset: function(window, offset) { + setSheetOffset: function (window, offset) { return binding.setSheetOffset(window, offset) }, - showOpenDialog: function(...args) { + showOpenDialog: function (...args) { var prop, properties, value, wrappedCallback checkAppInitialized() let [window, options, callback] = parseArgs.apply(null, args) From d5124210844a9a85faefc9563c992ddbc2beb7fb Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Sat, 16 Apr 2016 19:58:03 +0200 Subject: [PATCH 007/141] Fix documentation --- docs/api/web-view-tag.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index cee06dfa35db..c77d3c690b85 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -504,6 +504,7 @@ Returns: * `errorCode` Integer * `errorDescription` String * `validatedURL` String +* `isMainFrame` Boolean This event is like `did-finish-load`, but fired when the load failed or was cancelled, e.g. `window.stop()` is invoked. @@ -762,6 +763,10 @@ Emitted when media is paused or done playing. ### Event: 'did-change-theme-color' +Returns: + +* `themeColor` String + Emitted when a page's theme color changes. This is usually due to encountering a meta tag: ```html From 0bf1e561561d87fb1ba9a4af418a1f74306e353a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 18 Apr 2016 13:59:15 +0900 Subject: [PATCH 008/141] Update brightray for electron/brightray#212 --- atom/browser/api/atom_api_session.cc | 26 +++++++++----------------- atom/browser/api/atom_api_session.h | 3 +++ vendor/brightray | 2 +- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 0f104c760724..2b352e52f7c5 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -23,12 +23,13 @@ #include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/node_includes.h" #include "base/files/file_path.h" +#include "base/guid.h" #include "base/prefs/pref_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/thread_task_runner_handle.h" #include "brightray/browser/net/devtools_network_conditions.h" -#include "brightray/browser/net/devtools_network_controller.h" +#include "brightray/browser/net/devtools_network_controller_handle.h" #include "chrome/common/pref_names.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" @@ -288,7 +289,8 @@ void ClearHostResolverCacheInIO( } // namespace Session::Session(AtomBrowserContext* browser_context) - : browser_context_(browser_context) { + : devtools_network_emulation_client_id_(base::GenerateGUID()), + browser_context_(browser_context) { AttachAsUserData(browser_context); // Observe DownloadManger to get download notifications. @@ -381,25 +383,15 @@ void Session::EnableNetworkEmulation(const mate::Dictionary& options) { download_throughput, upload_throughput)); } - auto controller = browser_context_->GetDevToolsNetworkController(); - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&brightray::DevToolsNetworkController::SetNetworkState, - base::Unretained(controller), - std::string(), - base::Passed(&conditions))); + browser_context_->network_controller_handle()->SetNetworkState( + devtools_network_emulation_client_id_, std::move(conditions)); } void Session::DisableNetworkEmulation() { - scoped_ptr conditions( - new brightray::DevToolsNetworkConditions(false)); - auto controller = browser_context_->GetDevToolsNetworkController(); - - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&brightray::DevToolsNetworkController::SetNetworkState, - base::Unretained(controller), - std::string(), - base::Passed(&conditions))); + scoped_ptr conditions; + browser_context_->network_controller_handle()->SetNetworkState( + devtools_network_emulation_client_id_, std::move(conditions)); } void Session::SetCertVerifyProc(v8::Local val, diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 02d8ba5cdec0..7da01acdaaa6 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -86,6 +86,9 @@ class Session: public mate::TrackableObject, v8::Global cookies_; v8::Global web_request_; + // The X-DevTools-Emulate-Network-Conditions-Client-Id. + std::string devtools_network_emulation_client_id_; + scoped_refptr browser_context_; DISALLOW_COPY_AND_ASSIGN(Session); diff --git a/vendor/brightray b/vendor/brightray index 79b80e83f4a6..bc9c496a6185 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 79b80e83f4a64790e51ad2fc44b0a56bdb3d7ef3 +Subproject commit bc9c496a6185e37e792c10bfc5b49ea779b27cd3 From fcf04377d7e69877db4f6fca3d2e7b35e4241074 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Thu, 14 Apr 2016 08:27:27 +0530 Subject: [PATCH 009/141] set network emulation client id in request headers --- atom/browser/api/atom_api_session.cc | 10 ++++++++++ atom/browser/net/atom_network_delegate.cc | 8 ++++++++ atom/common/options_switches.cc | 4 ++++ atom/common/options_switches.h | 2 ++ 4 files changed, 24 insertions(+) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 2b352e52f7c5..c6ef6619034f 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -22,6 +22,8 @@ #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/node_includes.h" +#include "atom/common/options_switches.h" +#include "base/command_line.h" #include "base/files/file_path.h" #include "base/guid.h" #include "base/prefs/pref_service.h" @@ -286,6 +288,12 @@ void ClearHostResolverCacheInIO( } } +void SetDevToolsNetworkEmulationClientId(const std::string& id) { + auto cmd_line = base::CommandLine::ForCurrentProcess(); + cmd_line->AppendSwitchASCII( + switches::kDevToolsEmulateNetworkConditionsClientId, id); +} + } // namespace Session::Session(AtomBrowserContext* browser_context) @@ -386,12 +394,14 @@ void Session::EnableNetworkEmulation(const mate::Dictionary& options) { browser_context_->network_controller_handle()->SetNetworkState( devtools_network_emulation_client_id_, std::move(conditions)); + SetDevToolsNetworkEmulationClientId(devtools_network_emulation_client_id_); } void Session::DisableNetworkEmulation() { scoped_ptr conditions; browser_context_->network_controller_handle()->SetNetworkState( devtools_network_emulation_client_id_, std::move(conditions)); + SetDevToolsNetworkEmulationClientId(std::string()); } void Session::SetCertVerifyProc(v8::Local val, diff --git a/atom/browser/net/atom_network_delegate.cc b/atom/browser/net/atom_network_delegate.cc index 86bfe12079ad..cb602c4b3627 100644 --- a/atom/browser/net/atom_network_delegate.cc +++ b/atom/browser/net/atom_network_delegate.cc @@ -8,6 +8,8 @@ #include #include "atom/common/native_mate_converters/net_converter.h" +#include "atom/common/options_switches.h" +#include "base/command_line.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "content/public/browser/browser_thread.h" @@ -241,6 +243,12 @@ int AtomNetworkDelegate::OnBeforeSendHeaders( net::URLRequest* request, const net::CompletionCallback& callback, net::HttpRequestHeaders* headers) { + auto cmd_line = base::CommandLine::ForCurrentProcess(); + auto client_id = cmd_line->GetSwitchValueASCII( + switches::kDevToolsEmulateNetworkConditionsClientId); + if (!client_id.empty()) + headers->SetHeader( + switches::kDevToolsEmulateNetworkConditionsClientId, client_id); if (!ContainsKey(response_listeners_, kOnBeforeSendHeaders)) return brightray::NetworkDelegate::OnBeforeSendHeaders( request, callback, headers); diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index ce28cc98facf..b4c5c4ef8314 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -156,6 +156,10 @@ const char kWidevineCdmPath[] = "widevine-cdm-path"; // Widevine CDM version. const char kWidevineCdmVersion[] = "widevine-cdm-version"; +// Client id for devtools network emulation. +const char kDevToolsEmulateNetworkConditionsClientId[] = + "X-DevTools-Emulate-Network-Conditions-Client-Id"; + } // namespace switches } // namespace atom diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 52d64c00d51a..e05be3b4359f 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -87,6 +87,8 @@ extern const char kOpenerID[]; extern const char kWidevineCdmPath[]; extern const char kWidevineCdmVersion[]; +extern const char kDevToolsEmulateNetworkConditionsClientId[]; + } // namespace switches } // namespace atom From e81cec40589aff1688917306ea0c57b3e85016d8 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 18 Apr 2016 10:41:31 +0530 Subject: [PATCH 010/141] app: api to import client certificate --- atom/browser/api/atom_api_app.cc | 69 ++++++- atom/browser/api/atom_api_app.h | 11 ++ atom/browser/atom_browser_client.cc | 30 --- .../browser/certificate_manager_model.cc | 177 ++++++++++++++++++ .../browser/certificate_manager_model.h | 116 ++++++++++++ filenames.gypi | 2 + 6 files changed, 374 insertions(+), 31 deletions(-) create mode 100644 chromium_src/chrome/browser/certificate_manager_model.cc create mode 100644 chromium_src/chrome/browser/certificate_manager_model.h diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 52d6ec3d338c..4cbae0885e9a 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -24,6 +24,7 @@ #include "base/command_line.h" #include "base/environment.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/path_service.h" #include "brightray/browser/brightray_paths.h" #include "chrome/common/chrome_paths.h" @@ -157,6 +158,43 @@ void PassLoginInformation(scoped_refptr login_handler, login_handler->CancelAuth(); } +net::CertificateList ImportCertsFromFile( + const base::FilePath& path) { + net::CertificateList certs; + if (path.empty()) + return certs; + + std::string cert_data; + if (!base::ReadFileToString(path, &cert_data)) + return certs; + + certs = net::X509Certificate::CreateCertificateListFromBytes( + cert_data.data(), cert_data.size(), + net::X509Certificate::FORMAT_AUTO); + + return certs; +} + +int ImportCertificateIntoCertStore( + CertificateManagerModel* model, + const base::FilePath& path, + const base::FilePath& ca_path, + const base::string16& password) { + LOG(WARNING) << "importing ...."; + + std::string file_data; + int result = -1; + net::CertificateList ca_certs; + net::NSSCertDatabase::ImportCertFailureList not_imported; + auto module = model->cert_db()->GetPublicModule(); + if (base::ReadFileToString(path, &file_data)) { + result &= model->ImportFromPKCS12(module, file_data, password, true); + ca_certs = ImportCertsFromFile(ca_path); + result &= model->ImportCACerts(ca_certs, net::NSSCertDatabase::TRUST_DEFAULT, ¬_imported); + } + return result; +} + } // namespace App::App() { @@ -369,6 +407,34 @@ bool App::MakeSingleInstance( } } +void App::ImportClientCertificate( + const base::FilePath& path, + const base::FilePath& ca_path, + + const base::string16& password, + const net::CompletionCallback& callback) { + auto browser_context = AtomBrowserMainParts::Get()->browser_context(); + if (!certificate_manager_model_) { + CertificateManagerModel::Create(browser_context, base::Bind(&App::OnCertificateManagerModelCreated, base::Unretained(this), path, ca_path, password, callback)); + return; + } + + int rv = ImportCertificateIntoCertStore(certificate_manager_model_.get(), path, ca_path, password); + callback.Run(rv); +} + +void App::OnCertificateManagerModelCreated( + const base::FilePath& path, + const base::FilePath& ca_path, + const base::string16& password, + const net::CompletionCallback& callback, + scoped_ptr model) { + certificate_manager_model_ = std::move(model); + + int rv = ImportCertificateIntoCertStore(certificate_manager_model_.get(), path, ca_path, password); + callback.Run(rv); +} + mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( v8::Isolate* isolate) { auto browser = base::Unretained(Browser::Get()); @@ -408,7 +474,8 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("allowNTLMCredentialsForAllDomains", &App::AllowNTLMCredentialsForAllDomains) .SetMethod("getLocale", &App::GetLocale) - .SetMethod("makeSingleInstance", &App::MakeSingleInstance); + .SetMethod("makeSingleInstance", &App::MakeSingleInstance) + .SetMethod("importClientCertificate", &App::ImportClientCertificate); } // static diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 5025a3869dd4..b5c797df0030 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -11,9 +11,11 @@ #include "atom/browser/atom_browser_client.h" #include "atom/browser/browser_observer.h" #include "atom/common/native_mate_converters/callback.h" +#include "chrome/browser/certificate_manager_model.h" #include "chrome/browser/process_singleton.h" #include "content/public/browser/gpu_data_manager_observer.h" #include "native_mate/handle.h" +#include "net/base/completion_callback.h" namespace base { class FilePath; @@ -41,6 +43,13 @@ class App : public AtomBrowserClient::Delegate, int render_process_id, int render_frame_id); + void OnCertificateManagerModelCreated( + const base::FilePath& path, + const base::FilePath& ca_path, + const base::string16& password, + const net::CompletionCallback& callback, + scoped_ptr model); + protected: App(); virtual ~App(); @@ -97,12 +106,14 @@ class App : public AtomBrowserClient::Delegate, bool MakeSingleInstance( const ProcessSingleton::NotificationCallback& callback); std::string GetLocale(); + void ImportClientCertificate(const base::FilePath& path, const base::FilePath& ca_path, const base::string16& password, const net::CompletionCallback& callback); #if defined(OS_WIN) bool IsAeroGlassEnabled(); #endif scoped_ptr process_singleton_; + scoped_ptr certificate_manager_model_; DISALLOW_COPY_AND_ASSIGN(App); }; diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 9a59c3f9d412..ddefd0688a2a 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -55,26 +55,6 @@ std::string g_custom_schemes = ""; // Custom schemes to be registered to handle service worker. std::string g_custom_service_worker_schemes = ""; -scoped_refptr ImportCertFromFile( - const base::FilePath& path) { - if (path.empty()) - return nullptr; - - std::string cert_data; - if (!base::ReadFileToString(path, &cert_data)) - return nullptr; - - net::CertificateList certs = - net::X509Certificate::CreateCertificateListFromBytes( - cert_data.data(), cert_data.size(), - net::X509Certificate::FORMAT_AUTO); - - if (certs.empty()) - return nullptr; - - return certs[0]; -} - } // namespace // static @@ -242,16 +222,6 @@ void AtomBrowserClient::SelectClientCertificate( content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, scoped_ptr delegate) { - // --client-certificate=`path` - auto cmd = base::CommandLine::ForCurrentProcess(); - if (cmd->HasSwitch(switches::kClientCertificate)) { - auto cert_path = cmd->GetSwitchValuePath(switches::kClientCertificate); - auto certificate = ImportCertFromFile(cert_path); - if (certificate.get()) - delegate->ContinueWithCertificate(certificate.get()); - return; - } - if (!cert_request_info->client_certs.empty() && delegate_) { delegate_->SelectClientCertificate( web_contents, cert_request_info, std::move(delegate)); diff --git a/chromium_src/chrome/browser/certificate_manager_model.cc b/chromium_src/chrome/browser/certificate_manager_model.cc new file mode 100644 index 000000000000..83ab12af7609 --- /dev/null +++ b/chromium_src/chrome/browser/certificate_manager_model.cc @@ -0,0 +1,177 @@ +// Copyright (c) 2012 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. + +#include "chrome/browser/certificate_manager_model.h" + +#include + +#include "base/bind.h" +#include "base/i18n/time_formatting.h" +#include "base/logging.h" +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/resource_context.h" +#include "crypto/nss_util.h" +#include "crypto/nss_util_internal.h" +#include "net/base/crypto_module.h" +#include "net/base/net_errors.h" +#include "net/cert/nss_cert_database.h" +#include "net/cert/x509_certificate.h" +#include "ui/base/l10n/l10n_util.h" + +using content::BrowserThread; + +namespace { + +net::NSSCertDatabase* g_nss_cert_database = nullptr; + +net::NSSCertDatabase* GetNSSCertDatabaseForResourceContext( + content::ResourceContext* context, + const base::Callback& callback) { + // This initialization is not thread safe. This CHECK ensures that this code + // is only run on a single thread. + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + if (!g_nss_cert_database) { + // Linux has only a single persistent slot compared to ChromeOS's separate + // public and private slot. + // Redirect any slot usage to this persistent slot on Linux. + g_nss_cert_database = new net::NSSCertDatabase( + crypto::ScopedPK11Slot( + crypto::GetPersistentNSSKeySlot()) /* public slot */, + crypto::ScopedPK11Slot( + crypto::GetPersistentNSSKeySlot()) /* private slot */); + } + return g_nss_cert_database; +} + +} // namespace + +// CertificateManagerModel is created on the UI thread. It needs a +// NSSCertDatabase handle (and on ChromeOS it needs to get the TPM status) which +// needs to be done on the IO thread. +// +// The initialization flow is roughly: +// +// UI thread IO Thread +// +// CertificateManagerModel::Create +// \--------------------------------------v +// CertificateManagerModel::GetCertDBOnIOThread +// | +// GetNSSCertDatabaseForResourceContext +// | +// CertificateManagerModel::DidGetCertDBOnIOThread +// | +// crypto::IsTPMTokenEnabledForNSS +// v--------------------------------------/ +// CertificateManagerModel::DidGetCertDBOnUIThread +// | +// new CertificateManagerModel +// | +// callback + +// static +void CertificateManagerModel::Create( + content::BrowserContext* browser_context, + const CreationCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + BrowserThread::PostTask( + BrowserThread::IO, + FROM_HERE, + base::Bind(&CertificateManagerModel::GetCertDBOnIOThread, + browser_context->GetResourceContext(), + callback)); +} + +CertificateManagerModel::CertificateManagerModel( + net::NSSCertDatabase* nss_cert_database, + bool is_user_db_available) + : cert_db_(nss_cert_database), + is_user_db_available_(is_user_db_available) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +} + +CertificateManagerModel::~CertificateManagerModel() { +} + +int CertificateManagerModel::ImportFromPKCS12(net::CryptoModule* module, + const std::string& data, + const base::string16& password, + bool is_extractable) { + return cert_db_->ImportFromPKCS12(module, data, password, + is_extractable, NULL); +} + +int CertificateManagerModel::ImportUserCert(const std::string& data) { + return cert_db_->ImportUserCert(data); +} + +bool CertificateManagerModel::ImportCACerts( + const net::CertificateList& certificates, + net::NSSCertDatabase::TrustBits trust_bits, + net::NSSCertDatabase::ImportCertFailureList* not_imported) { + return cert_db_->ImportCACerts(certificates, trust_bits, not_imported); +} + +bool CertificateManagerModel::ImportServerCert( + const net::CertificateList& certificates, + net::NSSCertDatabase::TrustBits trust_bits, + net::NSSCertDatabase::ImportCertFailureList* not_imported) { + return cert_db_->ImportServerCert(certificates, trust_bits, + not_imported); +} + +bool CertificateManagerModel::SetCertTrust( + const net::X509Certificate* cert, + net::CertType type, + net::NSSCertDatabase::TrustBits trust_bits) { + return cert_db_->SetCertTrust(cert, type, trust_bits); +} + +bool CertificateManagerModel::Delete(net::X509Certificate* cert) { + return cert_db_->DeleteCertAndKey(cert); +} + +// static +void CertificateManagerModel::DidGetCertDBOnUIThread( + net::NSSCertDatabase* cert_db, + bool is_user_db_available, + const CreationCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + scoped_ptr model(new CertificateManagerModel( + cert_db, is_user_db_available)); + callback.Run(std::move(model)); +} + +// static +void CertificateManagerModel::DidGetCertDBOnIOThread( + const CreationCallback& callback, + net::NSSCertDatabase* cert_db) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + bool is_user_db_available = !!cert_db->GetPublicSlot(); + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&CertificateManagerModel::DidGetCertDBOnUIThread, + cert_db, + is_user_db_available, + callback)); +} + +// static +void CertificateManagerModel::GetCertDBOnIOThread( + content::ResourceContext* context, + const CreationCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + net::NSSCertDatabase* cert_db = GetNSSCertDatabaseForResourceContext( + context, + base::Bind(&CertificateManagerModel::DidGetCertDBOnIOThread, + callback)); + if (cert_db) + DidGetCertDBOnIOThread(callback, cert_db); +} diff --git a/chromium_src/chrome/browser/certificate_manager_model.h b/chromium_src/chrome/browser/certificate_manager_model.h new file mode 100644 index 000000000000..bd0d5ddfb291 --- /dev/null +++ b/chromium_src/chrome/browser/certificate_manager_model.h @@ -0,0 +1,116 @@ +// Copyright (c) 2012 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. + +#ifndef CHROME_BROWSER_CERTIFICATE_MANAGER_MODEL_H_ +#define CHROME_BROWSER_CERTIFICATE_MANAGER_MODEL_H_ + +#include +#include + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/strings/string16.h" +#include "net/cert/nss_cert_database.h" + +namespace content { +class BrowserContext; +class ResourceContext; +} // namespace content + +// CertificateManagerModel provides the data to be displayed in the certificate +// manager dialog, and processes changes from the view. +class CertificateManagerModel { + public: + typedef base::Callback)> + CreationCallback; + + // Creates a CertificateManagerModel. The model will be passed to the callback + // when it is ready. The caller must ensure the model does not outlive the + // |browser_context|. + static void Create(content::BrowserContext* browser_context, + const CreationCallback& callback); + + ~CertificateManagerModel(); + + bool is_user_db_available() const { return is_user_db_available_; } + + // Accessor for read-only access to the underlying NSSCertDatabase. + const net::NSSCertDatabase* cert_db() const { return cert_db_; } + + // Import private keys and certificates from PKCS #12 encoded + // |data|, using the given |password|. If |is_extractable| is false, + // mark the private key as unextractable from the module. + // Returns a net error code on failure. + int ImportFromPKCS12(net::CryptoModule* module, const std::string& data, + const base::string16& password, bool is_extractable); + + // Import user certificate from DER encoded |data|. + // Returns a net error code on failure. + int ImportUserCert(const std::string& data); + + // Import CA certificates. + // Tries to import all the certificates given. The root will be trusted + // according to |trust_bits|. Any certificates that could not be imported + // will be listed in |not_imported|. + // |trust_bits| should be a bit field of TRUST* values from NSSCertDatabase. + // Returns false if there is an internal error, otherwise true is returned and + // |not_imported| should be checked for any certificates that were not + // imported. + bool ImportCACerts(const net::CertificateList& certificates, + net::NSSCertDatabase::TrustBits trust_bits, + net::NSSCertDatabase::ImportCertFailureList* not_imported); + + // Import server certificate. The first cert should be the server cert. Any + // additional certs should be intermediate/CA certs and will be imported but + // not given any trust. + // Any certificates that could not be imported will be listed in + // |not_imported|. + // |trust_bits| can be set to explicitly trust or distrust the certificate, or + // use TRUST_DEFAULT to inherit trust as normal. + // Returns false if there is an internal error, otherwise true is returned and + // |not_imported| should be checked for any certificates that were not + // imported. + bool ImportServerCert( + const net::CertificateList& certificates, + net::NSSCertDatabase::TrustBits trust_bits, + net::NSSCertDatabase::ImportCertFailureList* not_imported); + + // Set trust values for certificate. + // |trust_bits| should be a bit field of TRUST* values from NSSCertDatabase. + // Returns true on success or false on failure. + bool SetCertTrust(const net::X509Certificate* cert, + net::CertType type, + net::NSSCertDatabase::TrustBits trust_bits); + + // Delete the cert. Returns true on success. |cert| is still valid when this + // function returns. + bool Delete(net::X509Certificate* cert); + + private: + CertificateManagerModel(net::NSSCertDatabase* nss_cert_database, + bool is_user_db_available); + + // Methods used during initialization, see the comment at the top of the .cc + // file for details. + static void DidGetCertDBOnUIThread( + net::NSSCertDatabase* cert_db, + bool is_user_db_available, + const CreationCallback& callback); + static void DidGetCertDBOnIOThread( + const CreationCallback& callback, + net::NSSCertDatabase* cert_db); + static void GetCertDBOnIOThread(content::ResourceContext* context, + const CreationCallback& callback); + + net::NSSCertDatabase* cert_db_; + // Whether the certificate database has a public slot associated with the + // profile. If not set, importing certificates is not allowed with this model. + bool is_user_db_available_; + + DISALLOW_COPY_AND_ASSIGN(CertificateManagerModel); +}; + +#endif // CHROME_BROWSER_CERTIFICATE_MANAGER_MODEL_H_ diff --git a/filenames.gypi b/filenames.gypi index dd9edb409f59..4de1b366b4fc 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -390,6 +390,8 @@ 'atom/utility/atom_content_utility_client.h', 'chromium_src/chrome/browser/browser_process.cc', 'chromium_src/chrome/browser/browser_process.h', + 'chromium_src/chrome/browser/certificate_manager_model.cc', + 'chromium_src/chrome/browser/certificate_manager_model.h', 'chromium_src/chrome/browser/chrome_process_finder_win.cc', 'chromium_src/chrome/browser/chrome_process_finder_win.h', 'chromium_src/chrome/browser/chrome_notification_types.h', From 34319abf4a87ed9979bf1de0d868ca1b76a3c257 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 18 Apr 2016 14:52:03 +0900 Subject: [PATCH 011/141] Initialize the embedder_ member data Otherwise it is going to be some random value and bite us. --- atom/browser/api/atom_api_web_contents.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index abad4add4fb0..64a76d57e652 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -217,6 +217,7 @@ content::ServiceWorkerContext* GetServiceWorkerContext( WebContents::WebContents(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), + embedder_(nullptr), type_(REMOTE), request_id_(0), background_throttling_(true) { From 12483486c06ef72a0286f0088b49b80112a805a0 Mon Sep 17 00:00:00 2001 From: Andrew Dassonville Date: Sun, 17 Apr 2016 23:04:02 -0700 Subject: [PATCH 012/141] Update link to setFeatureEnabledFromString --- 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 877a6d0f7457..b1b6cf130f7a 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -912,4 +912,4 @@ Returns whether the window is visible on all workspaces. Ignore all moused events that happened in the window. -[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 +[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=576 From b8e04f4947698cb2694317f2cd8227580fff2040 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 18 Apr 2016 11:35:24 +0530 Subject: [PATCH 013/141] set client id on AtomNetworkDelegate instead of cmd line switch --- atom/browser/api/atom_api_session.cc | 14 ++++---------- atom/browser/net/atom_network_delegate.cc | 18 ++++++++++-------- atom/browser/net/atom_network_delegate.h | 6 ++++++ atom/common/options_switches.cc | 4 ---- atom/common/options_switches.h | 2 -- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index c6ef6619034f..222591e92e92 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -22,8 +22,6 @@ #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/net_converter.h" #include "atom/common/node_includes.h" -#include "atom/common/options_switches.h" -#include "base/command_line.h" #include "base/files/file_path.h" #include "base/guid.h" #include "base/prefs/pref_service.h" @@ -288,12 +286,6 @@ void ClearHostResolverCacheInIO( } } -void SetDevToolsNetworkEmulationClientId(const std::string& id) { - auto cmd_line = base::CommandLine::ForCurrentProcess(); - cmd_line->AppendSwitchASCII( - switches::kDevToolsEmulateNetworkConditionsClientId, id); -} - } // namespace Session::Session(AtomBrowserContext* browser_context) @@ -394,14 +386,16 @@ void Session::EnableNetworkEmulation(const mate::Dictionary& options) { browser_context_->network_controller_handle()->SetNetworkState( devtools_network_emulation_client_id_, std::move(conditions)); - SetDevToolsNetworkEmulationClientId(devtools_network_emulation_client_id_); + browser_context_->network_delegate()->SetDevToolsNetworkEmulationClientId( + devtools_network_emulation_client_id_); } void Session::DisableNetworkEmulation() { scoped_ptr conditions; browser_context_->network_controller_handle()->SetNetworkState( devtools_network_emulation_client_id_, std::move(conditions)); - SetDevToolsNetworkEmulationClientId(std::string()); + browser_context_->network_delegate()->SetDevToolsNetworkEmulationClientId( + std::string()); } void Session::SetCertVerifyProc(v8::Local val, diff --git a/atom/browser/net/atom_network_delegate.cc b/atom/browser/net/atom_network_delegate.cc index cb602c4b3627..6ef5ac22807a 100644 --- a/atom/browser/net/atom_network_delegate.cc +++ b/atom/browser/net/atom_network_delegate.cc @@ -4,17 +4,16 @@ #include "atom/browser/net/atom_network_delegate.h" -#include #include #include "atom/common/native_mate_converters/net_converter.h" -#include "atom/common/options_switches.h" -#include "base/command_line.h" #include "base/stl_util.h" #include "base/strings/string_util.h" +#include "brightray/browser/net/devtools_network_transaction.h" #include "content/public/browser/browser_thread.h" #include "net/url_request/url_request.h" +using brightray::DevToolsNetworkTransaction; using content::BrowserThread; namespace atom { @@ -228,6 +227,11 @@ void AtomNetworkDelegate::SetResponseListenerInIO( response_listeners_[type] = { patterns, callback }; } +void AtomNetworkDelegate::SetDevToolsNetworkEmulationClientId( + const std::string& client_id) { + client_id_ = client_id; +} + int AtomNetworkDelegate::OnBeforeURLRequest( net::URLRequest* request, const net::CompletionCallback& callback, @@ -243,12 +247,10 @@ int AtomNetworkDelegate::OnBeforeSendHeaders( net::URLRequest* request, const net::CompletionCallback& callback, net::HttpRequestHeaders* headers) { - auto cmd_line = base::CommandLine::ForCurrentProcess(); - auto client_id = cmd_line->GetSwitchValueASCII( - switches::kDevToolsEmulateNetworkConditionsClientId); - if (!client_id.empty()) + if (!client_id_.empty()) headers->SetHeader( - switches::kDevToolsEmulateNetworkConditionsClientId, client_id); + DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId, + client_id_); if (!ContainsKey(response_listeners_, kOnBeforeSendHeaders)) return brightray::NetworkDelegate::OnBeforeSendHeaders( request, callback, headers); diff --git a/atom/browser/net/atom_network_delegate.h b/atom/browser/net/atom_network_delegate.h index ee159df60f13..e0b41eb45891 100644 --- a/atom/browser/net/atom_network_delegate.h +++ b/atom/browser/net/atom_network_delegate.h @@ -7,6 +7,7 @@ #include #include +#include #include "brightray/browser/network_delegate.h" #include "base/callback.h" @@ -68,6 +69,8 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate { const URLPatterns& patterns, const ResponseListener& callback); + void SetDevToolsNetworkEmulationClientId(const std::string& client_id); + protected: // net::NetworkDelegate: int OnBeforeURLRequest(net::URLRequest* request, @@ -116,6 +119,9 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate { std::map response_listeners_; std::map callbacks_; + // Client id for devtools network emulation. + std::string client_id_; + DISALLOW_COPY_AND_ASSIGN(AtomNetworkDelegate); }; diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index b4c5c4ef8314..ce28cc98facf 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -156,10 +156,6 @@ const char kWidevineCdmPath[] = "widevine-cdm-path"; // Widevine CDM version. const char kWidevineCdmVersion[] = "widevine-cdm-version"; -// Client id for devtools network emulation. -const char kDevToolsEmulateNetworkConditionsClientId[] = - "X-DevTools-Emulate-Network-Conditions-Client-Id"; - } // namespace switches } // namespace atom diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index e05be3b4359f..52d64c00d51a 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -87,8 +87,6 @@ extern const char kOpenerID[]; extern const char kWidevineCdmPath[]; extern const char kWidevineCdmVersion[]; -extern const char kDevToolsEmulateNetworkConditionsClientId[]; - } // namespace switches } // namespace atom From 142300aeb9a6939591093bf489b845e6425df1b9 Mon Sep 17 00:00:00 2001 From: StoneStoneStone Date: Mon, 18 Apr 2016 22:38:15 +0800 Subject: [PATCH 014/141] Create frameless-window.md Translate `frameless-window.md` to Chinese. And I'm not sure that the `non-client frame`'s translation is accurate. --- .../zh-CN/api/frameless-window.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 docs-translations/zh-CN/api/frameless-window.md diff --git a/docs-translations/zh-CN/api/frameless-window.md b/docs-translations/zh-CN/api/frameless-window.md new file mode 100644 index 000000000000..1916c6a929bc --- /dev/null +++ b/docs-translations/zh-CN/api/frameless-window.md @@ -0,0 +1,87 @@ +# 无边框窗口 + +无边框窗口指的是不包含除页面本身以外任何其它可视部分的窗口([chrome](https://developer.mozilla.org/en-US/docs/Glossary/Chrome))。 +像工具栏,是窗口的一部分,但并不属于页面。这些是[`BrowserWindow`](browser-window.md) 类的选项。 + +## 创建无边框窗口 + +为了创建一个无边框窗口,你需要设置[BrowserWindow](browser-window.md)的`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或者更新的版本中,有一个替代方案去生成一个无边框窗口。 +不同于设置`frame`为`false`会隐藏标题栏以及失去对窗口的控制,你可能想隐藏标题栏使你的页面内容显示在整个窗口上 +,同时又想保持对窗口的控制("traffic lights")。你可以通过指定`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/electron/electron/issues/1335)。 +* 透明窗口是不可调整大小的。在某些平台上,设置`resizable`为`true`也许会造成这个透明窗口停止工作。 +* `blur`滤光器器只适用于网页,所以没法将模糊效果用于窗口之下(i.e. 其它在用户的系统中打开的应用)。 +* 在Windows系统中,当DWM被禁用时透明窗口不会工作。 +* Linux用户需要在命令行中输入`--enable-transparent-visuals --disable-gpu` + 去禁用GPU以及允许ARGB去渲染透明窗口,这是由于一个Linux上的上游bug[alpha channel doesn't work on some + NVidia drivers](https://code.google.com/p/chromium/issues/detail?id=369209)造成的 +* 在Mac上,透明窗口的阴影不会显示出来. + +## 可拖动区域 + +默认情况下,无边框窗口是不可拖动的。应用在CSS中设置`-webkit-app-region: drag` +告诉Electron哪个区域是可拖动的(比如系统标准的标题栏),应用也可以设置`-webkit-app-region: no-drag` +在可拖动区域中排除不可拖动的区域。需要注意的是,目前只支持矩形区域。 + +为了让整个窗口可拖动,你可以在`body`的样式中添加`-webkit-app-region: drag`: + +```html + + +``` + +另外需要注意的是,如果你设置了整个窗口可拖动,你必须标记按钮为不可拖动的(non-draggable), +否则用户不能点击它们: + +```css +button { + -webkit-app-region: no-drag; +} +``` + +如果你设置一个自定义的标题栏可拖动,你同样需要设置标题栏中所有的按钮为不可拖动(non-draggable)。 + +## 文本选择 + +在一个无边框窗口中,拖动动作会与文本选择发生冲突。比如,当你拖动标题栏,偶尔会选中标题栏上的文本。 +为了防止这种情况发生,你需要向下面这样在一个可拖动区域中禁用文本选择: + +```css +.titlebar { + -webkit-user-select: none; + -webkit-app-region: drag; +} +``` + +## 上下文菜单 + +在一些平台上,可拖动区域会被认为是非客户端框架(non-client frame),所有当你点击右键时,一个系统菜单会弹出。 +为了保证上下文菜单在所有平台下正确的显示,你不应该在可拖动区域使用自定义上下文菜单。 + From 1240c83e40c925d643af7f20f6cc137a092f7ddb Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 18 Apr 2016 21:05:33 +0530 Subject: [PATCH 015/141] set trust bits for CA certs --- atom/browser/api/atom_api_app.cc | 89 +++++++++---------- atom/browser/api/atom_api_app.h | 7 +- atom/browser/atom_browser_client.cc | 1 - .../browser/certificate_manager_model.cc | 12 +-- .../browser/certificate_manager_model.h | 7 +- 5 files changed, 55 insertions(+), 61 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 4cbae0885e9a..1446d44ad006 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -15,10 +15,11 @@ #include "atom/browser/browser.h" #include "atom/browser/login_handler.h" #include "atom/common/native_mate_converters/callback.h" -#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/native_mate_converters/net_converter.h" +#include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/node_includes.h" #include "atom/common/options_switches.h" #include "base/command_line.h" @@ -158,41 +159,35 @@ void PassLoginInformation(scoped_refptr login_handler, login_handler->CancelAuth(); } -net::CertificateList ImportCertsFromFile( - const base::FilePath& path) { - net::CertificateList certs; - if (path.empty()) - return certs; - - std::string cert_data; - if (!base::ReadFileToString(path, &cert_data)) - return certs; - - certs = net::X509Certificate::CreateCertificateListFromBytes( - cert_data.data(), cert_data.size(), - net::X509Certificate::FORMAT_AUTO); - - return certs; -} - -int ImportCertificateIntoCertStore( +int ImportIntoCertStore( CertificateManagerModel* model, - const base::FilePath& path, - const base::FilePath& ca_path, - const base::string16& password) { - LOG(WARNING) << "importing ...."; + const base::DictionaryValue& options) { + std::string file_data, cert_path; + base::string16 password; + net::CertificateList imported_certs; + int rv; + options.GetString("clientCertificate", &cert_path); + options.GetString("password", &password); - std::string file_data; - int result = -1; - net::CertificateList ca_certs; - net::NSSCertDatabase::ImportCertFailureList not_imported; - auto module = model->cert_db()->GetPublicModule(); - if (base::ReadFileToString(path, &file_data)) { - result &= model->ImportFromPKCS12(module, file_data, password, true); - ca_certs = ImportCertsFromFile(ca_path); - result &= model->ImportCACerts(ca_certs, net::NSSCertDatabase::TRUST_DEFAULT, ¬_imported); + if (!cert_path.empty()) { + if (base::ReadFileToString(base::FilePath(cert_path), &file_data)) { + auto module = model->cert_db()->GetPublicModule(); + rv = model->ImportFromPKCS12(module, + file_data, + password, + true, + &imported_certs); + if (imported_certs.size() > 1) { + auto it = imported_certs.begin(); + ++it; // skip first which would be the client certificate. + for (; it != imported_certs.end(); ++it) + rv &= model->SetCertTrust(it->get(), + net::CA_CERT, + net::NSSCertDatabase::TRUSTED_SSL); + } + } } - return result; + return rv; } } // namespace @@ -408,30 +403,30 @@ bool App::MakeSingleInstance( } void App::ImportClientCertificate( - const base::FilePath& path, - const base::FilePath& ca_path, - - const base::string16& password, + const base::DictionaryValue& options, const net::CompletionCallback& callback) { auto browser_context = AtomBrowserMainParts::Get()->browser_context(); if (!certificate_manager_model_) { - CertificateManagerModel::Create(browser_context, base::Bind(&App::OnCertificateManagerModelCreated, base::Unretained(this), path, ca_path, password, callback)); + scoped_ptr copy = options.CreateDeepCopy(); + CertificateManagerModel::Create(browser_context, + base::Bind(&App::OnCertificateManagerModelCreated, + base::Unretained(this), + base::Passed(©), + callback)); return; } - int rv = ImportCertificateIntoCertStore(certificate_manager_model_.get(), path, ca_path, password); + int rv = ImportIntoCertStore(certificate_manager_model_.get(), options); callback.Run(rv); } void App::OnCertificateManagerModelCreated( - const base::FilePath& path, - const base::FilePath& ca_path, - const base::string16& password, + scoped_ptr options, const net::CompletionCallback& callback, scoped_ptr model) { certificate_manager_model_ = std::move(model); - - int rv = ImportCertificateIntoCertStore(certificate_manager_model_.get(), path, ca_path, password); + int rv = ImportIntoCertStore(certificate_manager_model_.get(), + *(options.get())); callback.Run(rv); } @@ -474,8 +469,10 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("allowNTLMCredentialsForAllDomains", &App::AllowNTLMCredentialsForAllDomains) .SetMethod("getLocale", &App::GetLocale) - .SetMethod("makeSingleInstance", &App::MakeSingleInstance) - .SetMethod("importClientCertificate", &App::ImportClientCertificate); +#if defined(OS_LINUX) + .SetMethod("importClientCertificate", &App::ImportClientCertificate) +#endif + .SetMethod("makeSingleInstance", &App::MakeSingleInstance); } // static diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index b5c797df0030..ce66daedf100 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -44,9 +44,7 @@ class App : public AtomBrowserClient::Delegate, int render_frame_id); void OnCertificateManagerModelCreated( - const base::FilePath& path, - const base::FilePath& ca_path, - const base::string16& password, + scoped_ptr options, const net::CompletionCallback& callback, scoped_ptr model); @@ -106,7 +104,8 @@ class App : public AtomBrowserClient::Delegate, bool MakeSingleInstance( const ProcessSingleton::NotificationCallback& callback); std::string GetLocale(); - void ImportClientCertificate(const base::FilePath& path, const base::FilePath& ca_path, const base::string16& password, const net::CompletionCallback& callback); + void ImportClientCertificate(const base::DictionaryValue& options, + const net::CompletionCallback& callback); #if defined(OS_WIN) bool IsAeroGlassEnabled(); diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index ddefd0688a2a..f4add58e3a89 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -37,7 +37,6 @@ #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "content/public/common/web_preferences.h" -#include "net/cert/x509_certificate.h" #include "net/ssl/ssl_cert_request_info.h" #include "ppapi/host/ppapi_host.h" #include "ui/base/l10n/l10n_util.h" diff --git a/chromium_src/chrome/browser/certificate_manager_model.cc b/chromium_src/chrome/browser/certificate_manager_model.cc index 83ab12af7609..b0db6edc357c 100644 --- a/chromium_src/chrome/browser/certificate_manager_model.cc +++ b/chromium_src/chrome/browser/certificate_manager_model.cc @@ -7,10 +7,8 @@ #include #include "base/bind.h" -#include "base/i18n/time_formatting.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_context.h" @@ -20,7 +18,6 @@ #include "net/base/net_errors.h" #include "net/cert/nss_cert_database.h" #include "net/cert/x509_certificate.h" -#include "ui/base/l10n/l10n_util.h" using content::BrowserThread; @@ -64,8 +61,6 @@ net::NSSCertDatabase* GetNSSCertDatabaseForResourceContext( // GetNSSCertDatabaseForResourceContext // | // CertificateManagerModel::DidGetCertDBOnIOThread -// | -// crypto::IsTPMTokenEnabledForNSS // v--------------------------------------/ // CertificateManagerModel::DidGetCertDBOnUIThread // | @@ -100,9 +95,10 @@ CertificateManagerModel::~CertificateManagerModel() { int CertificateManagerModel::ImportFromPKCS12(net::CryptoModule* module, const std::string& data, const base::string16& password, - bool is_extractable) { + bool is_extractable, + net::CertificateList* imported_certs) { return cert_db_->ImportFromPKCS12(module, data, password, - is_extractable, NULL); + is_extractable, imported_certs); } int CertificateManagerModel::ImportUserCert(const std::string& data) { @@ -121,7 +117,7 @@ bool CertificateManagerModel::ImportServerCert( net::NSSCertDatabase::TrustBits trust_bits, net::NSSCertDatabase::ImportCertFailureList* not_imported) { return cert_db_->ImportServerCert(certificates, trust_bits, - not_imported); + not_imported); } bool CertificateManagerModel::SetCertTrust( diff --git a/chromium_src/chrome/browser/certificate_manager_model.h b/chromium_src/chrome/browser/certificate_manager_model.h index bd0d5ddfb291..1eb350876803 100644 --- a/chromium_src/chrome/browser/certificate_manager_model.h +++ b/chromium_src/chrome/browser/certificate_manager_model.h @@ -44,8 +44,11 @@ class CertificateManagerModel { // |data|, using the given |password|. If |is_extractable| is false, // mark the private key as unextractable from the module. // Returns a net error code on failure. - int ImportFromPKCS12(net::CryptoModule* module, const std::string& data, - const base::string16& password, bool is_extractable); + int ImportFromPKCS12(net::CryptoModule* module, + const std::string& data, + const base::string16& password, + bool is_extractable, + net::CertificateList* imported_certs); // Import user certificate from DER encoded |data|. // Returns a net error code on failure. From 5a9b86dd051c761473e192a1ab8ee681da28c79a Mon Sep 17 00:00:00 2001 From: Ray Booysen Date: Mon, 18 Apr 2016 17:04:47 +0100 Subject: [PATCH 016/141] Update screen.md --- docs/api/screen.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/screen.md b/docs/api/screen.md index 61210c9e119b..4d12f1359f7f 100644 --- a/docs/api/screen.md +++ b/docs/api/screen.md @@ -1,8 +1,8 @@ # screen The `screen` module retrieves information about screen size, displays, cursor -position, etc. You should not use this module until the `ready` event of the -`app` module is emitted. +position, etc. You cannot not use this module until the `ready` event of the +`app` module is emitted (by invoking or requiring it). `screen` is an [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter). From 2ddac9352f48aa6ae386f8b1d001fe4b6c2ff2fd Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 18 Apr 2016 21:53:44 +0530 Subject: [PATCH 017/141] add spec --- spec/api-app-spec.js | 61 +++++++++ spec/fixtures/certificates/certs.cnf | 68 ++++++++++ spec/fixtures/certificates/client.p12 | Bin 0 -> 4149 bytes spec/fixtures/certificates/generate_certs.sh | 127 ++++++++++++++++++ spec/fixtures/certificates/intermediateCA.pem | 78 +++++++++++ spec/fixtures/certificates/rootCA.pem | 19 +++ spec/fixtures/certificates/server.key | 27 ++++ spec/fixtures/certificates/server.pem | 88 ++++++++++++ 8 files changed, 468 insertions(+) create mode 100644 spec/fixtures/certificates/certs.cnf create mode 100644 spec/fixtures/certificates/client.p12 create mode 100755 spec/fixtures/certificates/generate_certs.sh create mode 100644 spec/fixtures/certificates/intermediateCA.pem create mode 100644 spec/fixtures/certificates/rootCA.pem create mode 100644 spec/fixtures/certificates/server.key create mode 100644 spec/fixtures/certificates/server.pem diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index c237ef17238e..1f5452713bce 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -1,5 +1,7 @@ const assert = require('assert') const ChildProcess = require('child_process') +const https = require('https') +const fs = require('fs') const path = require('path') const remote = require('electron').remote @@ -87,6 +89,65 @@ describe('app module', function () { }) }) + describe('app.importClientCertificate', function () { + if (process.platform !== 'linux') + return + + this.timeout(5000) + + var port + var w = null + var certPath = path.join(__dirname, 'fixtures', 'certificates') + var options = { + key: fs.readFileSync(path.join(certPath, 'server.key')), + cert: fs.readFileSync(path.join(certPath, 'server.pem')), + ca: [ + fs.readFileSync(path.join(certPath, 'rootCA.pem')), + fs.readFileSync(path.join(certPath, 'intermediateCA.pem')) + ], + requestCert: true, + rejectUnauthorized: false + } + + var server = https.createServer(options, function (req, res) { + if (req.client.authorized) { + res.writeHead(200); + res.end('authorized'); + } + }) + server.listen(0, '127.0.0.1', function () { + port = server.address().port + }) + + afterEach(function () { + if (w != null) { + w.destroy() + } + w = null + }) + + it('can import certificate into platform cert store', function (done) { + let options = { + clientCertificate: path.join(certPath, 'client.p12'), + password: 'electron' + } + + w = new BrowserWindow({ + show: false + }) + + w.webContents.on('did-finish-load', function () { + server.close() + done() + }) + + app.importClientCertificate(options, function (result) { + assert(!result) + w.loadURL(`https://127.0.0.1:${port}`) + }) + }) + }) + describe('BrowserWindow events', function () { var w = null diff --git a/spec/fixtures/certificates/certs.cnf b/spec/fixtures/certificates/certs.cnf new file mode 100644 index 000000000000..d8b5c66e13a1 --- /dev/null +++ b/spec/fixtures/certificates/certs.cnf @@ -0,0 +1,68 @@ +ID=1 +CA_DIR=out + +[ca] +default_ca = ca_settings + +[ca_settings] +dir = ${ENV::CA_DIR} +database = $dir/${ENV::ID}-index.txt +new_certs_dir = $dir +serial = $dir/${ENV::ID}-serial +certificate = $dir/${ENV::ID}.pem +private_key = $dir/${ENV::ID}.key +RANDFILE = $dir/rand +default_md = sha256 +default_days = 3650 +policy = policy_anything +preserve = no + +[policy_anything] +# Default signing policy +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[req] +default_bits = 2048 +default_md = sha256 +string_mask = utf8only +distinguished_name = req_env_dn +prompt = no + +[user_cert] +basicConstraints = CA:FALSE +nsCertType = client +nsComment = "OpenSSL Generated Client Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer +keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, emailProtection + +[server_cert] +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth + +[ca_cert] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ca_intermediate_cert] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[req_env_dn] +commonName = ${ENV::COMMON_NAME} diff --git a/spec/fixtures/certificates/client.p12 b/spec/fixtures/certificates/client.p12 new file mode 100644 index 0000000000000000000000000000000000000000..7543c7d38904f15708eae001c285f1ab6be1e6e1 GIT binary patch literal 4149 zcmV-55X$c`f)FtR0Ru3C5BCNMDuzgg_YDCD0ic2p=mdffE{;4p#;mj($chDe6@ z4FLxRpn?jBFoFt%0s#Opf(m^G2`Yw2hW8Bt2LUh~1_~;MNQUF3F= zrMuDyw~)Pkq#adbSV(Y%UB63E+6)h}f>+2?;YYypermyCaxN<2p&&1cl7kL+XSsN< z+e6Ls9-OsIq1WTd*QkEiWo?SXhH>Em>lchy(B7e*fujcM8dCH#8LZ{t9n)&!g+)wk z?}NBil+rq<$zgZL7S`@RY1?XZ8C_>ERVa0D;|2u!N}pQs3m2r^E4~Lx2-kcb?Axh| zC;+s!kzZ~53{w54{3IAuOK2yn(FwSOB$qU}X8CkSBOj4X1k8E0gzXI>hD2y45T^@`sA472*6o%ZEea212_5>qYA_6ho%C# z7aTh~b&UXJroNwL-%5&YkPa5e%GTSw5GYHL-OAL$*XB@9ciJHKpqVRoth|ZvI^OAk&P2=D8Dl72|)3|y@gD>kJ;vk2sOe-7zR=zg zt056nJ#HEV?6&}iE^s{rgzBg2Q<}JXr;*KVg;-KjEDda~==?G^(|w5CqXJ`9VbV7v zaYPVc@fC>Ei|vxAN(3oAo!+IrQ;+2rNVonPDd=>t_0!n#Bolh`uA_x8hhgPaZgDtfIfpgE3 zD3MF#m1*04>{BvMHp1$AQB|<{DnnIQE6hX7u5~tR6Ro#lzVXa3RCezu>-5z==awi% z3OgbvC2BU?*l8-Ca3voL;0y?JEzSkLSmVfJ3xn$(!J)x(>+1iEfTQv5w+)VvU@;zt zuzp~|FEaJ!v>etO;jfKUH!4o(63t^}GrcAv$HY}Wq#(C$Saqk5u= zSOs0A*_u_qSmnjEYA+$l;OIlk@`ofo{KUf#)y>bCM`(Jvh0CpjZvck@x|qfF7ZeWI zC(G2wert-(Ix>8?`XS2oYJyDXiK|YHH;U=w98a{C0S#R11cYRPle^+z=1Df&V6!aU z9%2VdDhy`n+gk%K*V#tTA#lZ~8b1i#V} zIbWHdm&YPMs(PIAyUN}USC^SoUzVXwPz#CrUzc56B!X(m-MzPi-lqA}n%$-Ow;?lO zHsZ5M-lNjpQfTC7qT+mqM4O(rCbTTSIX_6D2-L9tEOD_3;^vI)Vg=1hP|qJS3#H=3ZobI=kBB$u@m+t+;}{B3}s8?SvHs9*CsbO#*~u6vO^hTs0u zYtB8#r2PTRl-PS|@MyJvzJN1nM4eW@kk2awF7%QExl>A23CN+I z#E`3|1*hbizIPds&K@|Wep(X^420H@kijXtuI*6=#kjrFj$T^cfu66H+xC4-O622G#dguYNyN;biZ;*)&&H%P^!m#T59hD~-=!+c zxZOxy#sLY5PnTHdPh+%c8)Hx&ck80v&J@Q1BwZ-bzt_DF=)S_0VLAy$-J1i1*1!aJ zI`B&5wDs*sKgRIAeB#?!XdOqW3@PuP0esQ> zX9&wYN~}98A1%=AY?l!09Xkj|Hrxv;*VP6)ITD+Afpjjy=K~sxfsZTSyFYR~txkG! zh|e3%0=?Fs>k*Ou!4~RuE+T@|4&l?gh)m`{T6c=Mj8G_95@D;QN;7|OlxRC))#+pH z2o*2KSl;B{oSZ;A+#JJP#%=f0Mv#YB=&uA3r4)Yi_MUBnC%QSrZe4n0K;k(gv}o6> zpk>3qg7{VpA3ZwKHUXR74pY{kT+MO(+xAPEATo&LNQUKp6Pi^FD$P3Fi?OyZYbezlXv^f$?3z{m3aiG#2rl8ouugO* zQYs5CT~wtC3Ot2W%thvfckvV}$+4p$EOb08US5h1 zz3yqKHxK-m56o&ZAb?UE5Rt+YEFuSOnCTe&AevZ7pnCcjs3b=kiu`=tnBuBhh!N`9 z9R(J9h471>P_paPON$I>5loSmmM85b(*WOLDiwE)DA?(GC`R}!I&rf0Yc)DTBPxKC z=uqK19;q^VPqGOmdFOc#8>kvkWwE^9FXH3x@7w=2 z6DDu>eAM|Z%Sf|g6Y-f&)m3_WQ^dJjPe7po&D8{@1M(GFI-1;THI@MMecA(WfRf3f zLGW_?-8qsa5;1gkL9~q?3UKuYk+9{Ok!+l~5Rzp1o`Sgd>IY_d^@g8vS%)+q z0*URWNp2tE<^R_)%#V)ycU#*KCKUq^dR!?wSH7`^x4YK!a~^D`5$!swtI4=mjfcNq zv=?Fz80Zr7pXZ@>C{x3Wv@NNU{4L5WBL$LkG3^EN)#z0 z=4>sCn5!SBJ+|SfV&@T|9E3C4bJyTaGMdDOa_x9MI>2(@-xynmt8U#8_pYw?M&9aN zU6FUL$hhlMbmC1X91%l0dGapPmtsXtVr_yamKbb7*w*3BpL|nk@mX-4-;S#;%Lnv= zPsNabwpH`wRm_XGsF=I$WR2`YUDmB28j`ffR|kh`<4~fM+{qd{w?w8v#cz6Q$Erhx z!JLOo!`XkWKH|~YGVN%6bqQ+aB|kcpJ`J-csOTxYl!mGht3DIGO~_f|W@m`Tmr#6RI<4Bw4~jT|l++n;ecj`%>P%6n_{8wU(vT^9~kE zHwpcuLy1S%X0@2W-ou5*Ed8oXUNVPdD3%;^p1Q{K0<=Ctcmze&+_9(O2J5(otJp?C z*|c`bW^7+i;qQ!(joO9W++koYlK``1rz@DgU)crV#M-Sq7vnXG^qger%!&2LG3I!lhBm&3@t6*}QAA zKfRYWMvfRx=Wai4>hLm7^li2$9th`-zBy*pUBNeoV|A6;TU-a%FQblv`u};DsTQ^+ zFq5B5Yz}S0i@m$~19<2hlw>kk<4X4bb| zcJUWZRB3q);`E^S(#0h%S;0&YH zivvjX{?rw0OCm8PFe3&DDuzgg_YDCF6)_eB6p+0r>6Y%e B -> C (self-signed root) +# 2. D (end-entity) -> B -> C (self-signed root) + +try () { + echo "$@" + "$@" || exit 1 +} + +try mkdir out + +echo Create the serial number files and indices. +serial=1000 +for i in B C +do + try /bin/sh -c "echo $serial > out/$i-serial" + serial=$(expr $serial + 1) + touch out/$i-index.txt + touch out/$i-index.txt.attr +done + +echo Generate the keys. +for i in A B C D +do + try openssl genrsa -out out/$i.key 2048 +done + +echo Generate the C CSR +COMMON_NAME="Root CA" \ + CA_DIR=out \ + ID=C \ + try openssl req \ + -new \ + -key out/C.key \ + -out out/C.csr \ + -config certs.cnf + +echo C signs itself. +COMMON_NAME="Root CA" \ + CA_DIR=out \ + ID=C \ + try openssl x509 \ + -req -days 3650 \ + -in out/C.csr \ + -extensions ca_cert \ + -extfile certs.cnf \ + -signkey out/C.key \ + -out out/C.pem + +echo Generate the intermediates +COMMON_NAME="Intermediate CA" \ + CA_DIR=out \ + ID=B \ + try openssl req \ + -new \ + -key out/B.key \ + -out out/B.csr \ + -config certs.cnf + +COMMON_NAME="Root CA" \ + CA_DIR=out \ + ID=C \ + try openssl ca \ + -batch \ + -extensions ca_intermediate_cert \ + -in out/B.csr \ + -out out/B.pem \ + -config certs.cnf + +echo Generate the leaf certs +COMMON_NAME="Client Cert" \ + ID=A \ + try openssl req \ + -new \ + -key out/A.key \ + -out out/A.csr \ + -config certs.cnf + +echo B signs A +COMMON_NAME="Intermediate CA" \ + CA_DIR=out \ + ID=B \ + try openssl ca \ + -batch \ + -extensions user_cert \ + -in out/A.csr \ + -out out/A.pem \ + -config certs.cnf + +COMMON_NAME="localhost" \ + ID=D \ + try openssl req \ + -new \ + -key out/D.key \ + -out out/D.csr \ + -config certs.cnf + +echo B signs D +COMMON_NAME="Intermediate CA" \ + CA_DIR=out \ + ID=B \ + try openssl ca \ + -batch \ + -extensions server_cert \ + -in out/D.csr \ + -out out/D.pem \ + -config certs.cnf + +echo Package the client cert and private key into PKCS12 file +try /bin/sh -c "cat out/A.pem out/A.key out/B.pem out/C.pem > out/A-chain.pem" + +try openssl pkcs12 \ + -in out/A-chain.pem \ + -out client.p12 \ + -export \ + -passout pass:electron + +echo Package the certs +try cp out/C.pem rootCA.pem +try cp out/B.pem intermediateCA.pem +try cp out/D.key server.key +try cp out/D.pem server.pem + +try rm -rf out diff --git a/spec/fixtures/certificates/intermediateCA.pem b/spec/fixtures/certificates/intermediateCA.pem new file mode 100644 index 000000000000..58293f76da0b --- /dev/null +++ b/spec/fixtures/certificates/intermediateCA.pem @@ -0,0 +1,78 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4097 (0x1001) + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=Root CA + Validity + Not Before: Apr 18 16:14:29 2016 GMT + Not After : Apr 16 16:14:29 2026 GMT + Subject: CN=Intermediate CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b6:42:02:13:25:40:13:a6:05:99:69:da:0c:c9: + a8:bf:86:3b:fc:c6:51:ba:64:65:7e:33:11:31:d5: + 03:45:30:4c:ca:49:d2:96:42:52:2f:f9:e6:6c:9a: + 50:1c:fe:fa:e2:e8:63:36:14:47:f7:49:9f:78:28: + 5e:1f:0b:9d:9e:f8:d3:33:77:06:4d:6d:14:c0:57: + 01:83:2b:ef:99:06:48:21:ec:c1:d7:05:48:2c:ea: + 83:06:6a:20:df:73:ce:8a:a5:e4:81:00:41:84:cf: + 89:81:78:2e:3a:bd:1b:fd:3e:96:08:8d:44:1b:00: + c8:d6:4e:7a:6a:75:c0:9b:3c:e0:fa:aa:3a:82:5b: + 3c:39:32:ca:4a:ba:82:bc:60:47:6f:e4:4a:fd:dc: + a0:72:8a:1b:fe:cd:2e:10:f4:27:4c:08:4e:d1:ed: + dc:08:b0:f8:1f:e4:fc:45:72:43:58:6e:dd:05:37: + 8c:04:a1:fb:64:f4:3f:90:bb:85:f2:4c:97:46:fd: + 1f:29:e5:19:d0:0f:24:fd:d1:00:c5:b6:be:da:84: + 62:77:be:db:67:f6:ec:98:5d:97:f5:df:0a:bd:b8: + 07:7f:0a:d5:92:29:1f:c4:b0:97:4f:e4:87:d7:a9: + 00:c9:61:d5:6c:cd:6a:fc:56:c3:f3:b7:ca:53:70: + 02:3f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + A9:75:99:CF:9C:92:54:A4:4B:65:CD:3D:FC:93:98:8D:9E:09:1F:47 + X509v3 Authority Key Identifier: + keyid:E3:51:87:E3:CD:7A:B3:26:9F:8F:EC:62:D1:0E:15:0C:39:36:47:4F + + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + Signature Algorithm: sha256WithRSAEncryption + 55:69:d6:1d:33:ad:ab:40:46:fd:34:02:c1:43:50:7b:90:ea: + f3:5f:4f:b6:2c:28:aa:72:e0:4b:36:2e:8f:44:93:15:52:14: + f6:61:b3:50:e0:ba:43:91:ba:a9:5d:ac:43:b7:52:ca:91:a3: + d7:0e:ac:a7:9e:ee:28:7f:2d:0f:93:b5:d9:23:35:68:54:29: + 2a:e7:3a:4c:41:24:d0:5e:2d:f3:1e:b9:52:f1:3e:16:76:93: + 89:6d:a1:4c:63:f5:4a:cc:08:36:61:29:0a:29:5f:f4:5a:55: + 98:10:b3:de:b3:90:f9:03:e5:bd:1b:61:01:a7:22:03:ae:0f: + 77:c4:a8:bf:31:b4:af:c8:c7:e3:25:a1:2b:b9:43:37:3b:08: + ea:c4:46:60:b8:5f:ee:2a:0d:ce:18:75:63:ba:32:28:84:f4: + 56:95:1b:c5:f9:46:7e:14:2e:83:5e:a9:ff:b2:80:ca:25:fd: + 22:90:b5:de:bd:e6:f1:0c:ee:7e:09:71:0d:82:6a:ca:2f:9c: + 96:45:73:3a:65:bc:d8:9d:e0:61:01:5d:a8:de:de:61:8c:82: + 52:0c:ef:97:39:b3:13:c6:7d:d0:c0:f5:6d:c8:70:5b:96:e8: + 99:31:d8:75:3a:21:58:ab:01:21:9e:38:8e:53:ff:f8:48:a7: + af:01:9a:93 +-----BEGIN CERTIFICATE----- +MIIDDjCCAfagAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHUm9v +dCBDQTAeFw0xNjA0MTgxNjE0MjlaFw0yNjA0MTYxNjE0MjlaMBoxGDAWBgNVBAMM +D0ludGVybWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALZCAhMlQBOmBZlp2gzJqL+GO/zGUbpkZX4zETHVA0UwTMpJ0pZCUi/55myaUBz+ ++uLoYzYUR/dJn3goXh8LnZ740zN3Bk1tFMBXAYMr75kGSCHswdcFSCzqgwZqIN9z +zoql5IEAQYTPiYF4Ljq9G/0+lgiNRBsAyNZOemp1wJs84PqqOoJbPDkyykq6grxg +R2/kSv3coHKKG/7NLhD0J0wITtHt3Aiw+B/k/EVyQ1hu3QU3jASh+2T0P5C7hfJM +l0b9HynlGdAPJP3RAMW2vtqEYne+22f27Jhdl/XfCr24B38K1ZIpH8Swl0/kh9ep +AMlh1WzNavxWw/O3ylNwAj8CAwEAAaNmMGQwHQYDVR0OBBYEFKl1mc+cklSkS2XN +PfyTmI2eCR9HMB8GA1UdIwQYMBaAFONRh+PNerMmn4/sYtEOFQw5NkdPMBIGA1Ud +EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IB +AQBVadYdM62rQEb9NALBQ1B7kOrzX0+2LCiqcuBLNi6PRJMVUhT2YbNQ4LpDkbqp +XaxDt1LKkaPXDqynnu4ofy0Pk7XZIzVoVCkq5zpMQSTQXi3zHrlS8T4WdpOJbaFM +Y/VKzAg2YSkKKV/0WlWYELPes5D5A+W9G2EBpyIDrg93xKi/MbSvyMfjJaEruUM3 +OwjqxEZguF/uKg3OGHVjujIohPRWlRvF+UZ+FC6DXqn/soDKJf0ikLXevebxDO5+ +CXENgmrKL5yWRXM6ZbzYneBhAV2o3t5hjIJSDO+XObMTxn3QwPVtyHBbluiZMdh1 +OiFYqwEhnjiOU//4SKevAZqT +-----END CERTIFICATE----- diff --git a/spec/fixtures/certificates/rootCA.pem b/spec/fixtures/certificates/rootCA.pem new file mode 100644 index 000000000000..5c77fe61cd0f --- /dev/null +++ b/spec/fixtures/certificates/rootCA.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCjCCAfKgAwIBAgIJAOcWbv0WHll0MA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV +BAMMB1Jvb3QgQ0EwHhcNMTYwNDE4MTYxNDI5WhcNMjYwNDE2MTYxNDI5WjASMRAw +DgYDVQQDDAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +0iZvelv6MjxqdmQsAmKqIfc5gvQjYB3CqWlEH3g5czPFBMMtmOI9czlk+0jc1VEf +t1SKst7zwe1rpxFArgudV45NBHQH3ZlzkLeO7Ol2kPzlyMHNJ70vT3CBitKnLl4B +bg7xf6kDQQlC3/QeWxvbR5cvp131uwcpXKdJ9k4dwpfS2BKiRb5Uk46DgX5kGaka +q/tQ2F7b6AlAoTq608tZBuOInkg2tTbGe9PDWSL8oMZRwCSbF543SAR45zjWBa0k +ymY31VvlYbEd/3lfE5Mrn/JwZQpTKOfcOI//kUkcClJVpSMObh4eiy1oNjqcJ4KR +/4hkY7oTQCA7zWD34jQpkQIDAQABo2MwYTAdBgNVHQ4EFgQU41GH4816syafj+xi +0Q4VDDk2R08wHwYDVR0jBBgwFoAU41GH4816syafj+xi0Q4VDDk2R08wDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggEBADrt +1bSbOYxDmB1x9KaHNFVSzs0XsipsbZW/XTqtNMPMFXh+I57NVptVanCwcfU5zmOF +AjL+R8v0NkPU9+6nSM2PYqWxEavf0f6pkxIj+ThFwtVwXEKocPG9RFUvZNZv+rSH +yAnzuAzFI71EsT9VgJGHI0pgPjrGbSlNfb0OJFOlwtbGWGofmg+N6hHcx5nVKlgL +ZWLtYT+/mT2pSGuIpJtdnuUv0vcrRa4mxAa8NPF4+Qpi6yErkfogE+T4RYf2L4rp +CaRIFicLoNUmwK0nCerJaPFLwGkiNGNX81CHnw3+xLisSPvxze2ZRA0DhUWUGInq +grjWDMO9P1hPWu5jmbo= +-----END CERTIFICATE----- diff --git a/spec/fixtures/certificates/server.key b/spec/fixtures/certificates/server.key new file mode 100644 index 000000000000..719bfc8797df --- /dev/null +++ b/spec/fixtures/certificates/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAuByk7Ib6anz0xOFRqyogGsTTEAAGduquIckVFajDHrk7vdq+ +TflkDp+UhbISqu1rj0OuaqODxiPSSw5fHClqNKpjhHS1ry86knS847BGwrByY0oa +zBdN0UgtWiXOK+iCuSI9p0KSIORJ3Y70pUZmm12EHRwb0tANv4ogYxjAxwnyqYgn +PnrDsoyCh/Cb4Fu8XucrnepYbInXi6yOdwTuivTx9qy7tlQzvYJ2LLEUIJdBtCUZ +dZkxky9CJUbfu5rm6PFvbLII5YCSlpXLxg9bumZCR1z9IXE6rLYcJIp3HIquR2cN +tAs9M8OHuR5V6vhUG51bP3aTkg3asJVdUe10dwIDAQABAoIBAQCJGINSwZv86blW +VbX7r+2iIUhNVMd7i3tJGzQBId7RpPswf49P/tIb9YaiG5y8/PgoAS0CqWn5hDkW +vMfj747vUqWyPzn/DjseTaFOJrg6RyuWddsIeJ3wpj9nLlmc5pFZDH8+alrn9TZv +rgDMhWTocjVre7/YNibWpyNAx3DdhG5DzNVLnu1R68d5k3JutQVqm01xCAV9ne9n +xE1RB5Z1xLvpQfW2qLYT0yFB7Xxw8awGyzVesPhGW1aa5F4urQjdCt2baa06Xolu +T3wXJ6wA9BuF2KOCi8DxELDaXoB//+82HafgWbOWIhJFOzEZaMNqZkfS/GbCgpEr +mE2r8zGBAoGBAOHNcUPgnIIeGdgFZZvL3Ge3Hp5mi2Vd2KBkAPNCjVSXeCu57yRC +SetlYuZlIhd7o+wdxUmWtg73DU19eDXJsOjXgNAoJfT9Zsyi4RClmJ0FRcSzvFU/ +m/TKrBbnFFAI+1pKwDnQ7envuRiTECFSsvKqdr8hddx0cPCgDtbe+75BAoGBANC7 +4ozkgsUTtdojz0DYBYBwUjN1gUETIhl91tt+48hmmEedROWDQDCT9gJfpAVFe1I6 +RyKKJnBcgNDJ7mqPUB1f5xb5rtaZS1owPNYTi3GrdVVg3lAf0j5ch8XoRJn/plnL +M0Sj5lLMviHJjyk8CPHbnE2k2vERAW4/SgzfA3S3AoGAHx55Jamm6CfN1/+maTpH +PeP2zE3FmEq+uBwQJXZek/HsFdqiIpUgKtjmMGpvsFzR0pCnx+SFYrqZkrxf/Mm3 +H9/TWNyvnnvt1vX7npez2LAJVXqP0g/aJnpoDR/7pKwYN/FlXJJ2t27aS5C5AF6t +WtQzWVP7Mk654e+tG9/PQgECgYEAiTCT7EpccK9NvLwAgfv5UbuBK3U1qNGsfdip +mMZDa/mSaK9DEx462DLHZDP8F8LdFORc0KTAMuV5fMDbxInA/C2GMyGT+lPypKpD +sehSpDku+xiZxUvE4VvrmPXZ8OWILkhRv/GBdjY/WPGi+FUPA/d1Ocr6Y6rrp8xN +HTyOhu0CgYBKxTSH6RCQsm8Q8uqmcP7cwe6fciTC0c2CRRqlzuXeseG72MBRDk/8 +P1jtOIlIsax/8NwNm5ReAiLgVn/h6/YgN4fpMkV1XIaH4j7HiGf5CWgOTWxS9jWA +cV09H22BaNkT0fZ71IlXQI11cVRodX0g4cJXeuyTxY9OkMd6cGs8+A== +-----END RSA PRIVATE KEY----- diff --git a/spec/fixtures/certificates/server.pem b/spec/fixtures/certificates/server.pem new file mode 100644 index 000000000000..117be807e528 --- /dev/null +++ b/spec/fixtures/certificates/server.pem @@ -0,0 +1,88 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4097 (0x1001) + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=Intermediate CA + Validity + Not Before: Apr 18 16:14:29 2016 GMT + Not After : Apr 16 16:14:29 2026 GMT + Subject: CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b8:1c:a4:ec:86:fa:6a:7c:f4:c4:e1:51:ab:2a: + 20:1a:c4:d3:10:00:06:76:ea:ae:21:c9:15:15:a8: + c3:1e:b9:3b:bd:da:be:4d:f9:64:0e:9f:94:85:b2: + 12:aa:ed:6b:8f:43:ae:6a:a3:83:c6:23:d2:4b:0e: + 5f:1c:29:6a:34:aa:63:84:74:b5:af:2f:3a:92:74: + bc:e3:b0:46:c2:b0:72:63:4a:1a:cc:17:4d:d1:48: + 2d:5a:25:ce:2b:e8:82:b9:22:3d:a7:42:92:20:e4: + 49:dd:8e:f4:a5:46:66:9b:5d:84:1d:1c:1b:d2:d0: + 0d:bf:8a:20:63:18:c0:c7:09:f2:a9:88:27:3e:7a: + c3:b2:8c:82:87:f0:9b:e0:5b:bc:5e:e7:2b:9d:ea: + 58:6c:89:d7:8b:ac:8e:77:04:ee:8a:f4:f1:f6:ac: + bb:b6:54:33:bd:82:76:2c:b1:14:20:97:41:b4:25: + 19:75:99:31:93:2f:42:25:46:df:bb:9a:e6:e8:f1: + 6f:6c:b2:08:e5:80:92:96:95:cb:c6:0f:5b:ba:66: + 42:47:5c:fd:21:71:3a:ac:b6:1c:24:8a:77:1c:8a: + ae:47:67:0d:b4:0b:3d:33:c3:87:b9:1e:55:ea:f8: + 54:1b:9d:5b:3f:76:93:92:0d:da:b0:95:5d:51:ed: + 74:77 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Cert Type: + SSL Server + Netscape Comment: + OpenSSL Generated Server Certificate + X509v3 Subject Key Identifier: + 1D:60:82:FA:3A:EC:27:91:BA:8D:F5:ED:B2:E3:85:0B:22:5A:8E:38 + X509v3 Authority Key Identifier: + keyid:A9:75:99:CF:9C:92:54:A4:4B:65:CD:3D:FC:93:98:8D:9E:09:1F:47 + DirName:/CN=Root CA + serial:10:01 + + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication + Signature Algorithm: sha256WithRSAEncryption + 89:90:3d:2c:b8:0d:36:63:68:9a:cd:f9:14:56:94:d9:18:11: + b5:08:35:af:f9:34:cd:70:db:7d:66:06:e3:57:9b:06:8f:11: + d6:ea:ac:a6:07:db:ae:a2:c0:66:69:84:d8:2d:3c:cc:d7:4d: + 3c:75:60:4f:98:fc:56:df:30:39:c6:55:2c:73:92:9e:0c:b5: + 7c:75:40:5d:21:aa:01:c1:8a:03:86:eb:d7:02:7d:f5:7b:12: + cc:18:90:23:ad:8f:d7:05:18:6d:f0:11:a8:6b:27:fd:4c:07: + 07:53:f5:7f:f7:a2:e5:18:1e:4e:90:1b:10:5f:f3:5c:cb:c7: + 37:63:d0:d5:1d:3a:65:66:24:ee:0e:ce:7f:b1:fb:ee:17:d0: + b5:4d:64:2f:5a:9c:bc:7a:1c:c0:b4:0f:32:c9:a9:5c:cb:57: + 26:fd:49:39:8d:f2:89:54:c4:92:b5:35:ec:fe:cf:87:07:a6: + 84:01:98:00:e4:2a:44:26:b7:48:00:11:d3:e4:5a:c1:ad:46: + 36:53:f9:28:b7:e4:c5:bb:66:88:ab:8e:cc:30:d0:96:aa:3e: + c1:12:6a:8f:fa:6d:19:15:f4:90:66:54:62:84:97:06:2d:5c: + b9:18:71:90:f4:ca:4c:8c:a5:8b:32:14:93:89:f1:93:f4:00: + bd:1d:42:4f +-----BEGIN CERTIFICATE----- +MIIDgjCCAmqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAwwPSW50 +ZXJtZWRpYXRlIENBMB4XDTE2MDQxODE2MTQyOVoXDTI2MDQxNjE2MTQyOVowFDES +MBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuByk7Ib6anz0xOFRqyogGsTTEAAGduquIckVFajDHrk7vdq+TflkDp+UhbIS +qu1rj0OuaqODxiPSSw5fHClqNKpjhHS1ry86knS847BGwrByY0oazBdN0UgtWiXO +K+iCuSI9p0KSIORJ3Y70pUZmm12EHRwb0tANv4ogYxjAxwnyqYgnPnrDsoyCh/Cb +4Fu8XucrnepYbInXi6yOdwTuivTx9qy7tlQzvYJ2LLEUIJdBtCUZdZkxky9CJUbf +u5rm6PFvbLII5YCSlpXLxg9bumZCR1z9IXE6rLYcJIp3HIquR2cNtAs9M8OHuR5V +6vhUG51bP3aTkg3asJVdUe10dwIDAQABo4HXMIHUMAkGA1UdEwQCMAAwEQYJYIZI +AYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBT +ZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFB1ggvo67CeRuo317bLjhQsiWo44 +MDsGA1UdIwQ0MDKAFKl1mc+cklSkS2XNPfyTmI2eCR9HoRakFDASMRAwDgYDVQQD +DAdSb290IENBggIQATAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH +AwEwDQYJKoZIhvcNAQELBQADggEBAImQPSy4DTZjaJrN+RRWlNkYEbUINa/5NM1w +231mBuNXmwaPEdbqrKYH266iwGZphNgtPMzXTTx1YE+Y/FbfMDnGVSxzkp4MtXx1 +QF0hqgHBigOG69cCffV7EswYkCOtj9cFGG3wEahrJ/1MBwdT9X/3ouUYHk6QGxBf +81zLxzdj0NUdOmVmJO4Ozn+x++4X0LVNZC9anLx6HMC0DzLJqVzLVyb9STmN8olU +xJK1Nez+z4cHpoQBmADkKkQmt0gAEdPkWsGtRjZT+Si35MW7Zoirjsww0JaqPsES +ao/6bRkV9JBmVGKElwYtXLkYcZD0ykyMpYsyFJOJ8ZP0AL0dQk8= +-----END CERTIFICATE----- From 919be67cd2ad481668815d065174c88fff9e2343 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 18 Apr 2016 22:26:37 +0530 Subject: [PATCH 018/141] remove --client-certificate flag --- atom/browser/api/atom_api_app.cc | 7 +++---- atom/common/options_switches.cc | 3 --- atom/common/options_switches.h | 1 - docs/api/chrome-command-line-switches.md | 4 ---- 4 files changed, 3 insertions(+), 12 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 1446d44ad006..d6afbb366e04 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -179,11 +179,11 @@ int ImportIntoCertStore( &imported_certs); if (imported_certs.size() > 1) { auto it = imported_certs.begin(); - ++it; // skip first which would be the client certificate. + ++it; // skip first which would be the client certificate. for (; it != imported_certs.end(); ++it) rv &= model->SetCertTrust(it->get(), - net::CA_CERT, - net::NSSCertDatabase::TRUSTED_SSL); + net::CA_CERT, + net::NSSCertDatabase::TRUSTED_SSL); } } } @@ -491,7 +491,6 @@ void AppendSwitch(const std::string& switch_string, mate::Arguments* args) { auto command_line = base::CommandLine::ForCurrentProcess(); if (switch_string == atom::switches::kPpapiFlashPath || - switch_string == atom::switches::kClientCertificate || switch_string == switches::kLogNetLog) { base::FilePath path; args->GetNext(&path); diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index ce28cc98facf..562171d51f25 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -119,9 +119,6 @@ const char kPpapiFlashPath[] = "ppapi-flash-path"; // Ppapi Flash version. const char kPpapiFlashVersion[] = "ppapi-flash-version"; -// Path to client certificate. -const char kClientCertificate[] = "client-certificate"; - // Disable HTTP cache. const char kDisableHttpCache[] = "disable-http-cache"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 52d64c00d51a..5746a7bbfe54 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -68,7 +68,6 @@ namespace switches { extern const char kEnablePlugins[]; extern const char kPpapiFlashPath[]; extern const char kPpapiFlashVersion[]; -extern const char kClientCertificate[]; extern const char kDisableHttpCache[]; extern const char kRegisterStandardSchemes[]; extern const char kRegisterServiceWorkerSchemes[]; diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index 65f096eac6e0..8e8aa38e62dc 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -15,10 +15,6 @@ app.on('ready', function() { }); ``` -## --client-certificate=`path` - -Sets the `path` of client certificate file. - ## --ignore-connections-limit=`domains` Ignore the connections limit for `domains` list separated by `,`. From 2c0494dcef0b483061bbdf07f09e39d1774d20a0 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 18 Apr 2016 22:57:37 +0530 Subject: [PATCH 019/141] fix spec --- spec/api-app-spec.js | 15 ++++++++++----- spec/fixtures/certificates/certs.cnf | 4 ++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 1f5452713bce..8923d2d214fa 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -95,7 +95,6 @@ describe('app module', function () { this.timeout(5000) - var port var w = null var certPath = path.join(__dirname, 'fixtures', 'certificates') var options = { @@ -115,9 +114,6 @@ describe('app module', function () { res.end('authorized'); } }) - server.listen(0, '127.0.0.1', function () { - port = server.address().port - }) afterEach(function () { if (w != null) { @@ -141,9 +137,18 @@ describe('app module', function () { done() }) + app.on('select-client-certificate', function (event, webContents, url, list, callback) { + assert.equal(list.length, 1) + assert.equal(list[0].issuerName, 'Intermediate CA') + callback(list[0]) + }) + app.importClientCertificate(options, function (result) { assert(!result) - w.loadURL(`https://127.0.0.1:${port}`) + server.listen(0, '127.0.0.1', function () { + var port = server.address().port + w.loadURL(`https://127.0.0.1:${port}`) + }) }) }) }) diff --git a/spec/fixtures/certificates/certs.cnf b/spec/fixtures/certificates/certs.cnf index d8b5c66e13a1..76ef8d073f9d 100644 --- a/spec/fixtures/certificates/certs.cnf +++ b/spec/fixtures/certificates/certs.cnf @@ -15,7 +15,7 @@ RANDFILE = $dir/rand default_md = sha256 default_days = 3650 policy = policy_anything -preserve = no +preserve = no [policy_anything] # Default signing policy @@ -32,7 +32,7 @@ default_bits = 2048 default_md = sha256 string_mask = utf8only distinguished_name = req_env_dn -prompt = no +prompt = no [user_cert] basicConstraints = CA:FALSE From 3a9bbe30ac3a45748dbc4796ab4f2f51558be2f2 Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Mon, 18 Apr 2016 10:33:56 -0700 Subject: [PATCH 020/141] Test for #5183 - webContents.executeJavaScript hangs on subframe load. --- spec/api-browser-window-spec.js | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 2a8d1295c7fd..26d4ff4af35c 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -4,6 +4,7 @@ const assert = require('assert') const fs = require('fs') const path = require('path') const os = require('os') +const http = require('http') const remote = require('electron').remote const screen = require('electron').screen @@ -785,6 +786,14 @@ describe('browser-window module', function () { describe('window.webContents.executeJavaScript', function () { var expected = 'hello, world!' var code = '(() => "' + expected + '")()' + var server + + afterEach(function () { + if (server) { + server.close() + server = null + } + }) it('doesnt throw when no calback is provided', function () { const result = ipcRenderer.sendSync('executeJavaScript', code, false) @@ -798,6 +807,31 @@ describe('browser-window module', function () { done() }) }) + + it('works after page load and during subframe load', function (done) { + var url + // a slow server, guaranteeing time to execute code during loading + server = http.createServer(function (req, res) { + setTimeout(function() { res.end('') }, 200) + }); + server.listen(0, '127.0.0.1', function () { + url = 'http://127.0.0.1:' + server.address().port + w.loadURL('file://' + path.join(fixtures, 'pages', 'base-page.html')) + }) + + w.webContents.once('did-finish-load', function() { + // initiate a sub-frame load, then try and execute script during it + w.webContents.executeJavaScript(` + var iframe = document.createElement('iframe') + iframe.src = '${url}' + document.body.appendChild(iframe) + `, function() { + w.webContents.executeJavaScript(`console.log('hello')`, function() { + done() + }) + }) + }) + }) }) describe('deprecated options', function () { From 64a84dee3bdcc81819733fb7f3e266e8e0bb5709 Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Mon, 18 Apr 2016 10:37:08 -0700 Subject: [PATCH 021/141] =?UTF-8?q?Add=20`isLoadingMainFrame`=20method=20t?= =?UTF-8?q?o=20WebContents.=20Also=20switch=20`webContents.executeJavaScri?= =?UTF-8?q?pt`=20to=20check=20it=20instead=20of=20`isLoading`.=20There=20d?= =?UTF-8?q?oesn=E2=80=99t=20seem=20to=20be=20a=20reasonable=20public=20way?= =?UTF-8?q?=20to=20get=20this=20information=20out=20of=20Chromium,=20so=20?= =?UTF-8?q?it=E2=80=99s=20synthesized=20here=20based=20on=20WebContentsObs?= =?UTF-8?q?erver=20callbacks.=20Fixes=20#5183.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- atom/browser/api/atom_api_web_contents.cc | 33 +++++++++++++++++++++-- atom/browser/api/atom_api_web_contents.h | 11 ++++++++ lib/browser/api/web-contents.js | 2 +- lib/renderer/web-view/web-view.js | 1 + 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 64a76d57e652..c6943d506e67 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -220,7 +220,8 @@ WebContents::WebContents(content::WebContents* web_contents) embedder_(nullptr), type_(REMOTE), request_id_(0), - background_throttling_(true) { + background_throttling_(true), + is_loading_main_frame_(false) { AttachAsUserData(web_contents); web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); } @@ -229,7 +230,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) : embedder_(nullptr), request_id_(0), - background_throttling_(true) { + background_throttling_(true), + is_loading_main_frame_(false) { // Read options. options.Get("backgroundThrottling", &background_throttling_); @@ -543,12 +545,32 @@ void WebContents::DocumentLoadedInFrame( void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { bool is_main_frame = !render_frame_host->GetParent(); + if (is_main_frame) + is_loading_main_frame_ = false; + Emit("did-frame-finish-load", is_main_frame); if (is_main_frame) Emit("did-finish-load"); } +void WebContents::DidStartProvisionalLoadForFrame( + content::RenderFrameHost* render_frame_host, + const GURL& url, + bool is_error_page, + bool is_iframe_srcdoc) { + if (!render_frame_host->GetParent()) + is_loading_main_frame_ = true; +} + +void WebContents::DidCommitProvisionalLoadForFrame( + content::RenderFrameHost* render_frame_host, + const GURL& url, + ui::PageTransition transition_type) { + if (!render_frame_host->GetParent()) + is_loading_main_frame_ = true; +} + void WebContents::DidFailProvisionalLoad( content::RenderFrameHost* render_frame_host, const GURL& url, @@ -556,6 +578,8 @@ void WebContents::DidFailProvisionalLoad( const base::string16& description, bool was_ignored_by_handler) { bool is_main_frame = !render_frame_host->GetParent(); + if (is_main_frame) + is_loading_main_frame_ = false; Emit("did-fail-provisional-load", code, description, url, is_main_frame); Emit("did-fail-load", code, description, url, is_main_frame); } @@ -792,6 +816,10 @@ base::string16 WebContents::GetTitle() const { bool WebContents::IsLoading() const { return web_contents()->IsLoading(); } + +bool WebContents::IsLoadingMainFrame() const { + return is_loading_main_frame_; +} bool WebContents::IsWaitingForResponse() const { return web_contents()->IsWaitingForResponse(); @@ -1189,6 +1217,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("_getURL", &WebContents::GetURL) .SetMethod("getTitle", &WebContents::GetTitle) .SetMethod("isLoading", &WebContents::IsLoading) + .SetMethod("isLoadingMainFrame", &WebContents::IsLoadingMainFrame) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) .SetMethod("_stop", &WebContents::Stop) .SetMethod("_goBack", &WebContents::GoBack) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 0cb2a348e170..7e4bd693536a 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -62,6 +62,7 @@ class WebContents : public mate::TrackableObject, GURL GetURL() const; base::string16 GetTitle() const; bool IsLoading() const; + bool IsLoadingMainFrame() const; bool IsWaitingForResponse() const; void Stop(); void ReloadIgnoringCache(); @@ -228,6 +229,13 @@ class WebContents : public mate::TrackableObject, int error_code, const base::string16& error_description, bool was_ignored_by_handler) override; + void DidStartProvisionalLoadForFrame(content::RenderFrameHost* render_frame_host, + const GURL& validated_url, + bool is_error_page, + bool is_iframe_srcdoc) override; + void DidCommitProvisionalLoadForFrame(content::RenderFrameHost* render_frame_host, + const GURL& url, + ui::PageTransition transition_type) override; void DidStartLoading() override; void DidStopLoading() override; void DidGetResourceResponseStart( @@ -302,6 +310,9 @@ class WebContents : public mate::TrackableObject, // Whether background throttling is disabled. bool background_throttling_; + // Whether the main frame (not just a sub-frame) is currently loading. + bool is_loading_main_frame_; + DISALLOW_COPY_AND_ASSIGN(WebContents); }; diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index 40efa77cda02..dfacf6a02cf1 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -116,7 +116,7 @@ let wrapWebContents = function (webContents) { callback = hasUserGesture hasUserGesture = false } - if (this.getURL() && !this.isLoading()) { + if (this.getURL() && !this.isLoadingMainFrame()) { return asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture) } else { return this.once('did-finish-load', asyncWebFrameMethods.bind(this, requestId, 'executeJavaScript', callback, code, hasUserGesture)) diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index 974d5c6608d6..20f5f07465b5 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -335,6 +335,7 @@ var registerWebViewElement = function () { 'loadURL', 'getTitle', 'isLoading', + 'isLoadingMainFrame', 'isWaitingForResponse', 'stop', 'reload', From c3200ba7f6f4c9c53167baffde764ffc00c42eaa Mon Sep 17 00:00:00 2001 From: Jessica Lord Date: Mon, 18 Apr 2016 18:00:32 -0700 Subject: [PATCH 022/141] Revert "Fix headers" This reverts commit 4dd2716865f6944606f8dffd27ab68434f30643b. --- docs/api/session.md | 56 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/api/session.md b/docs/api/session.md index 758082fa621b..9cccefcbdb66 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -48,11 +48,11 @@ const session = require('electron').session; var ses = session.fromPartition('persist:name'); ``` -## Instance Events +### Instance Events The following events are available on instances of `Session`: -### Event: 'will-download' +#### Event: 'will-download' * `event` Event * `item` [DownloadItem](download-item.md) @@ -72,11 +72,11 @@ session.defaultSession.on('will-download', function(event, item, webContents) { }); ``` -## Instance Methods +### Instance Methods The following methods are available on instances of `Session`: -### `session.cookies` +#### `ses.cookies` The `cookies` gives you ability to query and modify cookies. For example: @@ -100,7 +100,7 @@ session.defaultSession.cookies.set(cookie, function(error) { }); ``` -### `session.cookies.get(filter, callback)` +#### `ses.cookies.get(filter, callback)` * `filter` Object * `url` String (optional) - Retrieves cookies which are associated with @@ -132,7 +132,7 @@ with `callback(error, cookies)` on complete. the number of seconds since the UNIX epoch. Not provided for session cookies. -### `session.cookies.set(details, callback)` +#### `ses.cookies.set(details, callback)` * `details` Object * `url` String - Retrieves cookies which are associated with `url` @@ -151,7 +151,7 @@ with `callback(error, cookies)` on complete. Sets the cookie with `details`, `callback` will be called with `callback(error)` on complete. -### `session.cookies.remove(url, name, callback)` +#### `ses.cookies.remove(url, name, callback)` * `url` String - The URL associated with the cookie. * `name` String - The name of cookie to remove. @@ -160,20 +160,20 @@ on complete. Removes the cookies matching `url` and `name`, `callback` will called with `callback()` on complete. -### `session.getCacheSize(callback)` +#### `ses.getCacheSize(callback)` * `callback` Function * `size` Integer - Cache size used in bytes. Returns the session's current cache size. -### `session.clearCache(callback)` +#### `ses.clearCache(callback)` * `callback` Function - Called when operation is done Clears the session’s HTTP cache. -### `session.clearStorageData([options, ]callback)` +#### `ses.clearStorageData([options, ]callback)` * `options` Object (optional) * `origin` String - Should follow `window.location.origin`’s representation @@ -187,11 +187,11 @@ Clears the session’s HTTP cache. Clears the data of web storages. -### `session.flushStorageData()` +#### `ses.flushStorageData()` Writes any unwritten DOMStorage data to disk. -### `session.setProxy(config, callback)` +#### `ses.setProxy(config, callback)` * `config` Object * `pacScript` String - The URL associated with the PAC file. @@ -228,7 +228,7 @@ For example: * `http=foopy;socks=foopy2` - Use HTTP proxy `foopy` for http URLs, and use `socks4://foopy2` for all other URLs. -### `session.resolveProxy(url, callback)` +### `ses.resolveProxy(url, callback)` * `url` URL * `callback` Function @@ -236,14 +236,14 @@ For example: Resolves the proxy information for `url`. The `callback` will be called with `callback(proxy)` when the request is performed. -### `session.setDownloadPath(path)` +#### `ses.setDownloadPath(path)` * `path` String - The download location Sets download saving directory. By default, the download directory will be the `Downloads` under the respective app folder. -### `session.enableNetworkEmulation(options)` +#### `ses.enableNetworkEmulation(options)` * `options` Object * `offline` Boolean - Whether to emulate network outage. @@ -265,12 +265,12 @@ window.webContents.session.enableNetworkEmulation({ window.webContents.session.enableNetworkEmulation({offline: true}); ``` -### `session.disableNetworkEmulation()` +#### `ses.disableNetworkEmulation()` Disables any network emulation already active for the `session`. Resets to the original network configuration. -### `session.setCertificateVerifyProc(proc)` +#### `ses.setCertificateVerifyProc(proc)` * `proc` Function @@ -291,7 +291,7 @@ myWindow.webContents.session.setCertificateVerifyProc(function(hostname, cert, c }); ``` -### `session.setPermissionRequestHandler(handler)` +#### `ses.setPermissionRequestHandler(handler)` * `handler` Function * `webContents` Object - [WebContents](web-contents.md) requesting the permission. @@ -314,13 +314,13 @@ session.fromPartition(partition).setPermissionRequestHandler(function(webContent }); ``` -### `session.clearHostResolverCache([callback])` +#### `ses.clearHostResolverCache([callback])` * `callback` Function (optional) - Called when operation is done. Clears the host resolver cache. -### `session.webRequest` +#### `ses.webRequest` The `webRequest` API set allows to intercept and modify contents of a request at various stages of its lifetime. @@ -349,7 +349,7 @@ session.defaultSession.webRequest.onBeforeSendHeaders(filter, function(details, }); ``` -### `session.webRequest.onBeforeRequest([filter, ]listener)` +#### `ses.webRequest.onBeforeRequest([filter, ]listener)` * `filter` Object * `listener` Function @@ -379,7 +379,7 @@ The `callback` has to be called with an `response` object: * `redirectURL` String (optional) - The original request is prevented from being sent or completed, and is instead redirected to the given URL. -### `session.webRequest.onBeforeSendHeaders([filter, ]listener)` +#### `ses.webRequest.onBeforeSendHeaders([filter, ]listener)` * `filter` Object * `listener` Function @@ -404,7 +404,7 @@ The `callback` has to be called with an `response` object: * `requestHeaders` Object (optional) - When provided, request will be made with these headers. -### `session.webRequest.onSendHeaders([filter, ]listener)` +#### `ses.webRequest.onSendHeaders([filter, ]listener)` * `filter` Object * `listener` Function @@ -421,7 +421,7 @@ response are visible by the time this listener is fired. * `timestamp` Double * `requestHeaders` Object -### `session.webRequest.onHeadersReceived([filter,] listener)` +#### `ses.webRequest.onHeadersReceived([filter,] listener)` * `filter` Object * `listener` Function @@ -449,7 +449,7 @@ The `callback` has to be called with an `response` object: * `statusLine` String (optional) - Should be provided when overriding `responseHeaders` to change header status otherwise original response header's status will be used. -### `session.webRequest.onResponseStarted([filter, ]listener)` +#### `ses.webRequest.onResponseStarted([filter, ]listener)` * `filter` Object * `listener` Function @@ -470,7 +470,7 @@ and response headers are available. * `statusCode` Integer * `statusLine` String -### `session.webRequest.onBeforeRedirect([filter, ]listener)` +#### `ses.webRequest.onBeforeRedirect([filter, ]listener)` * `filter` Object * `listener` Function @@ -491,7 +491,7 @@ redirect is about to occur. * `fromCache` Boolean * `responseHeaders` Object -### `session.webRequest.onCompleted([filter, ]listener)` +#### `ses.webRequest.onCompleted([filter, ]listener)` * `filter` Object * `listener` Function @@ -510,7 +510,7 @@ completed. * `statusCode` Integer * `statusLine` String -### `session.webRequest.onErrorOccurred([filter, ]listener)` +#### `ses.webRequest.onErrorOccurred([filter, ]listener)` * `filter` Object * `listener` Function From 916114dd2820b0fda8636d9f50d57e1ae6fed4e3 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Mon, 18 Apr 2016 20:23:11 -0700 Subject: [PATCH 023/141] :memo: keeping submodules up to date --- .../source-code-directory-structure.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/development/source-code-directory-structure.md b/docs/development/source-code-directory-structure.md index 998280a37054..1c9e8c2b7749 100644 --- a/docs/development/source-code-directory-structure.md +++ b/docs/development/source-code-directory-structure.md @@ -62,3 +62,30 @@ Electron when creating a distribution. * **external_binaries** - Downloaded binaries of third-party frameworks which do not support building with `gyp`. + +## Keeping Git Submodules Up to Date + +The Electron repository has a few vendored dependencies, found in the +[/vendor](/vendor) directory. Occasionally you might see a message like this +when running `git status`: + +```sh +$ git status + + modified: vendor/brightray (new commits) + modified: vendor/node (new commits) +``` + +To update these vendored dependencies, run the following command: + +```sh +git submodule update --init --recursive +``` + +If you find yourself running this command often, you can create an alias for it +in your `~/.gitconfig` file: + +``` +[alias] + su = git submodule update --init --recursive +``` From fcad4ee1867659c7b6e3d0a63393c65bae773ff5 Mon Sep 17 00:00:00 2001 From: StoneStoneStone Date: Tue, 19 Apr 2016 11:58:58 +0800 Subject: [PATCH 024/141] Create download-item.md --- docs-translations/zh-CN/api/download-item.md | 96 ++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 docs-translations/zh-CN/api/download-item.md diff --git a/docs-translations/zh-CN/api/download-item.md b/docs-translations/zh-CN/api/download-item.md new file mode 100644 index 000000000000..a8ed266479d0 --- /dev/null +++ b/docs-translations/zh-CN/api/download-item.md @@ -0,0 +1,96 @@ +# DownloadItem + +`DownloadItem`(下载项)是一个在Electron中展示下载项的 +[EventEmitter](https://github.com/nodejs/node/blob/master/doc/api/events.markdown)(nodejs)。 +它被用于`Session`模块中的`will-download`事件,允许用户去控制下载项。 + +```javascript +// In the main process. +win.webContents.session.on('will-download', function(event, item, webContents) { + // Set the save path, making Electron not to prompt a save dialog. + item.setSavePath('/tmp/save.pdf'); + console.log(item.getMimeType()); + console.log(item.getFilename()); + console.log(item.getTotalBytes()); + item.on('updated', function() { + console.log('Received bytes: ' + item.getReceivedBytes()); + }); + item.on('done', function(e, state) { + if (state == "completed") { + console.log("Download successfully"); + } else { + console.log("Download is cancelled or interrupted that can't be resumed"); + } + }); +``` + +## 事件 + +### 事件: 'updated' + +当`downloadItem`获得更新时发射。 + +### 事件: 'done' + +* `event` Event +* `state` String + * `completed` - 下载成功完成。 + * `cancelled` - 下载被取消。 + * `interrupted` - 与文件服务器错误的中断连接。 + +当下载处于一个终止状态时发射。这包括了一个完成的下载,一个被取消的下载(via `downloadItem.cancel()`), +和一个被意外中断的下载(无法恢复)。 + +## 方法 + +`downloadItem`对象有以下一些方法: + +### `downloadItem.setSavePath(path)` + +* `path` String - 设置下载项的保存文件路径. + +这个API仅仅在`session`的`will-download`回调函数中可用。 +如果用户没有这个API去设置保存路径,Electron会用原始程序去确定保存路径(通常提示一个保存对话框)。 + +### `downloadItem.pause()` + +暂停下载。 + +### `downloadItem.resume()` + +恢复被暂停的下载。 + +### `downloadItem.cancel()` + +取消下载操作。 + +### `downloadItem.getURL()` + +以`String`形式返回一个该下载项的下载源url。 + +### `downloadItem.getMimeType()` + +返回一个表示mime类型的`String`。 + +### `downloadItem.hasUserGesture()` + +返回一个`Boolean`表示下载是否有用户动作。 + +### `downloadItem.getFilename()` + +返回一个表示下载项文件名的`String`。 + +**Note:** 此文件名不一定总是保存在本地硬盘上的实际文件名。 +如果用户在下载保存对话框中修改了文件名,保存的文件的实际名称会与`downloadItem.getFilename()`方法返回的文件名不同。 + +### `downloadItem.getTotalBytes()` + +返回一个表示下载项总字节数大小的`Integer`。如果大小未知,返回0。 + +### `downloadItem.getReceivedBytes()` + +返回一个表示下载项已经接收的字节数大小的`Integer`。 + +### `downloadItem.getContentDisposition()` + +以`String`形式返回响应头(response header)中的`Content-Disposition`域。 From 591f8fed883ae1fd71866088f5266be97789caeb Mon Sep 17 00:00:00 2001 From: StoneStoneStone Date: Tue, 19 Apr 2016 12:03:34 +0800 Subject: [PATCH 025/141] Update frameless-window.md --- docs-translations/zh-CN/api/frameless-window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/zh-CN/api/frameless-window.md b/docs-translations/zh-CN/api/frameless-window.md index 1916c6a929bc..833f070ad27c 100644 --- a/docs-translations/zh-CN/api/frameless-window.md +++ b/docs-translations/zh-CN/api/frameless-window.md @@ -1,4 +1,4 @@ -# 无边框窗口 +# Frameless Window 无边框窗口指的是不包含除页面本身以外任何其它可视部分的窗口([chrome](https://developer.mozilla.org/en-US/docs/Glossary/Chrome))。 像工具栏,是窗口的一部分,但并不属于页面。这些是[`BrowserWindow`](browser-window.md) 类的选项。 From ddf962c6eae0aa44b61112e1e7ee6ab8c89137db Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 19 Apr 2016 10:01:38 +0530 Subject: [PATCH 026/141] client_id is accessed on different threads --- atom/browser/net/atom_network_delegate.cc | 11 +++++++++-- atom/browser/net/atom_network_delegate.h | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/atom/browser/net/atom_network_delegate.cc b/atom/browser/net/atom_network_delegate.cc index 6ef5ac22807a..3143cd3b2575 100644 --- a/atom/browser/net/atom_network_delegate.cc +++ b/atom/browser/net/atom_network_delegate.cc @@ -229,6 +229,7 @@ void AtomNetworkDelegate::SetResponseListenerInIO( void AtomNetworkDelegate::SetDevToolsNetworkEmulationClientId( const std::string& client_id) { + base::AutoLock auto_lock(lock_); client_id_ = client_id; } @@ -247,10 +248,16 @@ int AtomNetworkDelegate::OnBeforeSendHeaders( net::URLRequest* request, const net::CompletionCallback& callback, net::HttpRequestHeaders* headers) { - if (!client_id_.empty()) + std::string client_id; + { + base::AutoLock auto_lock(lock_); + client_id = client_id_; + } + + if (!client_id.empty()) headers->SetHeader( DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId, - client_id_); + client_id); if (!ContainsKey(response_listeners_, kOnBeforeSendHeaders)) return brightray::NetworkDelegate::OnBeforeSendHeaders( request, callback, headers); diff --git a/atom/browser/net/atom_network_delegate.h b/atom/browser/net/atom_network_delegate.h index e0b41eb45891..92ea6415e69e 100644 --- a/atom/browser/net/atom_network_delegate.h +++ b/atom/browser/net/atom_network_delegate.h @@ -11,6 +11,7 @@ #include "brightray/browser/network_delegate.h" #include "base/callback.h" +#include "base/synchronization/lock.h" #include "base/values.h" #include "extensions/common/url_pattern.h" #include "net/base/net_errors.h" @@ -119,6 +120,7 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate { std::map response_listeners_; std::map callbacks_; + base::Lock lock_; // Client id for devtools network emulation. std::string client_id_; From 8f89cd2d5988bd1ffa31d0144b4fe3033a0bdbb1 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Mon, 18 Apr 2016 22:39:12 -0700 Subject: [PATCH 027/141] Move "setSheetOffset" to the BrowserWindow --- atom/browser/api/atom_api_dialog.cc | 5 ----- atom/browser/api/atom_api_window.cc | 5 +++++ atom/browser/api/atom_api_window.h | 1 + atom/browser/native_window.cc | 16 ++++++++-------- docs/api/browser-window.md | 11 +++++++++++ docs/api/dialog.md | 18 ++---------------- lib/browser/api/dialog.js | 4 ---- 7 files changed, 27 insertions(+), 33 deletions(-) diff --git a/atom/browser/api/atom_api_dialog.cc b/atom/browser/api/atom_api_dialog.cc index 965b92878351..0a544c56468c 100644 --- a/atom/browser/api/atom_api_dialog.cc +++ b/atom/browser/api/atom_api_dialog.cc @@ -66,10 +66,6 @@ void ShowMessageBox(int type, } } -void SetSheetOffset(atom::NativeWindow* window, const double offset) { - window->SetSheetOffset(offset); -} - void ShowOpenDialog(const std::string& title, const base::FilePath& default_path, const file_dialog::Filters& filters, @@ -116,7 +112,6 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("showMessageBox", &ShowMessageBox); dict.SetMethod("showErrorBox", &atom::ShowErrorBox); dict.SetMethod("showOpenDialog", &ShowOpenDialog); - dict.SetMethod("setSheetOffset", &SetSheetOffset); dict.SetMethod("showSaveDialog", &ShowSaveDialog); } diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index fd9dd94458c3..07cee2af2d32 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -514,6 +514,10 @@ std::vector Window::GetPosition() { return result; } +void Window::SetSheetOffset(double offset) { + window_->SetSheetOffset(offset); +} + void Window::SetTitle(const std::string& title) { window_->SetTitle(title); } @@ -763,6 +767,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("center", &Window::Center) .SetMethod("setPosition", &Window::SetPosition) .SetMethod("getPosition", &Window::GetPosition) + .SetMethod("setSheetOffset", &Window::SetSheetOffset) .SetMethod("setTitle", &Window::SetTitle) .SetMethod("getTitle", &Window::GetTitle) .SetMethod("flashFrame", &Window::FlashFrame) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index d26ff5b36748..0b8f0e3c491c 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -110,6 +110,7 @@ class Window : public mate::TrackableObject, std::vector GetMinimumSize(); void SetMaximumSize(int width, int height); std::vector GetMaximumSize(); + void SetSheetOffset(double offset); void SetResizable(bool resizable); bool IsResizable(); void SetMovable(bool movable); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 37bf8f687ed8..091a7b8a3fb1 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -201,14 +201,6 @@ gfx::Size NativeWindow::GetContentSize() { return WindowSizeToContentSize(GetSize()); } -void NativeWindow::SetSheetOffset(const double offset) { - sheet_offset_ = offset; -} - -double NativeWindow::GetSheetOffset() { - return sheet_offset_; -} - void NativeWindow::SetSizeConstraints( const extensions::SizeConstraints& window_constraints) { extensions::SizeConstraints content_constraints; @@ -262,6 +254,14 @@ gfx::Size NativeWindow::GetMaximumSize() { return GetSizeConstraints().GetMaximumSize(); } +void NativeWindow::SetSheetOffset(const double offset) { + sheet_offset_ = offset; +} + +double NativeWindow::GetSheetOffset() { + return sheet_offset_; +} + void NativeWindow::SetRepresentedFilename(const std::string& filename) { } diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 877a6d0f7457..a28ed10f3cfe 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -675,6 +675,17 @@ Returns the title of the native window. **Note:** The title of web page can be different from the title of the native window. +### `win.setSheetOffset(offset)` + +Changes the attachment point for sheets on Mac OS X. By default, sheets are attached +just below the window frame, but you may want to display them beneath a HTML-rendered +toolbar. For example: + +``` +var toolbarRect = document.getElementById('toolbar').getBoundingClientRect(); +win.setSheetOffset(toolbarRect.height); +``` + ### `win.flashFrame(flag)` * `flag` Boolean diff --git a/docs/api/dialog.md b/docs/api/dialog.md index f36850f310a0..32b8628567af 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -129,19 +129,5 @@ On Mac OS X, dialogs are presented as sheets attached to a window if you provide a `BrowserWindow` reference in the `browserWindow` parameter, or modals if no window is provided. -### `dialog.setSheetOffset(browserWindow, offset)` - -* `browserWindow` BrowserWindow (optional) - -Changes the attachment point for sheets on Mac OS X. By default, sheets are attached -just below the window frame, but you may want to display them beneath a HTML-rendered -toolbar. For example: -``` -const {remote} = require('electron'); -const browserWindow = remote.getCurrentWindow(); - -var toolbarRect = document.getElementById('toolbar').getBoundingClientRect(); -remote.dialog.setSheetOffset(browserWindow, toolbarRect.height); - -... show dialog ... -``` +You can call `BrowserWindow.getCurrentWindow().setSheetOffset(offset)` to change +the offset from the window frame where sheets are attached. diff --git a/lib/browser/api/dialog.js b/lib/browser/api/dialog.js index ed7ab063ed84..6669d8cab89a 100644 --- a/lib/browser/api/dialog.js +++ b/lib/browser/api/dialog.js @@ -49,10 +49,6 @@ var checkAppInitialized = function () { } module.exports = { - setSheetOffset: function (window, offset) { - return binding.setSheetOffset(window, offset) - }, - showOpenDialog: function (...args) { var prop, properties, value, wrappedCallback checkAppInitialized() From 414245f4d837c3a04b14149903367daa15d894e3 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Mon, 18 Apr 2016 22:45:38 -0700 Subject: [PATCH 028/141] Keep function placement consistent --- atom/browser/api/atom_api_window.cc | 10 +++++----- atom/browser/native_window.h | 5 ++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 07cee2af2d32..2bac6fa808d6 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -440,6 +440,10 @@ std::vector Window::GetMaximumSize() { return result; } +void Window::SetSheetOffset(double offset) { + window_->SetSheetOffset(offset); +} + void Window::SetResizable(bool resizable) { window_->SetResizable(resizable); } @@ -514,10 +518,6 @@ std::vector Window::GetPosition() { return result; } -void Window::SetSheetOffset(double offset) { - window_->SetSheetOffset(offset); -} - void Window::SetTitle(const std::string& title) { window_->SetTitle(title); } @@ -750,6 +750,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("getMinimumSize", &Window::GetMinimumSize) .SetMethod("setMaximumSize", &Window::SetMaximumSize) .SetMethod("getMaximumSize", &Window::GetMaximumSize) + .SetMethod("setSheetOffset", &Window::SetSheetOffset) .SetMethod("setResizable", &Window::SetResizable) .SetMethod("isResizable", &Window::IsResizable) .SetMethod("setMovable", &Window::SetMovable) @@ -767,7 +768,6 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("center", &Window::Center) .SetMethod("setPosition", &Window::SetPosition) .SetMethod("getPosition", &Window::GetPosition) - .SetMethod("setSheetOffset", &Window::SetSheetOffset) .SetMethod("setTitle", &Window::SetTitle) .SetMethod("getTitle", &Window::GetTitle) .SetMethod("flashFrame", &Window::FlashFrame) diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index d60ac209d8a0..f3acf6222314 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -123,6 +123,8 @@ class NativeWindow : public base::SupportsUserData, virtual gfx::Size GetMinimumSize(); virtual void SetMaximumSize(const gfx::Size& size); virtual gfx::Size GetMaximumSize(); + virtual void SetSheetOffset(const double offset); + virtual double GetSheetOffset(); virtual void SetResizable(bool resizable) = 0; virtual bool IsResizable() = 0; virtual void SetMovable(bool movable) = 0; @@ -190,9 +192,6 @@ class NativeWindow : public base::SupportsUserData, gfx::Size GetAspectRatioExtraSize(); void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size); - void SetSheetOffset(const double offset); - double GetSheetOffset(); - base::WeakPtr GetWeakPtr() { return weak_factory_.GetWeakPtr(); } From 2d8286515defc2e201fe319768d3dab1fdc30606 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 19 Apr 2016 10:47:28 +0530 Subject: [PATCH 029/141] expose api only on platforms using nss cert database --- atom/browser/api/atom_api_app.cc | 8 ++++++-- atom/browser/api/atom_api_app.h | 13 ++++++++++++- electron.gyp | 3 +++ filenames.gypi | 6 ++++-- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index d6afbb366e04..46402d7f9b28 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -159,13 +159,14 @@ void PassLoginInformation(scoped_refptr login_handler, login_handler->CancelAuth(); } +#if defined(USE_NSS_CERTS) int ImportIntoCertStore( CertificateManagerModel* model, const base::DictionaryValue& options) { std::string file_data, cert_path; base::string16 password; net::CertificateList imported_certs; - int rv; + int rv = -1; options.GetString("clientCertificate", &cert_path); options.GetString("password", &password); @@ -189,6 +190,7 @@ int ImportIntoCertStore( } return rv; } +#endif } // namespace @@ -402,6 +404,7 @@ bool App::MakeSingleInstance( } } +#if defined(USE_NSS_CERTS) void App::ImportClientCertificate( const base::DictionaryValue& options, const net::CompletionCallback& callback) { @@ -429,6 +432,7 @@ void App::OnCertificateManagerModelCreated( *(options.get())); callback.Run(rv); } +#endif mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( v8::Isolate* isolate) { @@ -469,7 +473,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("allowNTLMCredentialsForAllDomains", &App::AllowNTLMCredentialsForAllDomains) .SetMethod("getLocale", &App::GetLocale) -#if defined(OS_LINUX) +#if defined(USE_NSS_CERTS) .SetMethod("importClientCertificate", &App::ImportClientCertificate) #endif .SetMethod("makeSingleInstance", &App::MakeSingleInstance); diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index ce66daedf100..acaa64a3437e 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -11,12 +11,15 @@ #include "atom/browser/atom_browser_client.h" #include "atom/browser/browser_observer.h" #include "atom/common/native_mate_converters/callback.h" -#include "chrome/browser/certificate_manager_model.h" #include "chrome/browser/process_singleton.h" #include "content/public/browser/gpu_data_manager_observer.h" #include "native_mate/handle.h" #include "net/base/completion_callback.h" +#if defined(USE_NSS_CERTS) +#include "chrome/browser/certificate_manager_model.h" +#endif + namespace base { class FilePath; } @@ -43,10 +46,12 @@ class App : public AtomBrowserClient::Delegate, int render_process_id, int render_frame_id); +#if defined(USE_NSS_CERTS) void OnCertificateManagerModelCreated( scoped_ptr options, const net::CompletionCallback& callback, scoped_ptr model); +#endif protected: App(); @@ -104,15 +109,21 @@ class App : public AtomBrowserClient::Delegate, bool MakeSingleInstance( const ProcessSingleton::NotificationCallback& callback); std::string GetLocale(); + +#if defined(USE_NSS_CERTS) void ImportClientCertificate(const base::DictionaryValue& options, const net::CompletionCallback& callback); +#endif #if defined(OS_WIN) bool IsAeroGlassEnabled(); #endif scoped_ptr process_singleton_; + +#if defined(USE_NSS_CERTS) scoped_ptr certificate_manager_model_; +#endif DISALLOW_COPY_AND_ASSIGN(App); }; diff --git a/electron.gyp b/electron.gyp index 7a431028f198..11a35490923b 100644 --- a/electron.gyp +++ b/electron.gyp @@ -310,6 +310,9 @@ ], }], # OS=="mac" and mas_build==1 ['OS=="linux"', { + 'sources': [ + '<@(lib_sources_nss)', + ], 'link_settings': { 'ldflags': [ # Make binary search for libraries under current directory, so we diff --git a/filenames.gypi b/filenames.gypi index 4de1b366b4fc..a1c704c348b1 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -390,8 +390,6 @@ 'atom/utility/atom_content_utility_client.h', 'chromium_src/chrome/browser/browser_process.cc', 'chromium_src/chrome/browser/browser_process.h', - 'chromium_src/chrome/browser/certificate_manager_model.cc', - 'chromium_src/chrome/browser/certificate_manager_model.h', 'chromium_src/chrome/browser/chrome_process_finder_win.cc', 'chromium_src/chrome/browser/chrome_process_finder_win.h', 'chromium_src/chrome/browser/chrome_notification_types.h', @@ -519,6 +517,10 @@ '<@(native_mate_files)', '<(SHARED_INTERMEDIATE_DIR)/atom_natives.h', ], + 'lib_sources_nss': [ + 'chromium_src/chrome/browser/certificate_manager_model.cc', + 'chromium_src/chrome/browser/certificate_manager_model.h', + ], 'lib_sources_win': [ 'chromium_src/chrome/browser/ui/views/color_chooser_dialog.cc', 'chromium_src/chrome/browser/ui/views/color_chooser_dialog.h', From bd406ab04678bf6215949fb36c83f24e7d859811 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 19 Apr 2016 16:08:37 +0900 Subject: [PATCH 030/141] Update the MAS submission guide --- .../mac-app-store-submission-guide.md | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index ec8d8653ca08..bb4a02ba09ac 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -4,10 +4,6 @@ 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. @@ -43,6 +39,8 @@ First, you need to prepare two entitlements files. com.apple.security.inherit + com.apple.security.temporary-exception.sbpl + (allow mach-lookup (global-name-regex #"^org.chromium.Chromium.rohitfork.[0-9]+$")) ``` @@ -56,6 +54,8 @@ First, you need to prepare two entitlements files. com.apple.security.app-sandbox + com.apple.security.temporary-exception.sbpl + (allow mach-lookup (global-name-regex #"^org.chromium.Chromium.rohitfork.[0-9]+$")) ``` @@ -96,11 +96,32 @@ 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 +### Upload Your App 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]. +before uploading. + +### Explain the Usages of `temporary-exception` + +When sandboxing your app there was a `temporary-exception` entry added to the +entitlements, according to the [App Sandbox Temporary Exception +Entitlements][temporary-exception] documentation, you have to explain why this +entry is needed: + +> Note: If you request a temporary-exception entitlement, be sure to follow the +guidance regarding entitlements provided on the iTunes Connect website. In +particular, identify the entitlement and corresponding issue number in the App +Sandbox Entitlement Usage Information section in iTunes Connect and explain why +your app needs the exception. + +You may explain that your app is built upon Chromium browser, which uses Mach +port for its multi-process architecture. But there is still probability that +your app failed the review because of this. + +### Submit Your App for Review + +After these steps, you can [submit your app for review][submit-for-review]. ## Limitations of MAS Build @@ -165,3 +186,4 @@ ERN)][ern-tutorial]. [app-sandboxing]: https://developer.apple.com/app-sandboxing/ [issue-3871]: https://github.com/electron/electron/issues/3871 [ern-tutorial]: https://carouselapps.com/2015/12/15/legally-submit-app-apples-app-store-uses-encryption-obtain-ern/ +[temporary-exception]: https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/AppSandboxTemporaryExceptionEntitlements.html From fd6747483aacf229916c941e4ea59e898650c632 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 19 Apr 2016 20:27:58 +0900 Subject: [PATCH 031/141] Update the codesign code for latest Xcode --- .../mac-app-store-submission-guide.md | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index bb4a02ba09ac..c80885f5a56b 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -39,8 +39,6 @@ First, you need to prepare two entitlements files. com.apple.security.inherit - com.apple.security.temporary-exception.sbpl - (allow mach-lookup (global-name-regex #"^org.chromium.Chromium.rohitfork.[0-9]+$")) ``` @@ -77,17 +75,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/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" +codesign -s "$APP_KEY" -f --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Electron Framework" +codesign -s "$APP_KEY" -f --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib" +codesign -s "$APP_KEY" -f --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libnode.dylib" +codesign -s "$APP_KEY" -f --entitlements child.plist "$FRAMEWORKS_PATH/Electron Framework.framework" +codesign -s "$APP_KEY" -f --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper" +codesign -s "$APP_KEY" -f --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper.app/" +codesign -s "$APP_KEY" -f --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH" +codesign -s "$APP_KEY" -f --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper EH.app/" +codesign -s "$APP_KEY" -f --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP" +codesign -s "$APP_KEY" -f --entitlements child.plist "$FRAMEWORKS_PATH/$APP Helper NP.app/" +codesign -s "$APP_KEY" -f --entitlements child.plist "$APP_PATH/Contents/MacOS/$APP" +codesign -s "$APP_KEY" -f --entitlements parent.plist "$APP_PATH" productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" ``` From 58dfad4d016f6f23129dd18b6fbeb900d2bafab4 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 19 Apr 2016 18:12:05 +0530 Subject: [PATCH 032/141] devtools: allow opening in specified dock state --- atom/browser/api/atom_api_web_contents.cc | 14 ++++++++++---- docs/api/web-contents.md | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index abad4add4fb0..0eddd03399c2 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -848,14 +848,20 @@ void WebContents::OpenDevTools(mate::Arguments* args) { if (type_ == REMOTE) return; - bool detach = false; + std::string state; if (type_ == WEB_VIEW) { - detach = true; + state = "detach"; } else if (args && args->Length() == 1) { + bool detach = false; mate::Dictionary options; - args->GetNext(&options) && options.Get("detach", &detach); + if (args->GetNext(&options)) { + options.Get("mode", &state); + options.Get("detach", &detach); + if (state.empty() && detach) + state = "detach"; + } } - managed_web_contents()->SetCanDock(!detach); + managed_web_contents()->SetDockState(state); managed_web_contents()->ShowDevTools(); } diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 8fc7a959f69d..46b7ec167b94 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -647,7 +647,8 @@ Removes the specified path from DevTools workspace. ### `webContents.openDevTools([options])` * `options` Object (optional) - * `detach` Boolean - opens DevTools in a new window + * `mode` String - Opens the devtools with specified dock state, can be one of + "right", "bottom", "undocked", "detach". Defaults to last used dock state. Opens the devtools. From 838cf0ffdc02bef70ca51ffe4678b344797faaf8 Mon Sep 17 00:00:00 2001 From: rmcdonald Date: Tue, 19 Apr 2016 09:31:04 -0700 Subject: [PATCH 033/141] Correct transposition errors by changing xfvb to xvfb --- docs/tutorial/testing-on-headless-ci.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tutorial/testing-on-headless-ci.md b/docs/tutorial/testing-on-headless-ci.md index ec1f4635c906..f9090a6cbd79 100644 --- a/docs/tutorial/testing-on-headless-ci.md +++ b/docs/tutorial/testing-on-headless-ci.md @@ -18,9 +18,9 @@ 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 +[xvfb-maybe](https://github.com/paulcbetts/xvfb-maybe): Prepend your test +commands with `xvfb-maybe` and the little tool will automatically configure +xvfb, if required by the current system. On Windows or Mac OS X, it will simply do nothing. ``` @@ -47,7 +47,7 @@ install: ### Jenkins -For Jenkins, a [Xfvb plugin is available](https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin). +For Jenkins, a [Xvfb plugin is available](https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin). ### Circle CI From 8f04dd1b9ce4f748feb3c7e090d42e1fca6cfcf0 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Tue, 19 Apr 2016 09:46:48 -0700 Subject: [PATCH 034/141] remove the git --- 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 1c9e8c2b7749..b2672def6544 100644 --- a/docs/development/source-code-directory-structure.md +++ b/docs/development/source-code-directory-structure.md @@ -87,5 +87,5 @@ in your `~/.gitconfig` file: ``` [alias] - su = git submodule update --init --recursive + su = submodule update --init --recursive ``` From 02c8c58c0b71b5af21fc193aba6a7c997448dcc1 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 19 Apr 2016 12:47:05 -0400 Subject: [PATCH 035/141] Fixed docs sample code programming error for DownloadItem --- docs/api/download-item.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/api/download-item.md b/docs/api/download-item.md index 756353b8ba3d..f117ffc57a78 100644 --- a/docs/api/download-item.md +++ b/docs/api/download-item.md @@ -22,6 +22,7 @@ win.webContents.session.on('will-download', function(event, item, webContents) { console.log("Download is cancelled or interrupted that can't be resumed"); } }); +}); ``` ## Events From 18f5fcde60007f6b22878f08de3022405a9e5203 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 20 Apr 2016 09:18:50 +0900 Subject: [PATCH 036/141] Fix some coding style issues --- atom/browser/native_window.cc | 1 + atom/browser/native_window_mac.mm | 6 +++--- atom/browser/net/atom_network_delegate.h | 1 + docs/api/dialog.md | 1 - 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 091a7b8a3fb1..2379bdd053c5 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -54,6 +54,7 @@ NativeWindow::NativeWindow( enable_larger_than_screen_(false), is_closed_(false), has_dialog_attached_(false), + sheet_offset_(0.0), aspect_ratio_(0.0), inspectable_web_contents_(inspectable_web_contents), weak_factory_(this) { diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index c35c177ac298..5f980fed62cf 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -243,13 +243,13 @@ bool ScopedDisableResize::disable_resize_ = false; return NO; } -- (NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet usingRect:(NSRect)rect { - NSView * view = window.contentView; +- (NSRect)window:(NSWindow*)window + willPositionSheet:(NSWindow*)sheet usingRect:(NSRect)rect { + NSView* view = window.contentView; rect.origin.y = view.frame.size.height - shell_->GetSheetOffset(); return rect; } - @end @interface AtomNSWindow : NSWindow { diff --git a/atom/browser/net/atom_network_delegate.h b/atom/browser/net/atom_network_delegate.h index 92ea6415e69e..701a953c265e 100644 --- a/atom/browser/net/atom_network_delegate.h +++ b/atom/browser/net/atom_network_delegate.h @@ -121,6 +121,7 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate { std::map callbacks_; base::Lock lock_; + // Client id for devtools network emulation. std::string client_id_; diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 32b8628567af..1cea9da119ad 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -122,7 +122,6 @@ it is usually used to report errors in early stage of startup. If called before the app `ready`event on Linux, the message will be emitted to stderr, and no GUI dialog will appear. - ## Sheets On Mac OS X, dialogs are presented as sheets attached to a window if you provide From b80272dbb424aaaec03b53f265b339b45453e6b0 Mon Sep 17 00:00:00 2001 From: Adam Drago Date: Tue, 19 Apr 2016 18:12:37 -0700 Subject: [PATCH 037/141] Add note for OS X about using `role` on MenuItem --- docs/api/menu-item.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/api/menu-item.md b/docs/api/menu-item.md index fb12e251153e..0029ba14dd4b 100644 --- a/docs/api/menu-item.md +++ b/docs/api/menu-item.md @@ -61,6 +61,8 @@ On OS X `role` can also have following additional values: * `help` - The submenu is a "Help" menu * `services` - The submenu is a "Services" menu +When specifying `role` on OS X, `label` and `accelerator` are the only options that will affect the MenuItem. All other options will be ignored. + ## Instance Properties The following properties (and no others) can be updated on an existing `MenuItem`: From 942971b01afd6773fce41e5ca3d49270cf88b5ce Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Tue, 19 Apr 2016 19:20:59 -0700 Subject: [PATCH 038/141] Fix linting errors. --- atom/browser/api/atom_api_web_contents.cc | 2 +- atom/browser/api/atom_api_web_contents.h | 27 +++++++++++++---------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index c6943d506e67..7c7e5896abc1 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -816,7 +816,7 @@ base::string16 WebContents::GetTitle() const { bool WebContents::IsLoading() const { return web_contents()->IsLoading(); } - + bool WebContents::IsLoadingMainFrame() const { return is_loading_main_frame_; } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 7e4bd693536a..292ec096088f 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -224,18 +224,21 @@ class WebContents : public mate::TrackableObject, int error_code, const base::string16& error_description, bool was_ignored_by_handler) override; - void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - bool was_ignored_by_handler) override; - void DidStartProvisionalLoadForFrame(content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page, - bool is_iframe_srcdoc) override; - void DidCommitProvisionalLoadForFrame(content::RenderFrameHost* render_frame_host, - const GURL& url, - ui::PageTransition transition_type) override; + void DidFailProvisionalLoad( + content::RenderFrameHost* render_frame_host, + const GURL& validated_url, + int error_code, + const base::string16& error_description, + bool was_ignored_by_handler) override; + void DidStartProvisionalLoadForFrame( + content::RenderFrameHost* render_frame_host, + const GURL& validated_url, + bool is_error_page, + bool is_iframe_srcdoc) override; + void DidCommitProvisionalLoadForFrame( + content::RenderFrameHost* render_frame_host, + const GURL& url, + ui::PageTransition transition_type) override; void DidStartLoading() override; void DidStopLoading() override; void DidGetResourceResponseStart( From 7468118df55b98f7ee6e13f2462bd5d48d00493c Mon Sep 17 00:00:00 2001 From: StoneStoneStone Date: Wed, 20 Apr 2016 10:26:31 +0800 Subject: [PATCH 039/141] Update screen.md --- docs-translations/zh-CN/api/screen.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs-translations/zh-CN/api/screen.md b/docs-translations/zh-CN/api/screen.md index 0de4c975afbd..93b61a460788 100644 --- a/docs-translations/zh-CN/api/screen.md +++ b/docs-translations/zh-CN/api/screen.md @@ -23,7 +23,7 @@ app.on('ready', function() { }); ``` -另一个例子,在次页外创建一个窗口: +另一个例子,在此页外创建一个窗口: ```javascript const electron = require('electron'); @@ -132,4 +132,4 @@ app.on('ready', function() { * `width` Integer * `height` Integer -返回与提供的边界范围最密切相关的 display. \ No newline at end of file +返回与提供的边界范围最密切相关的 display. From 16b54e15025c4d5f11e31c9fa0ff38d057aa4407 Mon Sep 17 00:00:00 2001 From: StoneStoneStone Date: Wed, 20 Apr 2016 10:37:41 +0800 Subject: [PATCH 040/141] Update screen.md --- docs-translations/zh-CN/api/screen.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/zh-CN/api/screen.md b/docs-translations/zh-CN/api/screen.md index 93b61a460788..bd4aec8b3709 100644 --- a/docs-translations/zh-CN/api/screen.md +++ b/docs-translations/zh-CN/api/screen.md @@ -54,7 +54,7 @@ app.on('ready', function() { ## `Display` 对象 -`Display` 对象表示了物力方式连接系统. 一个伪造的 `Display` 或许存在于一个无头系统中,或者一个 `Display` 相当于一个远程的、虚拟的 display. +`Display` 对象表示一个连接到系统的物理显示. 一个虚设的 `Display` 或许存在于一个`headless system`中,或者一个 `Display` 对应一个远程的、虚拟的display. * `display` object * `id` Integer - 与display 相关的唯一性标志. From 57bdbd818544f3006d0ca289fedba6cf2a1bd40b Mon Sep 17 00:00:00 2001 From: StoneStoneStone Date: Wed, 20 Apr 2016 10:39:47 +0800 Subject: [PATCH 041/141] Update download-item.md --- docs-translations/zh-CN/api/download-item.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/zh-CN/api/download-item.md b/docs-translations/zh-CN/api/download-item.md index a8ed266479d0..e869e8f30570 100644 --- a/docs-translations/zh-CN/api/download-item.md +++ b/docs-translations/zh-CN/api/download-item.md @@ -1,7 +1,7 @@ # DownloadItem `DownloadItem`(下载项)是一个在Electron中展示下载项的 -[EventEmitter](https://github.com/nodejs/node/blob/master/doc/api/events.markdown)(nodejs)。 +[EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)。 它被用于`Session`模块中的`will-download`事件,允许用户去控制下载项。 ```javascript From bdde5fd7adf33ede7f6f0aa8d55bdf29003fd873 Mon Sep 17 00:00:00 2001 From: StoneStoneStone Date: Wed, 20 Apr 2016 10:58:32 +0800 Subject: [PATCH 042/141] Update screen.md --- docs-translations/zh-CN/api/screen.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-translations/zh-CN/api/screen.md b/docs-translations/zh-CN/api/screen.md index bd4aec8b3709..3919ebabb779 100644 --- a/docs-translations/zh-CN/api/screen.md +++ b/docs-translations/zh-CN/api/screen.md @@ -54,7 +54,7 @@ app.on('ready', function() { ## `Display` 对象 -`Display` 对象表示一个连接到系统的物理显示. 一个虚设的 `Display` 或许存在于一个`headless system`中,或者一个 `Display` 对应一个远程的、虚拟的display. +`Display` 对象表示一个连接到系统的物理显示. 一个虚设的 `Display` 或许存在于一个无头系统(headless system)中,或者一个 `Display` 对应一个远程的、虚拟的display. * `display` object * `id` Integer - 与display 相关的唯一性标志. From 794d1207547dd422dc4791ab09deaaf7283155bf Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Wed, 20 Apr 2016 08:45:49 +0530 Subject: [PATCH 043/141] rename importClientCertificate => importCertificate --- atom/browser/api/atom_api_app.cc | 6 +++--- atom/browser/api/atom_api_app.h | 4 ++-- docs/api/app.md | 12 ++++++++++++ spec/api-app-spec.js | 6 +++--- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 46402d7f9b28..9d0aa792e607 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -167,7 +167,7 @@ int ImportIntoCertStore( base::string16 password; net::CertificateList imported_certs; int rv = -1; - options.GetString("clientCertificate", &cert_path); + options.GetString("certificate", &cert_path); options.GetString("password", &password); if (!cert_path.empty()) { @@ -405,7 +405,7 @@ bool App::MakeSingleInstance( } #if defined(USE_NSS_CERTS) -void App::ImportClientCertificate( +void App::ImportCertificate( const base::DictionaryValue& options, const net::CompletionCallback& callback) { auto browser_context = AtomBrowserMainParts::Get()->browser_context(); @@ -474,7 +474,7 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( &App::AllowNTLMCredentialsForAllDomains) .SetMethod("getLocale", &App::GetLocale) #if defined(USE_NSS_CERTS) - .SetMethod("importClientCertificate", &App::ImportClientCertificate) + .SetMethod("importCertificate", &App::ImportCertificate) #endif .SetMethod("makeSingleInstance", &App::MakeSingleInstance); } diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index acaa64a3437e..d4102521c0b4 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -111,8 +111,8 @@ class App : public AtomBrowserClient::Delegate, std::string GetLocale(); #if defined(USE_NSS_CERTS) - void ImportClientCertificate(const base::DictionaryValue& options, - const net::CompletionCallback& callback); + void ImportCertificate(const base::DictionaryValue& options, + const net::CompletionCallback& callback); #endif #if defined(OS_WIN) diff --git a/docs/api/app.md b/docs/api/app.md index 84eeed51d6cc..c8ddb47bd315 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -514,6 +514,18 @@ if (browserOptions.transparent) { This method returns `true` if the system is in Dark Mode, and `false` otherwise. +### `app.importCertificate(options, callback)` _LINUX_ + +* `options` Object + * `certificate` String - Path for the pkcs12 file. + * `password` String - Passphrase for the certificate. +* `callback` Function + * `result` Integer - Result of import. + +Imports the certificate in pkcs12 format into the platform certificate store. +`callback` is called with the `result` of import operation, a value of `0` indicates +success while any other value indicates failure according to chromium [net_error_list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h). + ### `app.commandLine.appendSwitch(switch[, value])` Append a switch (with optional `value`) to Chromium's command line. diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 8923d2d214fa..1c20ef8e4523 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -89,7 +89,7 @@ describe('app module', function () { }) }) - describe('app.importClientCertificate', function () { + describe('app.importCertificate', function () { if (process.platform !== 'linux') return @@ -124,7 +124,7 @@ describe('app module', function () { it('can import certificate into platform cert store', function (done) { let options = { - clientCertificate: path.join(certPath, 'client.p12'), + certificate: path.join(certPath, 'client.p12'), password: 'electron' } @@ -143,7 +143,7 @@ describe('app module', function () { callback(list[0]) }) - app.importClientCertificate(options, function (result) { + app.importCertificate(options, function (result) { assert(!result) server.listen(0, '127.0.0.1', function () { var port = server.address().port From a3e8591a41b98fa0cd8a9cff9a344bb300bc9db7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 20 Apr 2016 13:34:30 +0900 Subject: [PATCH 044/141] Update brightray for #5208 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index bc9c496a6185..8dbaeed37b9c 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit bc9c496a6185e37e792c10bfc5b49ea779b27cd3 +Subproject commit 8dbaeed37b9c4fb8ae985670b142f659bb265fb4 From d3e879cd7f3cc7093ebc9246eaccd2b5857faebb Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Tue, 19 Apr 2016 22:05:09 -0700 Subject: [PATCH 045/141] Change `WebContents::IsLoadingMainFrame` to compare SiteInstances (per @deepak1556's recommendation) Also updates tests to cover the situation where navigating between pages from the same potential "site" and adds generalized tests for `isLoadingMainFrame()`. --- atom/browser/api/atom_api_web_contents.cc | 34 +++------- atom/browser/api/atom_api_web_contents.h | 23 ++----- spec/api-browser-window-spec.js | 76 +++++++++++++++++------ 3 files changed, 69 insertions(+), 64 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 7c7e5896abc1..e39fa985e26b 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -220,8 +220,7 @@ WebContents::WebContents(content::WebContents* web_contents) embedder_(nullptr), type_(REMOTE), request_id_(0), - background_throttling_(true), - is_loading_main_frame_(false) { + background_throttling_(true) { AttachAsUserData(web_contents); web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); } @@ -230,8 +229,7 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) : embedder_(nullptr), request_id_(0), - background_throttling_(true), - is_loading_main_frame_(false) { + background_throttling_(true) { // Read options. options.Get("backgroundThrottling", &background_throttling_); @@ -545,32 +543,12 @@ void WebContents::DocumentLoadedInFrame( void WebContents::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) { bool is_main_frame = !render_frame_host->GetParent(); - if (is_main_frame) - is_loading_main_frame_ = false; - Emit("did-frame-finish-load", is_main_frame); if (is_main_frame) Emit("did-finish-load"); } -void WebContents::DidStartProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& url, - bool is_error_page, - bool is_iframe_srcdoc) { - if (!render_frame_host->GetParent()) - is_loading_main_frame_ = true; -} - -void WebContents::DidCommitProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& url, - ui::PageTransition transition_type) { - if (!render_frame_host->GetParent()) - is_loading_main_frame_ = true; -} - void WebContents::DidFailProvisionalLoad( content::RenderFrameHost* render_frame_host, const GURL& url, @@ -578,8 +556,6 @@ void WebContents::DidFailProvisionalLoad( const base::string16& description, bool was_ignored_by_handler) { bool is_main_frame = !render_frame_host->GetParent(); - if (is_main_frame) - is_loading_main_frame_ = false; Emit("did-fail-provisional-load", code, description, url, is_main_frame); Emit("did-fail-load", code, description, url, is_main_frame); } @@ -818,7 +794,11 @@ bool WebContents::IsLoading() const { } bool WebContents::IsLoadingMainFrame() const { - return is_loading_main_frame_; + // Comparing site instances works because Electron always creates a new site + // instance when navigating, regardless of origin. See AtomBrowserClient. + return (web_contents()->GetLastCommittedURL().is_empty() || + web_contents()->GetSiteInstance() != + web_contents()->GetPendingSiteInstance()) && IsLoading(); } bool WebContents::IsWaitingForResponse() const { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 292ec096088f..bc2d4106f5f2 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -224,21 +224,11 @@ class WebContents : public mate::TrackableObject, int error_code, const base::string16& error_description, bool was_ignored_by_handler) override; - void DidFailProvisionalLoad( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - bool was_ignored_by_handler) override; - void DidStartProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page, - bool is_iframe_srcdoc) override; - void DidCommitProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& url, - ui::PageTransition transition_type) override; + void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host, + const GURL& validated_url, + int error_code, + const base::string16& error_description, + bool was_ignored_by_handler) override; void DidStartLoading() override; void DidStopLoading() override; void DidGetResourceResponseStart( @@ -313,9 +303,6 @@ class WebContents : public mate::TrackableObject, // Whether background throttling is disabled. bool background_throttling_; - // Whether the main frame (not just a sub-frame) is currently loading. - bool is_loading_main_frame_; - DISALLOW_COPY_AND_ASSIGN(WebContents); }; diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 26d4ff4af35c..1110269e5de1 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -19,6 +19,23 @@ const isCI = remote.getGlobal('isCi') describe('browser-window module', function () { var fixtures = path.resolve(__dirname, 'fixtures') var w = null + var server + + before(function (done) { + server = http.createServer(function (req, res) { + function respond() { res.end(''); } + setTimeout(respond, req.url.includes('slow') ? 200 : 0) + }); + server.listen(0, '127.0.0.1', function () { + server.url = 'http://127.0.0.1:' + server.address().port + done() + }) + }) + + after(function () { + server.close() + server = null + }) beforeEach(function () { if (w != null) { @@ -635,6 +652,44 @@ describe('browser-window module', function () { assert.equal(w.isResizable(), true) }) }) + + describe('loading main frame state', function () { + it('is true when the main frame is loading', function (done) { + w.webContents.on('did-start-loading', function() { + assert.equal(w.webContents.isLoadingMainFrame(), true) + done() + }) + w.webContents.loadURL(server.url) + }) + + it('is false when only a subframe is loading', function (done) { + w.webContents.once('did-finish-load', function() { + assert.equal(w.webContents.isLoadingMainFrame(), false) + w.webContents.on('did-start-loading', function() { + assert.equal(w.webContents.isLoadingMainFrame(), false) + done() + }) + w.webContents.executeJavaScript(` + var iframe = document.createElement('iframe') + iframe.src = '${server.url}/page2' + document.body.appendChild(iframe) + `) + }) + w.webContents.loadURL(server.url) + }) + + it('is true when navigating to pages from the same origin', function (done) { + w.webContents.once('did-finish-load', function() { + assert.equal(w.webContents.isLoadingMainFrame(), false) + w.webContents.on('did-start-loading', function() { + assert.equal(w.webContents.isLoadingMainFrame(), true) + done() + }) + w.webContents.loadURL(`${server.url}/page2`) + }) + w.webContents.loadURL(server.url) + }) + }) }) describe('window states (excluding Linux)', function () { @@ -786,14 +841,6 @@ describe('browser-window module', function () { describe('window.webContents.executeJavaScript', function () { var expected = 'hello, world!' var code = '(() => "' + expected + '")()' - var server - - afterEach(function () { - if (server) { - server.close() - server = null - } - }) it('doesnt throw when no calback is provided', function () { const result = ipcRenderer.sendSync('executeJavaScript', code, false) @@ -809,21 +856,11 @@ describe('browser-window module', function () { }) it('works after page load and during subframe load', function (done) { - var url - // a slow server, guaranteeing time to execute code during loading - server = http.createServer(function (req, res) { - setTimeout(function() { res.end('') }, 200) - }); - server.listen(0, '127.0.0.1', function () { - url = 'http://127.0.0.1:' + server.address().port - w.loadURL('file://' + path.join(fixtures, 'pages', 'base-page.html')) - }) - w.webContents.once('did-finish-load', function() { // initiate a sub-frame load, then try and execute script during it w.webContents.executeJavaScript(` var iframe = document.createElement('iframe') - iframe.src = '${url}' + iframe.src = '${server.url}/slow' document.body.appendChild(iframe) `, function() { w.webContents.executeJavaScript(`console.log('hello')`, function() { @@ -831,6 +868,7 @@ describe('browser-window module', function () { }) }) }) + w.loadURL(server.url) }) }) From ff1b7d18f6499b73803ccee69037fb3b4b8bebf4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 20 Apr 2016 14:26:49 +0900 Subject: [PATCH 046/141] Cleanup the code determining value's type --- lib/browser/rpc-server.js | 59 +++++++++++++++----------------------- lib/renderer/api/remote.js | 22 +++++++------- 2 files changed, 35 insertions(+), 46 deletions(-) diff --git a/lib/browser/rpc-server.js b/lib/browser/rpc-server.js index 4603ba332c26..d512cbabf1cb 100644 --- a/lib/browser/rpc-server.js +++ b/lib/browser/rpc-server.js @@ -50,50 +50,37 @@ let getObjectPrototype = function (object) { } // Convert a real value into meta data. -var valueToMeta = function (sender, value, optimizeSimpleObject) { - var el, i, len, meta - if (optimizeSimpleObject == null) { - optimizeSimpleObject = false - } - meta = { - type: typeof value - } +let valueToMeta = function (sender, value, optimizeSimpleObject = false) { + // Determine the type of value. + let meta = { type: typeof value } if (Buffer.isBuffer(value)) { meta.type = 'buffer' - } - if (value === null) { + } else if (value === null) { meta.type = 'value' - } - if (Array.isArray(value)) { + } else if (Array.isArray(value)) { meta.type = 'array' - } - if (value instanceof Error) { + } else if (value instanceof Error) { meta.type = 'error' - } - if (value instanceof Date) { + } else if (value instanceof Date) { meta.type = 'date' - } - if ((value != null ? value.constructor.name : void 0) === 'Promise') { - meta.type = 'promise' - } - - // Treat simple objects as value. - if (optimizeSimpleObject && meta.type === 'object' && v8Util.getHiddenValue(value, 'simple')) { - meta.type = 'value' - } - - // Treat the arguments object as array. - if (meta.type === 'object' && (value.hasOwnProperty('callee')) && (value.length != null)) { - meta.type = 'array' - } - if (meta.type === 'array') { - meta.members = [] - for (i = 0, len = value.length; i < len; i++) { - el = value[i] - meta.members.push(valueToMeta(sender, el)) + } else if (meta.type === 'object') { + // Recognize certain types of objects. + if (value.constructor != null && value.constructor.name === 'Promise') { + meta.type = 'promise' + } else if (value.hasOwnProperty('callee') && value.length != null) { + // Treat the arguments object as array. + meta.type = 'array' + } else if (optimizeSimpleObject && v8Util.getHiddenValue(value, 'simple')) { + // Treat simple objects as value. + meta.type = 'value' } + } + + // Fill the meta object according to value's type. + if (meta.type === 'array') { + meta.members = value.map((el) => valueToMeta(sender, el)) } else if (meta.type === 'object' || meta.type === 'function') { - meta.name = value.constructor.name + meta.name = value.constructor ? value.constructor.name : '' // 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 diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index 8865c33c2772..d15ebd717ec5 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -45,17 +45,19 @@ var wrapArgs = function (args, visited) { type: 'date', value: value.getTime() } - } else if ((value != null ? value.constructor.name : void 0) === 'Promise') { - return { - type: 'promise', - then: valueToMeta(function (v) { value.then(v) }) - } - } else if ((value != null) && typeof value === 'object' && v8Util.getHiddenValue(value, 'atomId')) { - return { - type: 'remote-object', - id: v8Util.getHiddenValue(value, 'atomId') - } } else if ((value != null) && typeof value === 'object') { + if (value.constructor != null && value.constructor.name === 'Promise') { + return { + type: 'promise', + then: valueToMeta(function (v) { value.then(v) }) + } + } else if (v8Util.getHiddenValue(value, 'atomId')) { + return { + type: 'remote-object', + id: v8Util.getHiddenValue(value, 'atomId') + } + } + ret = { type: 'object', name: value.constructor.name, From 680652d01c4fc29d2b3315043632d11743cd9d5f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 20 Apr 2016 14:32:32 +0900 Subject: [PATCH 047/141] buffer, null, array etc. all belong to object --- lib/browser/rpc-server.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/browser/rpc-server.js b/lib/browser/rpc-server.js index d512cbabf1cb..ca193b4115e8 100644 --- a/lib/browser/rpc-server.js +++ b/lib/browser/rpc-server.js @@ -53,19 +53,19 @@ let getObjectPrototype = function (object) { let valueToMeta = function (sender, value, optimizeSimpleObject = false) { // Determine the type of value. let meta = { type: typeof value } - if (Buffer.isBuffer(value)) { - meta.type = 'buffer' - } else if (value === null) { - meta.type = 'value' - } else if (Array.isArray(value)) { - meta.type = 'array' - } else if (value instanceof Error) { - meta.type = 'error' - } else if (value instanceof Date) { - meta.type = 'date' - } else if (meta.type === 'object') { + if (meta.type === 'object') { // Recognize certain types of objects. - if (value.constructor != null && value.constructor.name === 'Promise') { + if (value === null) { + meta.type = 'value' + } else if (Buffer.isBuffer(value)) { + meta.type = 'buffer' + } else if (Array.isArray(value)) { + meta.type = 'array' + } else if (value instanceof Error) { + meta.type = 'error' + } else if (value instanceof Date) { + meta.type = 'date' + } else if (value.constructor != null && value.constructor.name === 'Promise') { meta.type = 'promise' } else if (value.hasOwnProperty('callee') && value.length != null) { // Treat the arguments object as array. From dc8fc7c079ec0eec416eedb0bfd54b68de42b1b8 Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Tue, 19 Apr 2016 23:27:22 -0700 Subject: [PATCH 048/141] :memo: Add English docs for `webContents.isLoadingMainFrame()` [ci skip] --- docs/api/web-contents.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 8fc7a959f69d..cb0998804a57 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -353,6 +353,10 @@ Returns the title of the current web page. Returns whether web page is still loading resources. +### `webContents.isLoadingMainFrame()` + +Returns whether the main frame (and not just iframes or frames within it) is still loading. + ### `webContents.isWaitingForResponse()` Returns whether the web page is waiting for a first-response from the main From ca756c3c2492c69c75c9a8c1d99dc29c73f3f942 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Wed, 20 Apr 2016 22:25:15 +0530 Subject: [PATCH 049/141] session: allow providing permission to handle external protocols --- .../atom_resource_dispatcher_host_delegate.cc | 35 ++++++++++++++++--- .../browser/web_contents_permission_helper.cc | 8 +++++ atom/browser/web_contents_permission_helper.h | 6 +++- .../content_converter.cc | 2 ++ docs/api/session.md | 3 +- spec/webview-spec.js | 11 +++++- 6 files changed, 58 insertions(+), 7 deletions(-) diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index 68576a52f248..59ac258ea13a 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -5,6 +5,7 @@ #include "atom/browser/atom_resource_dispatcher_host_delegate.h" #include "atom/browser/login_handler.h" +#include "atom/browser/web_contents_permission_helper.h" #include "atom/common/platform_util.h" #include "content/public/browser/browser_thread.h" #include "net/base/escape.h" @@ -14,20 +15,46 @@ using content::BrowserThread; namespace atom { +namespace { + +void OnOpenExternal(const GURL& escaped_url, + bool allowed) { + if (allowed) + platform_util::OpenExternal(escaped_url, true); +} + +void HandleExternalProtocolInUI( + const GURL& url, + const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter, + bool has_user_gesture) { + content::WebContents* web_contents = web_contents_getter.Run(); + if (!web_contents) + return; + + GURL escaped_url(net::EscapeExternalHandlerValue(url.spec())); + auto callback = base::Bind(&OnOpenExternal, escaped_url); + auto permission_helper = + WebContentsPermissionHelper::FromWebContents(web_contents); + permission_helper->RequestOpenExternalPermission(callback, has_user_gesture); +} + +} // namespace + AtomResourceDispatcherHostDelegate::AtomResourceDispatcherHostDelegate() { } bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( const GURL& url, int child_id, - const content::ResourceRequestInfo::WebContentsGetter&, + const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter, bool is_main_frame, ui::PageTransition transition, 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, true)); + base::Bind(&HandleExternalProtocolInUI, + url, + web_contents_getter, + has_user_gesture)); return true; } diff --git a/atom/browser/web_contents_permission_helper.cc b/atom/browser/web_contents_permission_helper.cc index d018e1d09dbc..7c944832d88d 100644 --- a/atom/browser/web_contents_permission_helper.cc +++ b/atom/browser/web_contents_permission_helper.cc @@ -91,4 +91,12 @@ void WebContentsPermissionHelper::RequestPointerLockPermission( user_gesture); } +void WebContentsPermissionHelper::RequestOpenExternalPermission( + const base::Callback& callback, + bool user_gesture) { + RequestPermission((content::PermissionType)(PermissionType::OPEN_EXTERNAL), + callback, + user_gesture); +} + } // namespace atom diff --git a/atom/browser/web_contents_permission_helper.h b/atom/browser/web_contents_permission_helper.h index 90ae6dff56f5..89da64b75833 100644 --- a/atom/browser/web_contents_permission_helper.h +++ b/atom/browser/web_contents_permission_helper.h @@ -19,7 +19,8 @@ class WebContentsPermissionHelper enum class PermissionType { POINTER_LOCK = static_cast(content::PermissionType::NUM) + 1, - FULLSCREEN + FULLSCREEN, + OPEN_EXTERNAL, }; void RequestFullscreenPermission( @@ -30,6 +31,9 @@ class WebContentsPermissionHelper void RequestWebNotificationPermission( const base::Callback& callback); void RequestPointerLockPermission(bool user_gesture); + void RequestOpenExternalPermission( + const base::Callback& callback, + bool user_gesture); private: explicit WebContentsPermissionHelper(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 f5d81d085bc1..7e7cd9bd1ff1 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -145,6 +145,8 @@ v8::Local Converter::ToV8( return StringToV8(isolate, "pointerLock"); else if (val == (content::PermissionType)(PermissionType::FULLSCREEN)) return StringToV8(isolate, "fullscreen"); + else if (val == (content::PermissionType)(PermissionType::OPEN_EXTERNAL)) + return StringToV8(isolate, "openExternal"); return StringToV8(isolate, "unknown"); } diff --git a/docs/api/session.md b/docs/api/session.md index 9cccefcbdb66..ecc65f550ed0 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -295,7 +295,8 @@ 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', 'pointerLock', 'fullscreen'. + * `permission` String - Enum of 'media', 'geolocation', 'notifications', 'midiSysex', + 'pointerLock', 'fullscreen', 'openExternal'. * `callback` Function - Allow or deny the permission. Sets the handler which can be used to respond to permission requests for the `session`. diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 10758a0a4365..88afbe2f131c 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -722,11 +722,13 @@ describe(' tag', function () { }) describe('permission-request event', function () { - function setUpRequestHandler (webview, requested_permission) { + function setUpRequestHandler (webview, requested_permission, completed) { var listener = function (webContents, permission, callback) { if (webContents.getId() === webview.getId()) { assert.equal(permission, requested_permission) callback(false) + if (completed) + completed() } } session.fromPartition(webview.partition).setPermissionRequestHandler(listener) @@ -770,6 +772,13 @@ describe(' tag', function () { setUpRequestHandler(webview, 'midiSysex') document.body.appendChild(webview) }) + + it('emits when accessing external protocol', function (done) { + webview.src = 'magnet:test' + webview.partition = 'permissionTest' + setUpRequestHandler(webview, 'openExternal', done) + document.body.appendChild(webview) + }) }) describe('.getWebContents', function () { From b5c1db9ad9901585e397492888b6320b724298fe Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 21 Apr 2016 11:17:12 +0900 Subject: [PATCH 050/141] Guard against unexist owner when removing ref to remote object --- lib/browser/objects-registry.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/browser/objects-registry.js b/lib/browser/objects-registry.js index b8aa480a6dba..adbf6835554c 100644 --- a/lib/browser/objects-registry.js +++ b/lib/browser/objects-registry.js @@ -50,7 +50,10 @@ class ObjectsRegistry { this.dereference(id) // Also remove the reference in owner. - this.owners[webContentsId].delete(id) + let owner = this.owners[webContentsId] + if (owner) { + owner.delete(id) + } } // Clear all references to objects refrenced by the WebContents. From 0900762507570b8e823d6eb14c43821842128f26 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 21 Apr 2016 13:58:11 +0900 Subject: [PATCH 051/141] Make the length of SingletonSocket's path as short as we can --- .../chrome/browser/process_singleton_posix.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/chromium_src/chrome/browser/process_singleton_posix.cc b/chromium_src/chrome/browser/process_singleton_posix.cc index 7e54d9b5d370..c583db0162a0 100644 --- a/chromium_src/chrome/browser/process_singleton_posix.cc +++ b/chromium_src/chrome/browser/process_singleton_posix.cc @@ -111,7 +111,7 @@ const base::FilePath::CharType kSingletonCookieFilename[] = const base::FilePath::CharType kSingletonLockFilename[] = FILE_PATH_LITERAL("SingletonLock"); const base::FilePath::CharType kSingletonSocketFilename[] = - FILE_PATH_LITERAL("SingletonSocket"); + FILE_PATH_LITERAL("SS"); // Set the close-on-exec bit on a file descriptor. // Returns 0 on success, -1 on failure. @@ -943,6 +943,19 @@ bool ProcessSingleton::Create() { #endif } +#if defined(MAS_BUILD) + // For Mac App Store build, the tmp dir could be too long to fit + // addr->sun_path, so we need to make it as short as possible. + base::FilePath tmp_dir; + if (!base::GetTempDir(&tmp_dir)) { + LOG(ERROR) << "Failed to get temporary directory."; + return false; + } + if (!socket_dir_.Set(tmp_dir.Append("S"))) { + LOG(ERROR) << "Failed to set socket directory."; + return false; + } +#else // Create the socket file somewhere in /tmp which is usually mounted as a // normal filesystem. Some network filesystems (notably AFS) are screwy and // do not support Unix domain sockets. @@ -950,6 +963,7 @@ bool ProcessSingleton::Create() { LOG(ERROR) << "Failed to create socket directory."; return false; } +#endif // Check that the directory was created with the correct permissions. int dir_mode = 0; From df97be30e5903958ad75f661c0079d77d6644206 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 21 Apr 2016 14:37:29 +0900 Subject: [PATCH 052/141] Do not create the folder passed to app.setPath --- atom/browser/api/atom_api_app.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 9d0aa792e607..d239a63d0581 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -351,10 +351,15 @@ base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) { void App::SetPath(mate::Arguments* args, const std::string& name, const base::FilePath& path) { + if (!path.IsAbsolute()) { + args->ThrowError("path must be absolute"); + return; + } + bool succeed = false; int key = GetPathConstant(name); if (key >= 0) - succeed = PathService::Override(key, path); + succeed = PathService::OverrideAndCreateIfNeeded(key, path, true, false); if (!succeed) args->ThrowError("Failed to set path"); } From 2a2a8d3263c0d35c1e1248c7da873b75a23760d8 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Wed, 20 Apr 2016 23:55:56 -0700 Subject: [PATCH 053/141] Add Windows Store Detection If we're running as a Windows Store appx package, `process.windowsstore` will be `true`, otherwise `undefined`. --- docs/api/process.md | 2 ++ lib/common/init.js | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/docs/api/process.md b/docs/api/process.md index 620ad6dc931a..c5506f7e25b7 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -10,6 +10,8 @@ upstream node: * `process.resourcesPath` String - Path to JavaScript source code. * `process.mas` Boolean - For Mac App Store build, this value is `true`, for other builds it is `undefined`. +* `process.windowsstore` Boolean - If the app is running as a Windows Store app (appx), this value is `true`, for + other builds it is `undefined`. ## Events diff --git a/lib/common/init.js b/lib/common/init.js index 221febb0c37a..8790320376d2 100644 --- a/lib/common/init.js +++ b/lib/common/init.js @@ -44,3 +44,12 @@ if (process.type === 'browser') { global.setTimeout = wrapWithActivateUvLoop(timers.setTimeout) global.setInterval = wrapWithActivateUvLoop(timers.setInterval) } + +// If we're running as a Windows Store app, __dirname will be set +// to C:/Program Files/WindowsApps. +// +// Nobody else get's to install there, changing the path is forbidden +// We can therefore say that we're running as appx +if (process.platform === 'win32' && __dirname.indexOf('\\Program Files\\WindowsApps\\') === 2) { + process.windowsstore = true +} From e4bd592e0e712a4ba0f3da28eb61e7fb3cd5695a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 21 Apr 2016 11:49:42 -0700 Subject: [PATCH 054/141] Add failing spec --- spec/fixtures/module/answer.js | 4 +++ spec/fixtures/pages/web-view-log-process.html | 13 ++++++++ ...webview-no-node-integration-on-window.html | 23 +++++++++++++ spec/webview-spec.js | 33 +++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 spec/fixtures/module/answer.js create mode 100644 spec/fixtures/pages/web-view-log-process.html create mode 100644 spec/fixtures/pages/webview-no-node-integration-on-window.html diff --git a/spec/fixtures/module/answer.js b/spec/fixtures/module/answer.js new file mode 100644 index 000000000000..d592d6cda214 --- /dev/null +++ b/spec/fixtures/module/answer.js @@ -0,0 +1,4 @@ +var ipcRenderer = require('electron').ipcRenderer +window.answer = function (answer) { + ipcRenderer.send('answer', answer) +} diff --git a/spec/fixtures/pages/web-view-log-process.html b/spec/fixtures/pages/web-view-log-process.html new file mode 100644 index 000000000000..9e75edb393e2 --- /dev/null +++ b/spec/fixtures/pages/web-view-log-process.html @@ -0,0 +1,13 @@ + + + + + test + + + + test? + + diff --git a/spec/fixtures/pages/webview-no-node-integration-on-window.html b/spec/fixtures/pages/webview-no-node-integration-on-window.html new file mode 100644 index 000000000000..0af03cf1c497 --- /dev/null +++ b/spec/fixtures/pages/webview-no-node-integration-on-window.html @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 88afbe2f131c..d2c37c857df1 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -84,6 +84,39 @@ describe(' tag', function () { document.body.appendChild(webview) }) + it('disables node integration when disabled on the parent BrowserWindow', function (done) { + var b = undefined + + ipcMain.once('answer', function (event, typeofProcess) { + try { + assert.equal(typeofProcess, 'undefined') + done() + } finally { + b.close() + } + }) + + var windowUrl = require('url').format({ + pathname: `${fixtures}/pages/webview-no-node-integration-on-window.html`, + protocol: 'file', + query: { + p: `${fixtures}/pages/web-view-log-process.html` + }, + slashes: true + }) + var preload = path.join(fixtures, 'module', 'answer.js') + + b = new BrowserWindow({ + height: 400, + width: 400, + show: false, + webPreferences: { + preload: preload, + nodeIntegration: false, + } + }) + b.loadURL(windowUrl) + }) it('disables node integration on child windows when it is disabled on the webview', function (done) { app.once('browser-window-created', function (event, window) { From 8e7bf1051d9f35837ce7a0a6009a61b5642b8ca1 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 21 Apr 2016 11:52:10 -0700 Subject: [PATCH 055/141] Disable node integration on webview when disabled on window --- lib/browser/guest-view-manager.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index ad79fe699a40..58775669c2f4 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -182,6 +182,11 @@ var attachGuest = function (embedder, elementInstanceId, guestInstanceId, params webSecurity: !params.disablewebsecurity, blinkFeatures: params.blinkfeatures } + + if (embedder.getWebPreferences().nodeIntegration === false) { + webPreferences.nodeIntegration = false + } + if (params.preload) { webPreferences.preloadURL = params.preload } From b45f6836554f6a4e1451df0560cddb976ed79045 Mon Sep 17 00:00:00 2001 From: Daniel Pereira Date: Thu, 21 Apr 2016 17:00:19 -0500 Subject: [PATCH 056/141] Update desktop-capturer.md Fixed native image link. --- docs/api/desktop-capturer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/desktop-capturer.md b/docs/api/desktop-capturer.md index 3babe0e16383..bf775c3a6d2e 100644 --- a/docs/api/desktop-capturer.md +++ b/docs/api/desktop-capturer.md @@ -72,7 +72,7 @@ captured screen or individual window, and has following properties: * `name` String - The described name of the capturing screen or window. If the source is a screen, the name will be `Entire Screen` or `Screen `; if it is a window, the name will be the window's title. -* `thumbnail` [NativeImage](NativeImage.md) - A thumbnail image. +* `thumbnail` A thumbnail [native image](native-image.md). **Note:** There is no guarantee that the size of `source.thumbnail` is always the same as the `thumnbailSize` in `options`. It also depends on the scale of From c0f63eed4eaf3134e55c6b1cf75050e0ca5a9fe2 Mon Sep 17 00:00:00 2001 From: Felix Rieseberg Date: Thu, 21 Apr 2016 19:11:25 -0700 Subject: [PATCH 057/141] :art: Windows Store Camels --- docs/api/process.md | 2 +- lib/common/init.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/process.md b/docs/api/process.md index c5506f7e25b7..b2d9c765a03a 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -10,7 +10,7 @@ upstream node: * `process.resourcesPath` String - Path to JavaScript source code. * `process.mas` Boolean - For Mac App Store build, this value is `true`, for other builds it is `undefined`. -* `process.windowsstore` Boolean - If the app is running as a Windows Store app (appx), this value is `true`, for +* `process.windowsStore` Boolean - If the app is running as a Windows Store app (appx), this value is `true`, for other builds it is `undefined`. ## Events diff --git a/lib/common/init.js b/lib/common/init.js index 8790320376d2..11c098d3ce5c 100644 --- a/lib/common/init.js +++ b/lib/common/init.js @@ -51,5 +51,5 @@ if (process.type === 'browser') { // Nobody else get's to install there, changing the path is forbidden // We can therefore say that we're running as appx if (process.platform === 'win32' && __dirname.indexOf('\\Program Files\\WindowsApps\\') === 2) { - process.windowsstore = true + process.windowsStore = true } From c04d43ca132bea2bbd048c2bf3d347b920089438 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 22 Apr 2016 17:39:11 +0900 Subject: [PATCH 058/141] Bump v0.37.7 --- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- electron.gyp | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 50522ddda178..8cfb63688910 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile electron.icns CFBundleVersion - 0.37.6 + 0.37.7 CFBundleShortVersionString - 0.37.6 + 0.37.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 473cd151f9ac..bcd4a829369f 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,6,0 - PRODUCTVERSION 0,37,6,0 + FILEVERSION 0,37,7,0 + PRODUCTVERSION 0,37,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.37.6" + VALUE "FileVersion", "0.37.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.37.6" + VALUE "ProductVersion", "0.37.7" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 65921c77581a..dab2966bb997 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 6 +#define ATOM_PATCH_VERSION 7 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/electron.gyp b/electron.gyp index 11a35490923b..e6134df117b8 100644 --- a/electron.gyp +++ b/electron.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.37.6', + 'version%': '0.37.7', }, 'includes': [ 'filenames.gypi', diff --git a/package.json b/package.json index d6306b8406ee..aa7ca37e5eb8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.37.6", + "version": "0.37.7", "devDependencies": { "asar": "^0.11.0", "request": "*", From da727a3c1bdbf5cfaa55b7e718dc280d2d0a720d Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Fri, 22 Apr 2016 12:32:11 +0200 Subject: [PATCH 059/141] Fix display.rotation documentation --- docs/api/screen.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/screen.md b/docs/api/screen.md index 4d12f1359f7f..0dbf5b35a298 100644 --- a/docs/api/screen.md +++ b/docs/api/screen.md @@ -62,8 +62,8 @@ a remote, virtual display. * `display` object * `id` Integer - Unique identifier associated with the display. - * `rotation` Integer - Can be 0, 1, 2, 3, each represents screen rotation in - clock-wise degrees of 0, 90, 180, 270. + * `rotation` Integer - Can be 0, 90, 180, 270, represents screen rotation in + clock-wise degrees. * `scaleFactor` Number - Output device's pixel scale factor. * `touchSupport` String - Can be `available`, `unavailable`, `unknown`. * `bounds` Object From 0282180b9c4ec0ee16385b3b002857e9bb1e4a6a Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 22 Apr 2016 22:20:41 +0900 Subject: [PATCH 060/141] :memo: Correct description style [ci skip] --- docs/api/desktop-capturer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/desktop-capturer.md b/docs/api/desktop-capturer.md index bf775c3a6d2e..b39a09e5aa8b 100644 --- a/docs/api/desktop-capturer.md +++ b/docs/api/desktop-capturer.md @@ -40,7 +40,7 @@ function getUserMediaError(e) { When creating a constraints object for the `navigator.webkitGetUserMedia` call, if you are using a source from `desktopCapturer` your `chromeMediaSource` must -be set to `"desktop"` and your `audio` must be set to `false`. +be set to `"desktop"` and your `audio` must be set to `false`. If you wish to capture the audio and video from the entire desktop you can set @@ -72,7 +72,7 @@ captured screen or individual window, and has following properties: * `name` String - The described name of the capturing screen or window. If the source is a screen, the name will be `Entire Screen` or `Screen `; if it is a window, the name will be the window's title. -* `thumbnail` A thumbnail [native image](native-image.md). +* `thumbnail` [NativeImage](native-image.md) - A thumbnail native image. **Note:** There is no guarantee that the size of `source.thumbnail` is always the same as the `thumnbailSize` in `options`. It also depends on the scale of From 4f4277e25e2207a879501d0fc76be28b4a9d3b1f Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 22 Apr 2016 22:53:26 +0900 Subject: [PATCH 061/141] :memo: Fix coding style issues * Adjust line length to `80` * Normalize whitespaces [ci skip] --- docs/api/app.md | 4 ++-- docs/api/auto-updater.md | 7 +++++-- docs/api/browser-window.md | 13 ++++++------ docs/api/crash-reporter.md | 3 ++- docs/api/dialog.md | 3 ++- docs/api/frameless-window.md | 8 ++++++-- docs/api/menu-item.md | 9 +++++---- docs/api/process.md | 4 ++-- docs/api/session.md | 5 +++-- docs/api/synopsis.md | 4 ++-- docs/api/web-contents.md | 13 +++++++----- docs/api/web-view-tag.md | 20 +++++++++---------- docs/development/build-instructions-osx.md | 4 ++-- .../development/build-instructions-windows.md | 3 ++- docs/development/build-system-overview.md | 5 +++-- docs/development/coding-style.md | 6 ++++-- docs/faq/electron-faq.md | 4 ++-- docs/tutorial/debugging-main-process.md | 5 +++-- .../desktop-environment-integration.md | 3 +-- docs/tutorial/quick-start.md | 4 ++-- 20 files changed, 73 insertions(+), 54 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index c8ddb47bd315..f86a205e6f96 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -523,8 +523,8 @@ This method returns `true` if the system is in Dark Mode, and `false` otherwise. * `result` Integer - Result of import. Imports the certificate in pkcs12 format into the platform certificate store. -`callback` is called with the `result` of import operation, a value of `0` indicates -success while any other value indicates failure according to chromium [net_error_list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h). +`callback` is called with the `result` of import operation, a value of `0` +indicates success while any other value indicates failure according to chromium [net_error_list](https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h). ### `app.commandLine.appendSwitch(switch[, value])` diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index 8dd6d2412a4a..dccae1212aa0 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -5,8 +5,11 @@ 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 using one of these projects: -- [electron-release-server][electron-release-server]: *A fully featured, self-hosted release server for electron applications, compatible with auto-updater* -- [squirrel-updates-server][squirrel-updates-server]: *A simple node.js server for Squirrel.Mac and Squirrel.Windows which uses GitHub releases* +- [electron-release-server][electron-release-server]: *A fully featured, + self-hosted release server for electron applications, compatible with + auto-updater* +- [squirrel-updates-server][squirrel-updates-server]: *A simple node.js server + for Squirrel.Mac and Squirrel.Windows which uses GitHub releases* ## Platform notices diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 67f8c737a0cf..97dd2d972950 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -311,7 +311,8 @@ Emitted when an [App Command](https://msdn.microsoft.com/en-us/library/windows/d 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. +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 @@ -677,9 +678,9 @@ window. ### `win.setSheetOffset(offset)` -Changes the attachment point for sheets on Mac OS X. By default, sheets are attached -just below the window frame, but you may want to display them beneath a HTML-rendered -toolbar. For example: +Changes the attachment point for sheets on Mac OS X. By default, sheets are +attached just below the window frame, but you may want to display them beneath +a HTML-rendered toolbar. For example: ``` var toolbarRect = document.getElementById('toolbar').getBoundingClientRect(); @@ -823,8 +824,8 @@ 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. +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_ diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index 64e5602474a9..9b7141e364e9 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -60,7 +60,8 @@ ID. ## crash-reporter Payload -The crash reporter will send the following data to the `submitURL` as a `multipart/form-data` `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'. diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 1cea9da119ad..3eb0292a4937 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -12,7 +12,8 @@ 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: +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; diff --git a/docs/api/frameless-window.md b/docs/api/frameless-window.md index 3c26a36b0329..8e1dd46ec56e 100644 --- a/docs/api/frameless-window.md +++ b/docs/api/frameless-window.md @@ -1,6 +1,9 @@ # Frameless Window -A frameless window is a window that has no [chrome](https://developer.mozilla.org/en-US/docs/Glossary/Chrome), the parts of the window, like toolbars, that are not a part of the web page. These are options on the [`BrowserWindow`](browser-window.md) class. +A frameless window is a window that has no +[chrome](https://developer.mozilla.org/en-US/docs/Glossary/Chrome), the parts of +the window, like toolbars, that are not a part of the web page. These are +options on the [`BrowserWindow`](browser-window.md) class. ## Create a frameless window @@ -38,7 +41,8 @@ var win = new BrowserWindow({ transparent: true, frame: false }); ### Limitations * You can not click through the transparent area. We are going to introduce an - API to set window shape to solve this, see [our issue](https://github.com/electron/electron/issues/1335) for details. + API to set window shape to solve this, see + [our issue](https://github.com/electron/electron/issues/1335) for details. * Transparent windows are not resizable. Setting `resizable` to `true` may make a transparent window stop working on some platforms. * The `blur` filter only applies to the web page, so there is no way to apply diff --git a/docs/api/menu-item.md b/docs/api/menu-item.md index 0029ba14dd4b..1b36432ab297 100644 --- a/docs/api/menu-item.md +++ b/docs/api/menu-item.md @@ -22,9 +22,10 @@ Create a new `MenuItem` with the following method: * `sublabel` String * `accelerator` [Accelerator](accelerator.md) * `icon` [NativeImage](native-image.md) - * `enabled` Boolean - If false, the menu item will be greyed out and unclickable. + * `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 + * `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 @@ -61,7 +62,8 @@ On OS X `role` can also have following additional values: * `help` - The submenu is a "Help" menu * `services` - The submenu is a "Services" menu -When specifying `role` on OS X, `label` and `accelerator` are the only options that will affect the MenuItem. All other options will be ignored. +When specifying `role` on OS X, `label` and `accelerator` are the only options +that will affect the MenuItem. All other options will be ignored. ## Instance Properties @@ -79,4 +81,3 @@ 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. - diff --git a/docs/api/process.md b/docs/api/process.md index b2d9c765a03a..ce76eb2d99aa 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -10,8 +10,8 @@ upstream node: * `process.resourcesPath` String - Path to JavaScript source code. * `process.mas` Boolean - For Mac App Store build, this value is `true`, for other builds it is `undefined`. -* `process.windowsStore` Boolean - If the app is running as a Windows Store app (appx), this value is `true`, for - other builds it is `undefined`. +* `process.windowsStore` Boolean - If the app is running as a Windows Store app + (appx), this value is `true`, for other builds it is `undefined`. ## Events diff --git a/docs/api/session.md b/docs/api/session.md index ecc65f550ed0..b8ea23434cd3 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -447,8 +447,9 @@ The `callback` has to be called with an `response` object: * `cancel` Boolean * `responseHeaders` Object (optional) - When provided, the server is assumed to have responded with these headers. - * `statusLine` String (optional) - Should be provided when overriding `responseHeaders` - to change header status otherwise original response header's status will be used. + * `statusLine` String (optional) - Should be provided when overriding + `responseHeaders` to change header status otherwise original response + header's status will be used. #### `ses.webRequest.onResponseStarted([filter, ]listener)` diff --git a/docs/api/synopsis.md b/docs/api/synopsis.md index 015674c2ef6f..466b13828c41 100644 --- a/docs/api/synopsis.md +++ b/docs/api/synopsis.md @@ -11,8 +11,8 @@ both processes. The basic rule is: if a module is [GUI][gui] or low-level system related, then it should be only available in the main process. You need to be familiar with -the concept of [main process vs. renderer process](../tutorial/quick-start.md#the-main-process) scripts to be -able to use those modules. +the concept of [main process vs. renderer process](../tutorial/quick-start.md#the-main-process) +scripts to be able to use those modules. The main process script is just like a normal Node.js script: diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 9acceadd360d..0eee6c5bf8bb 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -278,7 +278,8 @@ Emitted when media is paused or done playing. ### Event: 'did-change-theme-color' -Emitted when a page's theme color changes. This is usually due to encountering a meta tag: +Emitted when a page's theme color changes. This is usually due to encountering +a meta tag: ```html @@ -355,7 +356,8 @@ Returns whether web page is still loading resources. ### `webContents.isLoadingMainFrame()` -Returns whether the main frame (and not just iframes or frames within it) is still loading. +Returns whether the main frame (and not just iframes or frames within it) is +still loading. ### `webContents.isWaitingForResponse()` @@ -525,9 +527,10 @@ Inserts `text` to the focused element. uppercase letter followed by a lowercase or non-letter. Accepts several other intra-word matches, defaults to `false`. -Starts a request to find all matches for the `text` in the web page and returns an `Integer` -representing the request id used for the request. The result of the request can be -obtained by subscribing to [`found-in-page`](web-contents.md#event-found-in-page) event. +Starts a request to find all matches for the `text` in the web page and returns +an `Integer` representing the request id used for the request. The result of +the request can be obtained by subscribing to +[`found-in-page`](web-contents.md#event-found-in-page) event. ### `webContents.stopFindInPage(action)` diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index c77d3c690b85..214f93dbad6f 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -47,17 +47,17 @@ and displays a "loading..." message during the load time: ## CSS Styling Notes -Please note that the `webview` tag's style uses `display:flex;` internally to -ensure the child `object` element fills the full height and width of its `webview` -container when used with traditional and flexbox layouts (since v0.36.11). Please -do not overwrite the default `display:flex;` CSS property, unless specifying +Please note that the `webview` tag's style uses `display:flex;` internally to +ensure the child `object` element fills the full height and width of its `webview` +container when used with traditional and flexbox layouts (since v0.36.11). Please +do not overwrite the default `display:flex;` CSS property, unless specifying `display:inline-flex;` for inline layout. -`webview` has issues being hidden using the `hidden` attribute or using `display: none;`. -It can cause unusual rendering behaviour within its child `browserplugin` object -and the web page is reloaded, when the `webview` is un-hidden, as opposed to just -becoming visible again. The recommended approach is to hide the `webview` using -CSS by zeroing the `width` & `height` and allowing the element to shrink to the 0px +`webview` has issues being hidden using the `hidden` attribute or using `display: none;`. +It can cause unusual rendering behaviour within its child `browserplugin` object +and the web page is reloaded, when the `webview` is un-hidden, as opposed to just +becoming visible again. The recommended approach is to hide the `webview` using +CSS by zeroing the `width` & `height` and allowing the element to shrink to the 0px dimensions via `flex`. ```html @@ -70,7 +70,7 @@ dimensions via `flex`. webview.hide { flex: 0 1; width: 0px; - height: 0px; + height: 0px; } ``` diff --git a/docs/development/build-instructions-osx.md b/docs/development/build-instructions-osx.md index 02bdb72e2279..b703a75897d9 100644 --- a/docs/development/build-instructions-osx.md +++ b/docs/development/build-instructions-osx.md @@ -22,8 +22,8 @@ $ git clone https://github.com/electron/electron.git ## Bootstrapping The bootstrap script will download all necessary build dependencies and create -the build project files. Notice that we're using [ninja](https://ninja-build.org/) to build Electron so -there is no Xcode project generated. +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 $ cd electron diff --git a/docs/development/build-instructions-windows.md b/docs/development/build-instructions-windows.md index 73526b362584..3f94a18393cf 100644 --- a/docs/development/build-instructions-windows.md +++ b/docs/development/build-instructions-windows.md @@ -11,7 +11,8 @@ Follow the guidelines below for building Electron on Windows. * [Node.js](http://nodejs.org/download/) * [Git](http://git-scm.com) -If you don't currently have a Windows installation, [modern.ie](https://www.modern.ie/en-us/virtualization-tools#downloads) +If you don't currently have a Windows installation, +[modern.ie](https://www.modern.ie/en-us/virtualization-tools#downloads) has timebombed versions of Windows that you can use to build Electron. Building Electron is done entirely with command-line scripts and cannot be done diff --git a/docs/development/build-system-overview.md b/docs/development/build-system-overview.md index 61b88e14078c..bc27c1932fa6 100644 --- a/docs/development/build-system-overview.md +++ b/docs/development/build-system-overview.md @@ -1,7 +1,8 @@ # Build System Overview -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. +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 diff --git a/docs/development/coding-style.md b/docs/development/coding-style.md index baf2a2cce7de..1840700f5237 100644 --- a/docs/development/coding-style.md +++ b/docs/development/coding-style.md @@ -45,8 +45,10 @@ Electron APIs uses the same capitalization scheme as Node.js: - When the module itself is a class like `BrowserWindow`, use `CamelCase`. - When the module is a set of APIs, like `globalShortcut`, use `mixedCase`. -- When the API is a property of object, and it is complex enough to be in a separate chapter like `win.webContents`, use `mixedCase`. -- For other non-module APIs, use natural titles, like ` Tag` or `Process Object`. +- When the API is a property of object, and it is complex enough to be in a + separate chapter like `win.webContents`, use `mixedCase`. +- For other non-module APIs, use natural titles, like ` Tag` or + `Process Object`. When creating a new API, it is preferred to use getters and setters instead of jQuery's one-function style. For example, `.getText()` and `.setText(text)` diff --git a/docs/faq/electron-faq.md b/docs/faq/electron-faq.md index 41b301d71981..02d72744e657 100644 --- a/docs/faq/electron-faq.md +++ b/docs/faq/electron-faq.md @@ -77,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 the DOM like `module`, `exports`, `require`. This causes problems for -some libraries since they want to insert the symbols with the same names. +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: diff --git a/docs/tutorial/debugging-main-process.md b/docs/tutorial/debugging-main-process.md index ee7fc4c5fa47..714b7100cf47 100644 --- a/docs/tutorial/debugging-main-process.md +++ b/docs/tutorial/debugging-main-process.md @@ -68,9 +68,10 @@ $ ELECTRON_RUN_AS_NODE=true path/to/electron.exe node_modules/node-inspector/bin ### 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. +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/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md index 1186918799b9..110d2917ab47 100644 --- a/docs/tutorial/desktop-environment-integration.md +++ b/docs/tutorial/desktop-environment-integration.md @@ -53,8 +53,7 @@ GNOME, KDE. ### OS X Notifications are straight-forward on OS X, you should however be aware of -[Apple's Human Interface guidelines regarding -notifications](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html). +[Apple's Human Interface guidelines regarding notifications](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html). Note that notifications are limited to 256 bytes in size - and will be truncated if you exceed that limit. diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index 2a41d6356a89..ddbda3782449 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -147,8 +147,8 @@ working as expected. ### electron-prebuilt -If you've installed `electron-prebuilt` globally with `npm`, then you will only need -to run the following in your app's source directory: +If you've installed `electron-prebuilt` globally with `npm`, then you will only +need to run the following in your app's source directory: ```bash electron . From c72bb6df33488f4069cfb42f6a5994a969f4c3e5 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 22 Apr 2016 22:55:38 +0900 Subject: [PATCH 062/141] :memo: Remove unused link reference [ci skip] --- docs/tutorial/mac-app-store-submission-guide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index c80885f5a56b..404dcb80efbf 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -183,6 +183,5 @@ ERN)][ern-tutorial]. [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/electron/electron/issues/3871 [ern-tutorial]: https://carouselapps.com/2015/12/15/legally-submit-app-apples-app-store-uses-encryption-obtain-ern/ [temporary-exception]: https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/AppSandboxTemporaryExceptionEntitlements.html From cbc2a869e3a6568da9390fa6b04a101aecbd1a8f Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 22 Apr 2016 22:56:24 +0900 Subject: [PATCH 063/141] :memo: Fix typos [ci skip] --- docs/api/screen.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/screen.md b/docs/api/screen.md index 4d12f1359f7f..90ef183a8a8d 100644 --- a/docs/api/screen.md +++ b/docs/api/screen.md @@ -1,7 +1,7 @@ # screen The `screen` module retrieves information about screen size, displays, cursor -position, etc. You cannot not use this module until the `ready` event of the +position, etc. You can not use this module until the `ready` event of the `app` module is emitted (by invoking or requiring it). `screen` is an [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter). From 741f8091b45122c0257b5a47b7a13036e9d30a7c Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 22 Apr 2016 23:09:59 +0900 Subject: [PATCH 064/141] :memo: Fix coding style issues * Correct heading order * Adjust line length to `80` * Beautify docs * Apply small fixes * Normalize whitespaces [ci skip] --- .../development/debug-instructions-windows.md | 105 +++++++++++++----- 1 file changed, 80 insertions(+), 25 deletions(-) diff --git a/docs/development/debug-instructions-windows.md b/docs/development/debug-instructions-windows.md index 3070bf33443a..3a1a05e11030 100644 --- a/docs/development/debug-instructions-windows.md +++ b/docs/development/debug-instructions-windows.md @@ -1,38 +1,93 @@ # Debugging Electron in Windows -If you experience crashes or issues in Electron that you believe are not caused by your JavaScript application, but instead by Electron itself, debugging can be a little bit tricky, especially for developers not used to native/C++ debugging. However, using Visual Studio, GitHub's hosted Electron Symbol Server, and the Electron source code, it is fairly easy to enable step-through debugging with breakpoints inside Electron's source code. -### Requirements - * **A debug build of Electron**: The easiest way is usually building it yourself, using the tools and prerequisites listed in the [build instructions for Windows](build-instructions-osx.md). While you can easily attach to and debug Electron as you can download it directly, you will find that it is heavily optimized, making debugging substantially more difficult: The debugger will not be able to show you the content of all variables and the execution path can seem strange because of inlining, tail calls, and other compiler optimizations. - - * **Visual Studio with C++ Tools**: The free community editions of [Visual Studio 2013]() and [Visual Studio 2015]() both work. - - Once installed, [configure Visual Studio to use GitHub's Electron Symbol server](setting-up-symbol-server.md). It will enable Visual Studio to gain a better understanding of what happens inside Electron, making it easier to present variables in a human-readable format. - - * **ProcMon**: The [free SysInternals tool](https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx) allows you to inspect a processes parameters, file handles, and registry operations. - -# Attaching to and Debugging Electron -To start a debugging session, open up PowerShell/CMD and execute your debug build of Electron, using the application to open as a parameter. +If you experience crashes or issues in Electron that you believe are not caused +by your JavaScript application, but instead by Electron itself, debugging can +be a little bit tricky, especially for developers not used to native/C++ +debugging. However, using Visual Studio, GitHub's hosted Electron Symbol Server, +and the Electron source code, it is fairly easy to enable step-through debugging +with breakpoints inside Electron's source code. -``` -./out/D/electron.exe ~/my-electron-app/ +## Requirements + +* **A debug build of Electron**: The easiest way is usually building it + yourself, using the tools and prerequisites listed in the + [build instructions for Windows](build-instructions-osx.md). While you can + easily attach to and debug Electron as you can download it directly, you will + find that it is heavily optimized, making debugging substantially more + difficult: The debugger will not be able to show you the content of all + variables and the execution path can seem strange because of inlining, + tail calls, and other compiler optimizations. + +* **Visual Studio with C++ Tools**: The free community editions of Visual + Studio 2013 and Visual Studio 2015 both work. Once installed, + [configure Visual Studio to use GitHub's Electron Symbol server](setting-up-symbol-server.md). + It will enable Visual Studio to gain a better understanding of what happens + inside Electron, making it easier to present variables in a human-readable + format. + +* **ProcMon**: The [free SysInternals tool][sys-internals] allows you to inspect + a processes parameters, file handles, and registry operations. + +## Attaching to and Debugging Electron + +To start a debugging session, open up PowerShell/CMD and execute your debug +build of Electron, using the application to open as a parameter. + +```powershell +$ ./out/D/electron.exe ~/my-electron-app/ ``` -## Setting Breakpoints -Then, open up Visual Studio. Electron is not built with Visual Studio and hence does not contain a project file - you can however open up the source code files "As File", meaning that Visual Studio will open them up by themselves. You can still set breakpoints - Visual Studio will automatically figure out that the source code matches the code running in the attached process and break accordingly. +### Setting Breakpoints -Relevant code files can be found in `./atom/` as well as in Brightray, found in `./vendor/brightray/browser` and `./vendor/brightray/common`. If you're hardcore, you can also debug Chromium directly, which is obviously found in `chromium_src`. +Then, open up Visual Studio. Electron is not built with Visual Studio and hence +does not contain a project file - you can however open up the source code files +"As File", meaning that Visual Studio will open them up by themselves. You can +still set breakpoints - Visual Studio will automatically figure out that the +source code matches the code running in the attached process and break +accordingly. -## Attaching -You can attach the Visual Studio debugger to a running process on a local or remote computer. After the process is running, click Debug / Attach to Process (or press `CTRL+ALT+P`) to open the "Attach to Process" dialog box. You can use this capability to debug apps that are running on a local or remote computer, debug multiple processes simultaneously. +Relevant code files can be found in `./atom/` as well as in Brightray, found in +`./vendor/brightray/browser` and `./vendor/brightray/common`. If you're hardcore, +you can also debug Chromium directly, which is obviously found in `chromium_src`. -If Electron is running under a different user account, select the `Show processes from all users` check box. Notice that depending on how many BrowserWindows your app opened, you will see multiple processes. A typical one-window app will result in Visual Studio presenting you with two `Electron.exe` entries - one for the main process and one for the renderer process. Since the list only gives you names, there's currently no reliable way of figuring out which is which. +### Attaching -#### Which Process Should I Attach to? -Code executed within the main process (that is, code found in or eventually run by your main JavaScript file) as well as code called using the remote (`require('electron').remote`) will run inside the main process, while other code will execute inside its respective renderer process. +You can attach the Visual Studio debugger to a running process on a local or +remote computer. After the process is running, click Debug / Attach to Process +(or press `CTRL+ALT+P`) to open the "Attach to Process" dialog box. You can use +this capability to debug apps that are running on a local or remote computer, +debug multiple processes simultaneously. -You can be attached to multiple programs when you are debugging, but only one program is active in the debugger at any time. You can set the active program in the `Debug Location` toolbar or the `Processes window`. +If Electron is running under a different user account, select the +`Show processes from all users` check box. Notice that depending on how many +BrowserWindows your app opened, you will see multiple processes. A typical +one-window app will result in Visual Studio presenting you with two +`Electron.exe` entries - one for the main process and one for the renderer +process. Since the list only gives you names, there's currently no reliable +way of figuring out which is which. + +### Which Process Should I Attach to? + +Code executed within the main process (that is, code found in or eventually run +by your main JavaScript file) as well as code called using the remote +(`require('electron').remote`) will run inside the main process, while other +code will execute inside its respective renderer process. + +You can be attached to multiple programs when you are debugging, but only one +program is active in the debugger at any time. You can set the active program +in the `Debug Location` toolbar or the `Processes window`. ## Using ProcMon to Observe a Process -While Visual Studio is fantastic for inspecting specific code paths, ProcMon's strength is really in observing everything your application is doing with the operating system - it captures File, Registry, Network, Process, and Profiling details of processes. It attempts to log *all* events occurring and can be quite overwhelming, but if you seek to understand what and how your application is doing to the operating system, it can be a valuable resource. -For an introduction to ProcMon's basic and advanced debugging features, go check out [this video tutorial](https://channel9.msdn.com/shows/defrag-tools/defrag-tools-4-process-monitor) provided by Microsoft. \ No newline at end of file +While Visual Studio is fantastic for inspecting specific code paths, ProcMon's +strength is really in observing everything your application is doing with the +operating system - it captures File, Registry, Network, Process, and Profiling +details of processes. It attempts to log **all** events occurring and can be +quite overwhelming, but if you seek to understand what and how your application +is doing to the operating system, it can be a valuable resource. + +For an introduction to ProcMon's basic and advanced debugging features, go check +out [this video tutorial][procmon-instructions] provided by Microsoft. + +[sys-internals]: https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx +[procmon-instructions]: https://channel9.msdn.com/shows/defrag-tools/defrag-tools-4-process-monitor From 7fa4b7c8b59531f7fa336e3c282d8d912bf933eb Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 22 Apr 2016 23:15:31 +0900 Subject: [PATCH 065/141] :memo: Normalize code tags [ci skip] --- docs/api/app.md | 4 ++-- docs/api/browser-window.md | 4 ++-- docs/api/process.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index f86a205e6f96..54e40263eab9 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -453,7 +453,7 @@ use this method to ensure single instance. An example of activating the window of primary instance when a second instance starts: -```js +```javascript var myWindow = null; var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) { @@ -489,7 +489,7 @@ correctly when DWM composition is disabled). Usage example: -```js +```javascript let browserOptions = {width: 1000, height: 800}; // Make the window transparent only if the platform supports it. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 97dd2d972950..29073c7539bf 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -315,7 +315,7 @@ 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 +```javascript 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()) { @@ -682,7 +682,7 @@ Changes the attachment point for sheets on Mac OS X. By default, sheets are attached just below the window frame, but you may want to display them beneath a HTML-rendered toolbar. For example: -``` +```javascript var toolbarRect = document.getElementById('toolbar').getBoundingClientRect(); win.setSheetOffset(toolbarRect.height); ``` diff --git a/docs/api/process.md b/docs/api/process.md index ce76eb2d99aa..17c0be10926c 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -23,7 +23,7 @@ beginning to load the web page or the main script. It can be used by the preload script to add removed Node global symbols back to the global scope when node integration is turned off: -```js +```javascript // preload.js var _setImmediate = setImmediate; var _clearImmediate = clearImmediate; From b6f8dcea20dfd4d21e04046e17f58ac2face91b8 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 22 Apr 2016 23:21:42 +0900 Subject: [PATCH 066/141] :memo: Add missing platform specified tag [ci skip] --- 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 29073c7539bf..c24972815266 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -676,7 +676,7 @@ Returns the title of the native window. **Note:** The title of web page can be different from the title of the native window. -### `win.setSheetOffset(offset)` +### `win.setSheetOffset(offset)` _OS X_ Changes the attachment point for sheets on Mac OS X. By default, sheets are attached just below the window frame, but you may want to display them beneath From 66f4701d937a882fa02881eb9e03c8b6d5be6db7 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 22 Apr 2016 23:23:15 +0900 Subject: [PATCH 067/141] :memo: Remove additional whitespaces [ci skip] --- docs/api/session.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/session.md b/docs/api/session.md index b8ea23434cd3..c668ef7e45f3 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -295,9 +295,9 @@ 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', 'openExternal'. - * `callback` Function - Allow or deny the permission. + * `callback` Function - Allow or deny the permission. Sets the handler which can be used to respond to permission requests for the `session`. Calling `callback(true)` will allow the permission and `callback(false)` will reject it. From a14014941b8b40642ecef256c9da5838fb38f0f1 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 22 Apr 2016 23:26:19 +0900 Subject: [PATCH 068/141] :memo: Fix coding style issues [ci skip] --- docs/api/session.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/session.md b/docs/api/session.md index c668ef7e45f3..9490de1f6685 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -422,7 +422,7 @@ response are visible by the time this listener is fired. * `timestamp` Double * `requestHeaders` Object -#### `ses.webRequest.onHeadersReceived([filter,] listener)` +#### `ses.webRequest.onHeadersReceived([filter,]listener)` * `filter` Object * `listener` Function From 6205dfa25f9b776fe6dfdba2502ad6443c4a404f Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Fri, 22 Apr 2016 23:30:16 +0900 Subject: [PATCH 069/141] :memo: Remove additional whitespaces [ci skip] --- docs/api/session.md | 2 +- docs/development/source-code-directory-structure.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/session.md b/docs/api/session.md index 9490de1f6685..900301803632 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -467,7 +467,7 @@ and response headers are available. * `resourceType` String * `timestamp` Double * `responseHeaders` Object - * `fromCache` Boolean - Indicates whether the response was fetched from disk + * `fromCache` Boolean - Indicates whether the response was fetched from disk cache. * `statusCode` Integer * `statusLine` String diff --git a/docs/development/source-code-directory-structure.md b/docs/development/source-code-directory-structure.md index b2672def6544..27cf36b9d4e7 100644 --- a/docs/development/source-code-directory-structure.md +++ b/docs/development/source-code-directory-structure.md @@ -34,7 +34,7 @@ Electron ├── default_app - The default page to show when Electron is started without | providing an app. ├── docs - Documentations. -├── lib - JavaScript source code. +├── lib - JavaScript source code. | ├── browser - Javascript main process initialization code. | | └── api - Javascript API implementation. | ├── common - JavaScript used by both the main and renderer processes From ee190ca62aa0595b23396544667dcc63bb83667c Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Thu, 21 Apr 2016 15:35:29 -0700 Subject: [PATCH 070/141] create a one-liner description for each API --- docs/api/accelerator.md | 6 ++++-- docs/api/app.md | 2 +- docs/api/auto-updater.md | 4 +++- docs/api/browser-window.md | 3 +-- docs/api/chrome-command-line-switches.md | 9 +++++---- docs/api/clipboard.md | 3 ++- docs/api/content-tracing.md | 5 +++-- docs/api/crash-reporter.md | 2 +- docs/api/desktop-capturer.md | 4 ++-- docs/api/dialog.md | 4 +--- docs/api/download-item.md | 2 ++ docs/api/environment-variables.md | 2 ++ docs/api/file-object.md | 2 ++ docs/api/frameless-window.md | 2 ++ docs/api/global-shortcut.md | 2 ++ docs/api/ipc-main.md | 2 ++ docs/api/ipc-renderer.md | 2 ++ docs/api/menu-item.md | 3 +-- docs/api/menu.md | 5 ++--- docs/api/native-image.md | 2 ++ docs/api/power-monitor.md | 5 +++-- docs/api/power-save-blocker.md | 4 +--- docs/api/process.md | 2 ++ docs/api/protocol.md | 4 ++-- docs/api/remote.md | 2 ++ docs/api/screen.md | 7 ++++--- docs/api/session.md | 2 ++ docs/api/shell.md | 2 ++ docs/api/synopsis.md | 2 ++ docs/api/tray.md | 3 +-- docs/api/web-contents.md | 3 ++- docs/api/web-frame.md | 3 +-- docs/api/web-view-tag.md | 2 ++ docs/api/window-open.md | 2 ++ 34 files changed, 70 insertions(+), 39 deletions(-) diff --git a/docs/api/accelerator.md b/docs/api/accelerator.md index 83d8d3a7c2de..ff2b8190a942 100644 --- a/docs/api/accelerator.md +++ b/docs/api/accelerator.md @@ -1,7 +1,9 @@ # Accelerator -An accelerator is a string that represents a keyboard shortcut. It can contain -multiple modifiers and key codes, combined by the `+` character. +Define keyboard shortcuts. + +Accelerators can contain multiple modifiers and key codes, combined by +the `+` character. Examples: diff --git a/docs/api/app.md b/docs/api/app.md index 54e40263eab9..b06f8e6b6afb 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -1,6 +1,6 @@ # app -The `app` module is responsible for controlling the application's lifecycle. +Control your application's event lifecycle. The following example shows how to quit the application when the last window is closed: diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index dccae1212aa0..daea50121001 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -1,6 +1,8 @@ # autoUpdater -This module provides an interface for the `Squirrel` auto-updater framework. +Enable apps to update themselves automatically. + +The `autoUpdater` module provides and interface for the [Squirrel](https://github.com/Squirrel) framework. You can quickly launch a multi-platform release server for distributing your application by using one of these projects: diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index c24972815266..b7536249f8f6 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -1,7 +1,6 @@ # BrowserWindow -The `BrowserWindow` class gives you the ability to create a browser window. For -example: +Create and control browser windows. ```javascript // In the main process. diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index 8e8aa38e62dc..f7515a5f1fbb 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -1,9 +1,10 @@ # Supported Chrome command line switches -This page lists the command line switches used by the Chrome browser that are -also supported by Electron. You can use -[app.commandLine.appendSwitch][append-switch] to append them in your app's main -script before the [ready][ready] event of [app][app] module is emitted: +Command line switches supported by Electron. + +You can use [app.commandLine.appendSwitch][append-switch] to append them in +your app's main script before the [ready][ready] event of [app][app] module is +emitted: ```javascript const app = require('electron').app; diff --git a/docs/api/clipboard.md b/docs/api/clipboard.md index 7f95a1af26d2..2f9440f80e99 100644 --- a/docs/api/clipboard.md +++ b/docs/api/clipboard.md @@ -1,6 +1,7 @@ # clipboard -The `clipboard` module provides methods to perform copy and paste operations. +Perform copy and paste operations on the system clipboard. + The following example shows how to write a string to the clipboard: ```javascript diff --git a/docs/api/content-tracing.md b/docs/api/content-tracing.md index 0b83c2759c67..66c7679dd090 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -1,7 +1,8 @@ # contentTracing -The `content-tracing` module is used to collect tracing data generated by the -underlying Chromium content module. This module does not include a web interface +Debug your application using Chromium's content module. + +This module does not include a web interface so you need to open `chrome://tracing/` in a Chrome browser and load the generated file to view the result. diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index 9b7141e364e9..0ef2317db6bd 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -1,6 +1,6 @@ # crashReporter -The `crash-reporter` module enables sending your app's crash reports. +Submit crash reports to a remote server. The following is an example of automatically submitting a crash report to a remote server: diff --git a/docs/api/desktop-capturer.md b/docs/api/desktop-capturer.md index b39a09e5aa8b..c80928017ace 100644 --- a/docs/api/desktop-capturer.md +++ b/docs/api/desktop-capturer.md @@ -1,7 +1,7 @@ # desktopCapturer -The `desktopCapturer` module can be used to get available sources that can be -used to be captured with `getUserMedia`. +Capture audio, video, and images from a microphone, camera, or +screen using the `getUserMedia` API. ```javascript // In the renderer process. diff --git a/docs/api/dialog.md b/docs/api/dialog.md index 3eb0292a4937..e052f10dca96 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -1,8 +1,6 @@ # dialog -The `dialog` module provides APIs to show native system dialogs, such as opening -files or alerting, so web applications can deliver the same user experience as -native applications. +Display native system dialogs for opening and saving files, alerting, etc. An example of showing a dialog to select multiple files and directories: diff --git a/docs/api/download-item.md b/docs/api/download-item.md index f117ffc57a78..02e5b3950041 100644 --- a/docs/api/download-item.md +++ b/docs/api/download-item.md @@ -1,5 +1,7 @@ # DownloadItem +Trigger file downloads from remote sources. + `DownloadItem` is an EventEmitter represents a download item in Electron. It is used in `will-download` event of `Session` module, and allows users to control the download item. diff --git a/docs/api/environment-variables.md b/docs/api/environment-variables.md index 3483c19d6431..6186c06904a7 100644 --- a/docs/api/environment-variables.md +++ b/docs/api/environment-variables.md @@ -1,5 +1,7 @@ # Environment variables +Control application configuration and behavior without changing code. + Some behaviors of Electron are controlled by environment variables, because they are initialized earlier than command line and the app's code. diff --git a/docs/api/file-object.md b/docs/api/file-object.md index 01d49c39155f..f1d3680eb8a8 100644 --- a/docs/api/file-object.md +++ b/docs/api/file-object.md @@ -1,5 +1,7 @@ # `File` object +Use the HTML5 `File` API to work natively with files on the filesystem. + 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 diff --git a/docs/api/frameless-window.md b/docs/api/frameless-window.md index 8e1dd46ec56e..12497db4dae9 100644 --- a/docs/api/frameless-window.md +++ b/docs/api/frameless-window.md @@ -1,5 +1,7 @@ # Frameless Window +> Open a window without toolbars, borders, or other graphical "chrome". + A frameless window is a window that has no [chrome](https://developer.mozilla.org/en-US/docs/Glossary/Chrome), the parts of the window, like toolbars, that are not a part of the web page. These are diff --git a/docs/api/global-shortcut.md b/docs/api/global-shortcut.md index f20758406b7c..c1bce458c893 100644 --- a/docs/api/global-shortcut.md +++ b/docs/api/global-shortcut.md @@ -1,5 +1,7 @@ # globalShortcut +Detect keyboard events when the application does not have keyboard focus. + The `globalShortcut` module can register/unregister a global keyboard shortcut with the operating system so that you can customize the operations for various shortcuts. diff --git a/docs/api/ipc-main.md b/docs/api/ipc-main.md index 84fbcfd5a72f..1ddb0bb1c991 100644 --- a/docs/api/ipc-main.md +++ b/docs/api/ipc-main.md @@ -1,5 +1,7 @@ # ipcMain +Communicate asynchronously from the main process to renderer processes. + The `ipcMain` module is an instance of the [EventEmitter](https://nodejs.org/api/events.html) class. When used in the main process, it handles asynchronous and synchronous messages sent from a renderer diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index 46a2331af43b..8d18524d1cd8 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -1,5 +1,7 @@ # ipcRenderer +Communicate asynchronously from a renderer process to the main process. + The `ipcRenderer` module is an instance of the [EventEmitter](https://nodejs.org/api/events.html) class. It provides a few methods so you can send synchronous and asynchronous messages from the render diff --git a/docs/api/menu-item.md b/docs/api/menu-item.md index 1b36432ab297..5c5532289a96 100644 --- a/docs/api/menu-item.md +++ b/docs/api/menu-item.md @@ -1,7 +1,6 @@ # MenuItem -The `menu-item` module allows you to add items to an application or context -[`menu`](menu.md). +Add items to application and context menus. See [`menu`](menu.md) for examples. diff --git a/docs/api/menu.md b/docs/api/menu.md index cb5a0cbe2df8..6ac8a9ea1e00 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -1,8 +1,7 @@ # Menu -The `menu` class is used to create native menus that can be used as -application menus and -[context menus](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/PopupGuide/ContextMenus). +Create native application menus and context menus. + This module is a main process module which can be used in a render process via the `remote` module. diff --git a/docs/api/native-image.md b/docs/api/native-image.md index e0c3ae466248..ed3bbdacc9ab 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -1,5 +1,7 @@ # nativeImage +Create tray, dock, and application icons using PNG or JPG files. + In Electron, for the APIs that take images, you can pass either file paths or `nativeImage` instances. An empty image will be used when `null` is passed. diff --git a/docs/api/power-monitor.md b/docs/api/power-monitor.md index 4465b253a754..72cfbca1f13e 100644 --- a/docs/api/power-monitor.md +++ b/docs/api/power-monitor.md @@ -1,7 +1,8 @@ # powerMonitor -The `power-monitor` module is used to monitor power state changes. You can -only use it in the main process. You should not use this module until the `ready` +Monitor power state changes. + +You can only use it in the main process. You should not use this module until the `ready` event of the `app` module is emitted. For example: diff --git a/docs/api/power-save-blocker.md b/docs/api/power-save-blocker.md index a3ef798411f2..315bbdb9bec4 100644 --- a/docs/api/power-save-blocker.md +++ b/docs/api/power-save-blocker.md @@ -1,8 +1,6 @@ # powerSaveBlocker -The `powerSaveBlocker` module is used to block the system from entering -low-power (sleep) mode and thus allowing the app to keep the system and screen -active. +Block the system from entering low-power (sleep) mode. For example: diff --git a/docs/api/process.md b/docs/api/process.md index 17c0be10926c..180533709532 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -1,5 +1,7 @@ # process +Get information about the running application process. + The `process` object in Electron has the following differences from the one in upstream node: diff --git a/docs/api/protocol.md b/docs/api/protocol.md index e57a34ef89b5..ade04c1cc308 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -1,7 +1,7 @@ # protocol -The `protocol` module can register a custom protocol or intercept an existing -protocol. +Register a custom protocol to intercept click events from other running +applications. An example of implementing a protocol that has the same effect as the `file://` protocol: diff --git a/docs/api/remote.md b/docs/api/remote.md index 7bdbe0362f60..fb585a0fc3d5 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -1,5 +1,7 @@ # remote +Communicate between the renderer process and the main process. + The `remote` module provides a simple way to do inter-process communication (IPC) between the renderer process (web page) and the main process. diff --git a/docs/api/screen.md b/docs/api/screen.md index 90ef183a8a8d..5f8188f0d8a6 100644 --- a/docs/api/screen.md +++ b/docs/api/screen.md @@ -1,8 +1,9 @@ # screen -The `screen` module retrieves information about screen size, displays, cursor -position, etc. You can not use this module until the `ready` event of the -`app` module is emitted (by invoking or requiring it). +> Retrieve information about screen size, displays, cursor position, etc. + +You cannot not use this module until the `ready` event of the `app` module is +emitted (by invoking or requiring it). `screen` is an [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter). diff --git a/docs/api/session.md b/docs/api/session.md index 900301803632..e7689c8e4b78 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -1,5 +1,7 @@ # session +Manage browser cookies, cache, and other session data. + The `session` module can be used to create new `Session` objects. You can also access the `session` of existing pages by using the `session` diff --git a/docs/api/shell.md b/docs/api/shell.md index 823dc481bb07..b340acaebf6c 100644 --- a/docs/api/shell.md +++ b/docs/api/shell.md @@ -1,5 +1,7 @@ # shell +Manage files and URLs using their default applications. + The `shell` module provides functions related to desktop integration. An example of opening a URL in the user's default browser: diff --git a/docs/api/synopsis.md b/docs/api/synopsis.md index 466b13828c41..d79942531e3c 100644 --- a/docs/api/synopsis.md +++ b/docs/api/synopsis.md @@ -1,5 +1,7 @@ # Synopsis +Info about Node.js and the main and renderer processes. + All of [Node.js's built-in modules](http://nodejs.org/api/) are available in Electron and third-party node modules also fully supported as well (including the [native modules](../tutorial/using-native-node-modules.md)). diff --git a/docs/api/tray.md b/docs/api/tray.md index aa972c57cd92..d6bf2b3c73e5 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -1,7 +1,6 @@ # Tray -A `Tray` represents an icon in an operating system's notification area, it is -usually attached with a context menu. +Add icons and context menus to the system's notification area. ```javascript const electron = require('electron'); diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 0eee6c5bf8bb..e49e220dbbd0 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1,8 +1,9 @@ # webContents +Render and control web pages using lifecycle events. + `webContents` is an [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter). - It is responsible for rendering and controlling a web page and is a property of the [`BrowserWindow`](browser-window.md) object. An example of accessing the `webContents` object: diff --git a/docs/api/web-frame.md b/docs/api/web-frame.md index d9e02ac097e7..109bfa103d59 100644 --- a/docs/api/web-frame.md +++ b/docs/api/web-frame.md @@ -1,7 +1,6 @@ # webFrame -The `web-frame` module allows you to customize the rendering of the current -web page. +Customize the rendering of the current web page. An example of zooming current page to 200%. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 214f93dbad6f..36b0513e556e 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -1,5 +1,7 @@ # The `` tag +Display external web content in an isolated frame and process. + Use the `webview` tag to embed 'guest' content (such as web pages) in your Electron app. The guest content is contained within the `webview` container. An embedded page within your app controls how the guest content is laid out and diff --git a/docs/api/window-open.md b/docs/api/window-open.md index 46e74327741f..14a0dce65f25 100644 --- a/docs/api/window-open.md +++ b/docs/api/window-open.md @@ -1,5 +1,7 @@ # The `window.open` function +Create a new window in a web page. + When `window.open` is called to create a new window in a web page, a new instance of `BrowserWindow` will be created for the `url` and a proxy will be returned to `window.open` to let the page have limited control over it. From 0527b17e4203f6593cdf64daa146b9a326039446 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Thu, 21 Apr 2016 15:39:12 -0700 Subject: [PATCH 071/141] blockquote summaries --- docs/api/accelerator.md | 2 +- docs/api/app.md | 2 +- docs/api/auto-updater.md | 2 +- docs/api/browser-window.md | 2 +- docs/api/chrome-command-line-switches.md | 2 +- docs/api/clipboard.md | 2 +- docs/api/content-tracing.md | 2 +- docs/api/crash-reporter.md | 2 +- docs/api/desktop-capturer.md | 2 +- docs/api/dialog.md | 2 +- docs/api/download-item.md | 2 +- docs/api/environment-variables.md | 2 +- docs/api/file-object.md | 2 +- docs/api/global-shortcut.md | 2 +- docs/api/ipc-main.md | 2 +- docs/api/ipc-renderer.md | 2 +- docs/api/menu-item.md | 2 +- docs/api/menu.md | 2 +- docs/api/native-image.md | 2 +- docs/api/power-monitor.md | 2 +- docs/api/power-save-blocker.md | 2 +- docs/api/process.md | 2 +- docs/api/protocol.md | 2 +- docs/api/remote.md | 2 +- docs/api/session.md | 2 +- docs/api/shell.md | 2 +- docs/api/synopsis.md | 2 +- docs/api/tray.md | 2 +- docs/api/web-contents.md | 2 +- docs/api/web-frame.md | 2 +- docs/api/web-view-tag.md | 2 +- docs/api/window-open.md | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/api/accelerator.md b/docs/api/accelerator.md index ff2b8190a942..cf28e01037a2 100644 --- a/docs/api/accelerator.md +++ b/docs/api/accelerator.md @@ -1,6 +1,6 @@ # Accelerator -Define keyboard shortcuts. +> Define keyboard shortcuts. Accelerators can contain multiple modifiers and key codes, combined by the `+` character. diff --git a/docs/api/app.md b/docs/api/app.md index b06f8e6b6afb..8a2cdcfd9224 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -1,6 +1,6 @@ # app -Control your application's event lifecycle. +> Control your application's event lifecycle. The following example shows how to quit the application when the last window is closed: diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index daea50121001..8ad3f8f16edd 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -1,6 +1,6 @@ # autoUpdater -Enable apps to update themselves automatically. +> Enable apps to update themselves automatically. The `autoUpdater` module provides and interface for the [Squirrel](https://github.com/Squirrel) framework. diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index b7536249f8f6..7289057b40eb 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -1,6 +1,6 @@ # BrowserWindow -Create and control browser windows. +> Create and control browser windows. ```javascript // In the main process. diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index f7515a5f1fbb..71a5ce6a40e7 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -1,6 +1,6 @@ # Supported Chrome command line switches -Command line switches supported by Electron. +> Command line switches supported by Electron. You can use [app.commandLine.appendSwitch][append-switch] to append them in your app's main script before the [ready][ready] event of [app][app] module is diff --git a/docs/api/clipboard.md b/docs/api/clipboard.md index 2f9440f80e99..58e5a1c1b096 100644 --- a/docs/api/clipboard.md +++ b/docs/api/clipboard.md @@ -1,6 +1,6 @@ # clipboard -Perform copy and paste operations on the system clipboard. +> Perform copy and paste operations on the system clipboard. The following example shows how to write a string to the clipboard: diff --git a/docs/api/content-tracing.md b/docs/api/content-tracing.md index 66c7679dd090..c69031850a33 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -1,6 +1,6 @@ # contentTracing -Debug your application using Chromium's content module. +> Debug your application using Chromium's content module. This module does not include a web interface so you need to open `chrome://tracing/` in a Chrome browser and load the diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index 0ef2317db6bd..1f8229eaa792 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -1,6 +1,6 @@ # crashReporter -Submit crash reports to a remote server. +> Submit crash reports to a remote server. The following is an example of automatically submitting a crash report to a remote server: diff --git a/docs/api/desktop-capturer.md b/docs/api/desktop-capturer.md index c80928017ace..505dd9596a9d 100644 --- a/docs/api/desktop-capturer.md +++ b/docs/api/desktop-capturer.md @@ -1,6 +1,6 @@ # desktopCapturer -Capture audio, video, and images from a microphone, camera, or +> Capture audio, video, and images from a microphone, camera, or screen using the `getUserMedia` API. ```javascript diff --git a/docs/api/dialog.md b/docs/api/dialog.md index e052f10dca96..a5f61a53e3f8 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -1,6 +1,6 @@ # dialog -Display native system dialogs for opening and saving files, alerting, etc. +> Display native system dialogs for opening and saving files, alerting, etc. An example of showing a dialog to select multiple files and directories: diff --git a/docs/api/download-item.md b/docs/api/download-item.md index 02e5b3950041..0f38ceedac90 100644 --- a/docs/api/download-item.md +++ b/docs/api/download-item.md @@ -1,6 +1,6 @@ # DownloadItem -Trigger file downloads from remote sources. +> Trigger file downloads from remote sources. `DownloadItem` is an EventEmitter represents a download item in Electron. It is used in `will-download` event of `Session` module, and allows users to diff --git a/docs/api/environment-variables.md b/docs/api/environment-variables.md index 6186c06904a7..7339661b09fe 100644 --- a/docs/api/environment-variables.md +++ b/docs/api/environment-variables.md @@ -1,6 +1,6 @@ # Environment variables -Control application configuration and behavior without changing code. +> Control application configuration and behavior without changing code. Some behaviors of Electron are controlled by environment variables, because they are initialized earlier than command line and the app's code. diff --git a/docs/api/file-object.md b/docs/api/file-object.md index f1d3680eb8a8..31c6feddb50b 100644 --- a/docs/api/file-object.md +++ b/docs/api/file-object.md @@ -1,6 +1,6 @@ # `File` object -Use the HTML5 `File` API to work natively with files on the filesystem. +> Use the HTML5 `File` API to work natively with files on the filesystem. 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 diff --git a/docs/api/global-shortcut.md b/docs/api/global-shortcut.md index c1bce458c893..08453d68a46c 100644 --- a/docs/api/global-shortcut.md +++ b/docs/api/global-shortcut.md @@ -1,6 +1,6 @@ # globalShortcut -Detect keyboard events when the application does not have keyboard focus. +> Detect keyboard events when the application does not have keyboard focus. The `globalShortcut` module can register/unregister a global keyboard shortcut with the operating system so that you can customize the operations for various diff --git a/docs/api/ipc-main.md b/docs/api/ipc-main.md index 1ddb0bb1c991..c8ba60ba3170 100644 --- a/docs/api/ipc-main.md +++ b/docs/api/ipc-main.md @@ -1,6 +1,6 @@ # ipcMain -Communicate asynchronously from the main process to renderer processes. +> Communicate asynchronously from the main process to renderer processes. The `ipcMain` module is an instance of the [EventEmitter](https://nodejs.org/api/events.html) class. When used in the main diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index 8d18524d1cd8..9835e42b4679 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -1,6 +1,6 @@ # ipcRenderer -Communicate asynchronously from a renderer process to the main process. +> Communicate asynchronously from a renderer process to the main process. The `ipcRenderer` module is an instance of the [EventEmitter](https://nodejs.org/api/events.html) class. It provides a few diff --git a/docs/api/menu-item.md b/docs/api/menu-item.md index 5c5532289a96..0b5db9431130 100644 --- a/docs/api/menu-item.md +++ b/docs/api/menu-item.md @@ -1,6 +1,6 @@ # MenuItem -Add items to application and context menus. +> Add items to application and context menus. See [`menu`](menu.md) for examples. diff --git a/docs/api/menu.md b/docs/api/menu.md index 6ac8a9ea1e00..4106dfdd4089 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -1,6 +1,6 @@ # Menu -Create native application menus and context menus. +> Create native application menus and context menus. This module is a main process module which can be used in a render process via the `remote` module. diff --git a/docs/api/native-image.md b/docs/api/native-image.md index ed3bbdacc9ab..1cbfcf410181 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -1,6 +1,6 @@ # nativeImage -Create tray, dock, and application icons using PNG or JPG files. +> Create tray, dock, and application icons using PNG or JPG files. In Electron, for the APIs that take images, you can pass either file paths or `nativeImage` instances. An empty image will be used when `null` is passed. diff --git a/docs/api/power-monitor.md b/docs/api/power-monitor.md index 72cfbca1f13e..75546dc80159 100644 --- a/docs/api/power-monitor.md +++ b/docs/api/power-monitor.md @@ -1,6 +1,6 @@ # powerMonitor -Monitor power state changes. +> Monitor power state changes. You can only use it in the main process. You should not use this module until the `ready` event of the `app` module is emitted. diff --git a/docs/api/power-save-blocker.md b/docs/api/power-save-blocker.md index 315bbdb9bec4..3ec07338646b 100644 --- a/docs/api/power-save-blocker.md +++ b/docs/api/power-save-blocker.md @@ -1,6 +1,6 @@ # powerSaveBlocker -Block the system from entering low-power (sleep) mode. +> Block the system from entering low-power (sleep) mode. For example: diff --git a/docs/api/process.md b/docs/api/process.md index 180533709532..80f0e539d80f 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -1,6 +1,6 @@ # process -Get information about the running application process. +> Get information about the running application process. The `process` object in Electron has the following differences from the one in upstream node: diff --git a/docs/api/protocol.md b/docs/api/protocol.md index ade04c1cc308..b3062bb6325c 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -1,6 +1,6 @@ # protocol -Register a custom protocol to intercept click events from other running +> Register a custom protocol to intercept click events from other running applications. An example of implementing a protocol that has the same effect as the diff --git a/docs/api/remote.md b/docs/api/remote.md index fb585a0fc3d5..65f58f01b0c2 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -1,6 +1,6 @@ # remote -Communicate between the renderer process and the main process. +> Communicate between the renderer process and the main process. The `remote` module provides a simple way to do inter-process communication (IPC) between the renderer process (web page) and the main process. diff --git a/docs/api/session.md b/docs/api/session.md index e7689c8e4b78..390a9a5e4d88 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -1,6 +1,6 @@ # session -Manage browser cookies, cache, and other session data. +> Manage browser cookies, cache, and other session data. The `session` module can be used to create new `Session` objects. diff --git a/docs/api/shell.md b/docs/api/shell.md index b340acaebf6c..8ede115f7c63 100644 --- a/docs/api/shell.md +++ b/docs/api/shell.md @@ -1,6 +1,6 @@ # shell -Manage files and URLs using their default applications. +> Manage files and URLs using their default applications. The `shell` module provides functions related to desktop integration. diff --git a/docs/api/synopsis.md b/docs/api/synopsis.md index d79942531e3c..641df7e2609d 100644 --- a/docs/api/synopsis.md +++ b/docs/api/synopsis.md @@ -1,6 +1,6 @@ # Synopsis -Info about Node.js and the main and renderer processes. +> Info about Node.js and the main and renderer processes. All of [Node.js's built-in modules](http://nodejs.org/api/) are available in Electron and third-party node modules also fully supported as well (including diff --git a/docs/api/tray.md b/docs/api/tray.md index d6bf2b3c73e5..1ea0859f14a4 100644 --- a/docs/api/tray.md +++ b/docs/api/tray.md @@ -1,6 +1,6 @@ # Tray -Add icons and context menus to the system's notification area. +> Add icons and context menus to the system's notification area. ```javascript const electron = require('electron'); diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index e49e220dbbd0..5c0f457538e3 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1,6 +1,6 @@ # webContents -Render and control web pages using lifecycle events. +> Render and control web pages using lifecycle events. `webContents` is an [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter). diff --git a/docs/api/web-frame.md b/docs/api/web-frame.md index 109bfa103d59..b2d8aa0f41eb 100644 --- a/docs/api/web-frame.md +++ b/docs/api/web-frame.md @@ -1,6 +1,6 @@ # webFrame -Customize the rendering of the current web page. +> Customize the rendering of the current web page. An example of zooming current page to 200%. diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 36b0513e556e..5f4a422a13a9 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -1,6 +1,6 @@ # The `` tag -Display external web content in an isolated frame and process. +> Display external web content in an isolated frame and process. Use the `webview` tag to embed 'guest' content (such as web pages) in your Electron app. The guest content is contained within the `webview` container. diff --git a/docs/api/window-open.md b/docs/api/window-open.md index 14a0dce65f25..b4f5057dae0c 100644 --- a/docs/api/window-open.md +++ b/docs/api/window-open.md @@ -1,6 +1,6 @@ # The `window.open` function -Create a new window in a web page. +> Create a new window in a web page. When `window.open` is called to create a new window in a web page, a new instance of `BrowserWindow` will be created for the `url` and a proxy will be returned From 2c8261b4292413b926f2d31da6cad39c4baf486d Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 22 Apr 2016 10:30:49 -0700 Subject: [PATCH 072/141] update excerpts based on feedback --- docs/api/content-tracing.md | 3 ++- docs/api/desktop-capturer.md | 4 ++-- docs/api/download-item.md | 6 +++--- docs/api/protocol.md | 3 +-- docs/api/remote.md | 2 +- docs/api/session.md | 2 +- docs/api/synopsis.md | 2 +- docs/api/web-contents.md | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/api/content-tracing.md b/docs/api/content-tracing.md index c69031850a33..85036c0d7077 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -1,6 +1,7 @@ # contentTracing -> Debug your application using Chromium's content module. +> Collect tracing data from Chromium's content module for finding performance +bottlenecks and slow operations. This module does not include a web interface so you need to open `chrome://tracing/` in a Chrome browser and load the diff --git a/docs/api/desktop-capturer.md b/docs/api/desktop-capturer.md index 505dd9596a9d..dc523c3a42f9 100644 --- a/docs/api/desktop-capturer.md +++ b/docs/api/desktop-capturer.md @@ -1,7 +1,7 @@ # desktopCapturer -> Capture audio, video, and images from a microphone, camera, or -screen using the `getUserMedia` API. +> List `getUserMedia` sources for capturing audio, video, and images from a +microphone, camera, or screen. ```javascript // In the renderer process. diff --git a/docs/api/download-item.md b/docs/api/download-item.md index 0f38ceedac90..4418f61c19fb 100644 --- a/docs/api/download-item.md +++ b/docs/api/download-item.md @@ -1,9 +1,9 @@ # DownloadItem -> Trigger file downloads from remote sources. +> Control file downloads from remote sources. -`DownloadItem` is an EventEmitter represents a download item in Electron. It -is used in `will-download` event of `Session` module, and allows users to +`DownloadItem` is an EventEmitter that represents a download item in Electron. +It is used in `will-download` event of `Session` module, and allows users to control the download item. ```javascript diff --git a/docs/api/protocol.md b/docs/api/protocol.md index b3062bb6325c..fe7dfabc64cf 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -1,7 +1,6 @@ # protocol -> Register a custom protocol to intercept click events from other running -applications. +> Register a custom protocol and intercept existing protocols. An example of implementing a protocol that has the same effect as the `file://` protocol: diff --git a/docs/api/remote.md b/docs/api/remote.md index 65f58f01b0c2..454758c9139f 100644 --- a/docs/api/remote.md +++ b/docs/api/remote.md @@ -1,6 +1,6 @@ # remote -> Communicate between the renderer process and the main process. +> Use main process modules from the renderer process. The `remote` module provides a simple way to do inter-process communication (IPC) between the renderer process (web page) and the main process. diff --git a/docs/api/session.md b/docs/api/session.md index 390a9a5e4d88..5bc819fb2bde 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -1,6 +1,6 @@ # session -> Manage browser cookies, cache, and other session data. +> Manage browser sessions, cookies, cache, proxy settings, etc. The `session` module can be used to create new `Session` objects. diff --git a/docs/api/synopsis.md b/docs/api/synopsis.md index 641df7e2609d..a2aa58f57f17 100644 --- a/docs/api/synopsis.md +++ b/docs/api/synopsis.md @@ -1,6 +1,6 @@ # Synopsis -> Info about Node.js and the main and renderer processes. +> How to use Node.js and Electron APIs. All of [Node.js's built-in modules](http://nodejs.org/api/) are available in Electron and third-party node modules also fully supported as well (including diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 5c0f457538e3..64e7cea60e79 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1,6 +1,6 @@ # webContents -> Render and control web pages using lifecycle events. +> Render and control web pages. `webContents` is an [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter). From 799fd13c503c52deb095dfd234c88825a5ecab55 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 22 Apr 2016 11:42:54 -0700 Subject: [PATCH 073/141] more updates to api summaries based on feedback --- docs/api/auto-updater.md | 4 ++-- docs/api/chrome-command-line-switches.md | 4 ++-- docs/api/content-tracing.md | 6 +++--- docs/api/menu-item.md | 2 +- docs/api/protocol.md | 2 +- docs/api/window-open.md | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/api/auto-updater.md b/docs/api/auto-updater.md index 8ad3f8f16edd..211d0c69a5f3 100644 --- a/docs/api/auto-updater.md +++ b/docs/api/auto-updater.md @@ -1,8 +1,8 @@ # autoUpdater -> Enable apps to update themselves automatically. +> Enable apps to automatically update themselves. -The `autoUpdater` module provides and interface for the [Squirrel](https://github.com/Squirrel) framework. +The `autoUpdater` module provides an interface for the [Squirrel](https://github.com/Squirrel) framework. You can quickly launch a multi-platform release server for distributing your application by using one of these projects: diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index 71a5ce6a40e7..17059435eaa7 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -3,8 +3,8 @@ > Command line switches supported by Electron. You can use [app.commandLine.appendSwitch][append-switch] to append them in -your app's main script before the [ready][ready] event of [app][app] module is -emitted: +your app's main script before the [ready][ready] event of the [app][app] module +is emitted: ```javascript const app = require('electron').app; diff --git a/docs/api/content-tracing.md b/docs/api/content-tracing.md index 85036c0d7077..a9414d348764 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -3,9 +3,9 @@ > Collect tracing data from Chromium's content module for finding performance bottlenecks and slow operations. -This module does not include a web interface -so you need to open `chrome://tracing/` in a Chrome browser and load the -generated file to view the result. +This module does not include a web interface so you need to open +`chrome://tracing/` in a Chrome browser and load the generated file to view the +result. ```javascript const contentTracing = require('electron').contentTracing; diff --git a/docs/api/menu-item.md b/docs/api/menu-item.md index 0b5db9431130..b67032271e61 100644 --- a/docs/api/menu-item.md +++ b/docs/api/menu-item.md @@ -1,6 +1,6 @@ # MenuItem -> Add items to application and context menus. +> Add items to native application menus and context menus. See [`menu`](menu.md) for examples. diff --git a/docs/api/protocol.md b/docs/api/protocol.md index fe7dfabc64cf..aa9b43486d02 100644 --- a/docs/api/protocol.md +++ b/docs/api/protocol.md @@ -1,6 +1,6 @@ # protocol -> Register a custom protocol and intercept existing protocols. +> Register a custom protocol and intercept existing protocol requests. An example of implementing a protocol that has the same effect as the `file://` protocol: diff --git a/docs/api/window-open.md b/docs/api/window-open.md index b4f5057dae0c..abb0760f121e 100644 --- a/docs/api/window-open.md +++ b/docs/api/window-open.md @@ -1,6 +1,6 @@ # The `window.open` function -> Create a new window in a web page. +> Open a new window and load a URL. When `window.open` is called to create a new window in a web page, a new instance of `BrowserWindow` will be created for the `url` and a proxy will be returned From 28381757d5e6ad7408c2e1fe989131d075ef6308 Mon Sep 17 00:00:00 2001 From: Alejandro Betancourt Date: Fri, 22 Apr 2016 14:34:46 -0500 Subject: [PATCH 074/141] Fix translations to spanish --- docs-translations/es/api/synopsis.md | 2 +- docs-translations/es/tutorial/application-packaging.md | 4 ++-- docs-translations/es/tutorial/devtools-extension.md | 6 +++--- docs-translations/es/tutorial/quick-start.md | 4 +--- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/docs-translations/es/api/synopsis.md b/docs-translations/es/api/synopsis.md index 534fafcf2f7c..54c264a1aa74 100644 --- a/docs-translations/es/api/synopsis.md +++ b/docs-translations/es/api/synopsis.md @@ -1,4 +1,4 @@ -# Synopsis +# Sinopsis Todos los [Módulos integrados de Node.js](http://nodejs.org/api/) se encuentran disponibles en Electron y módulos de terceros son támbien totalmente compatibles diff --git a/docs-translations/es/tutorial/application-packaging.md b/docs-translations/es/tutorial/application-packaging.md index f8768c49dd02..0e46a44d2b48 100644 --- a/docs-translations/es/tutorial/application-packaging.md +++ b/docs-translations/es/tutorial/application-packaging.md @@ -105,7 +105,7 @@ originalFs.readFileSync('/path/to/example.asar'); A pesar de que hemos intentado que los paquetes `asar` funcionen como directorios de la mejor forma posible, aún existen limitaciones debido a la naturaleza de bajo nivel de la API Node. -### Los paquetes son de sólo lecutra +### Los paquetes son de sólo lectura Los paquetes `asar` no pueden ser modificados, por lo cual todas las funciones que modifiquen archivos no funcionarán. @@ -132,7 +132,7 @@ Las APIs que requieren el desempaquetamiento adicional son: ### Información falsa en `fs.stat` El objeto `Stats` retornado por `fs.stat` y otras funciones relacionadas, -no es preciso, ya que los archivos del paquete `asar` no existen el sistema de archivos. +no es preciso, ya que los archivos del paquete `asar` no existen en el sistema de archivos. La utilización del objeto `Stats` sólo es recomendable para obtener el tamaño del archivo y/o comprobar el tipo de archivo. diff --git a/docs-translations/es/tutorial/devtools-extension.md b/docs-translations/es/tutorial/devtools-extension.md index f54c3e0eaa83..495f56058d5f 100644 --- a/docs-translations/es/tutorial/devtools-extension.md +++ b/docs-translations/es/tutorial/devtools-extension.md @@ -1,13 +1,13 @@ # Extensión DevTools -Para facilitar la depuración, Electron provee un soporte básico para la extensión -[Chrome DevTools Extension][devtools-extension]. +Para facilitar la depuración, Electron provee un soporte básico para la extensión +[Chrome DevTools][devtools-extension]. Para la mayoría de las extensiones devtools, simplemente puedes descargar el código fuente y utilizar `BrowserWindow.addDevToolsExtension` para cargarlas, las extensiones cargadas serán recordadas para que no sea necesario llamar a la función cada vez que creas una ventana. -Por ejemplo, para usar la extensión [React DevTools Extension](https://github.com/facebook/react-devtools), primero debes descargar el código fuente: +Por ejemplo, para usar la extensión [React DevTools](https://github.com/facebook/react-devtools), primero debes descargar el código fuente: ```bash $ cd /some-directory diff --git a/docs-translations/es/tutorial/quick-start.md b/docs-translations/es/tutorial/quick-start.md index 2e6825669faf..a760fccad2c8 100644 --- a/docs-translations/es/tutorial/quick-start.md +++ b/docs-translations/es/tutorial/quick-start.md @@ -1,8 +1,6 @@ -# Intro - ## Introducción -Electron permite la creación de aplicaciones de escritorio utilizando JavaScript puro, a través de un runtime con APIs nativas. Puedes verlo como una variante de io.js, enfocado en aplicaciones de escritorio, en vez de servidores web. +Electron permite la creación de aplicaciones de escritorio utilizando JavaScript puro, a través de un runtime con APIs nativas. Puedes verlo como una variante de io.js, enfocado a aplicaciones de escritorio, en vez de servidores web. Esto no significa que Electron sea un binding de librerías GUI para JavaScript. Electron utiliza páginas web como su GUI, por lo cual puedes verlo como un navegador Chromium mínimo, From dfd1a469562f63096b3ef75d4c0eaaf2778ea5ac Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Fri, 22 Apr 2016 23:58:41 +0200 Subject: [PATCH 075/141] Document process.crash method --- docs/api/process.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api/process.md b/docs/api/process.md index b2d9c765a03a..4aaa84f89d81 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -44,6 +44,10 @@ built-in modules. The `process` object has the following method: +### `process.crash()` + +Causes the main thread of the current process crash. + ### `process.hang()` Causes the main thread of the current process hang. From 778d18a51058fa2f47aa2a1449ddf452c3661e6f Mon Sep 17 00:00:00 2001 From: Alejandro Betancourt Date: Fri, 22 Apr 2016 17:13:51 -0500 Subject: [PATCH 076/141] Fix links in readme for spanish translation --- docs-translations/es/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs-translations/es/README.md b/docs-translations/es/README.md index e69e76b1c4c7..c2358bbb0161 100644 --- a/docs-translations/es/README.md +++ b/docs-translations/es/README.md @@ -35,7 +35,7 @@ * [content-tracing](../../docs/api/content-tracing.md) * [dialog](../../docs/api/dialog.md) * [global-shortcut](../../docs/api/global-shortcut.md) -* [ipc (proceso principal)](../../docs/api/ipc-main-process.md) +* [ipc (proceso principal)](../../docs/api/ipc-main.md) * [menu](../../docs/api/menu.md) * [menu-item](../../docs/api/menu-item.md) * [power-monitor](../../docs/api/power-monitor.md) @@ -66,6 +66,6 @@ * [Diferencias Técnicas con NW.js (anteriormente conocido como node-webkit)](development/atom-shell-vs-node-webkit.md) * [Repaso del Sistema de Compilación](development/build-system-overview.md) * [Instrucciones de Compilación (Mac)](development/build-instructions-osx.md) -* [Instrucciones de Compilación (Windows)](../../development/build-instructions-windows.md) +* [Instrucciones de Compilación (Windows)](development/build-instructions-windows.md) * [Instrucciones de Compilación (Linux)](development/build-instructions-linux.md) -* [Configurando un Servidor de Símbolos en el depurador](../../development/setting-up-symbol-server.md) +* [Configurando un Servidor de Símbolos en el depurador](development/setting-up-symbol-server.md) From e1516d4244e367223bc3f9c9e4e806a6e105e82e Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Sat, 23 Apr 2016 01:15:00 +0200 Subject: [PATCH 077/141] Fix BrowserWindow.maximize/unmaximize on Mac --- atom/browser/native_window_mac.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 5f980fed62cf..04569d8f50f9 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -602,10 +602,16 @@ bool NativeWindowMac::IsVisible() { } void NativeWindowMac::Maximize() { + if (IsMaximized()) + return; + [window_ zoom:nil]; } void NativeWindowMac::Unmaximize() { + if (!IsMaximized()) + return; + [window_ zoom:nil]; } From 2ae52d0ff4fc1c64dcc3be2ccaf0143de75fc8b5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 10:17:54 +0900 Subject: [PATCH 078/141] Make Wrappable a template class --- atom/browser/api/atom_api_app.cc | 20 ++++--- atom/browser/api/atom_api_app.h | 13 ++-- atom/browser/api/atom_api_auto_updater.cc | 22 +++---- atom/browser/api/atom_api_auto_updater.h | 13 ++-- atom/browser/api/atom_api_cookies.cc | 8 ++- atom/browser/api/atom_api_cookies.h | 4 +- atom/browser/api/atom_api_debugger.cc | 6 +- atom/browser/api/atom_api_debugger.h | 4 +- atom/browser/api/atom_api_desktop_capturer.cc | 16 ++--- atom/browser/api/atom_api_desktop_capturer.h | 13 ++-- atom/browser/api/atom_api_download_item.cc | 6 +- atom/browser/api/atom_api_download_item.h | 3 +- atom/browser/api/atom_api_global_shortcut.cc | 20 ++++--- atom/browser/api/atom_api_global_shortcut.h | 11 ++-- atom/browser/api/atom_api_menu.cc | 2 +- atom/browser/api/atom_api_menu.h | 4 +- atom/browser/api/atom_api_menu_mac.h | 2 +- atom/browser/api/atom_api_menu_mac.mm | 6 +- atom/browser/api/atom_api_menu_views.cc | 4 +- atom/browser/api/atom_api_menu_views.h | 2 +- atom/browser/api/atom_api_power_monitor.cc | 10 +++- atom/browser/api/atom_api_power_monitor.h | 5 +- .../api/atom_api_power_save_blocker.cc | 22 +++---- .../browser/api/atom_api_power_save_blocker.h | 11 ++-- atom/browser/api/atom_api_protocol.cc | 60 ++++++++++--------- atom/browser/api/atom_api_protocol.h | 11 ++-- atom/browser/api/atom_api_screen.cc | 27 +++++---- atom/browser/api/atom_api_screen.h | 13 ++-- atom/browser/api/atom_api_session.cc | 13 ++-- atom/browser/api/atom_api_session.h | 2 +- atom/browser/api/atom_api_tray.cc | 6 +- atom/browser/api/atom_api_tray.h | 5 +- atom/browser/api/atom_api_web_contents.cc | 14 +++-- atom/browser/api/atom_api_web_contents.h | 9 ++- atom/browser/api/atom_api_web_request.cc | 6 +- atom/browser/api/atom_api_web_request.h | 5 +- atom/browser/api/atom_api_window.cc | 2 +- atom/browser/api/atom_api_window.h | 4 +- atom/browser/api/event.cc | 32 ++++------ atom/browser/api/event.h | 12 ++-- atom/browser/api/event_emitter.cc | 22 ++++--- atom/browser/api/event_emitter.h | 38 ++++++++---- atom/browser/api/trackable_object.cc | 9 --- atom/browser/api/trackable_object.h | 41 ++++--------- atom/common/api/atom_api_asar.cc | 48 +++++++-------- atom/common/api/atom_api_id_weak_map.cc | 6 +- atom/common/api/atom_api_id_weak_map.h | 6 +- atom/common/api/atom_api_native_image.cc | 47 +++++++-------- atom/common/api/atom_api_native_image.h | 14 ++--- atom/renderer/api/atom_api_web_frame.cc | 22 +++---- atom/renderer/api/atom_api_web_frame.h | 13 ++-- vendor/native_mate | 2 +- 52 files changed, 367 insertions(+), 349 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index d239a63d0581..a7842c42ce05 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -194,10 +194,11 @@ int ImportIntoCertStore( } // namespace -App::App() { +App::App(v8::Isolate* isolate) { static_cast(AtomBrowserClient::Get())->set_delegate(this); Browser::Get()->AddObserver(this); content::GpuDataManager::GetInstance()->AddObserver(this); + Init(isolate); } App::~App() { @@ -439,10 +440,16 @@ void App::OnCertificateManagerModelCreated( } #endif -mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( - v8::Isolate* isolate) { +// static +mate::Handle App::Create(v8::Isolate* isolate) { + return CreateHandle(isolate, new App(isolate)); +} + +// static +void App::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { auto browser = base::Unretained(Browser::Get()); - return mate::ObjectTemplateBuilder(isolate) + mate::ObjectTemplateBuilder(isolate, prototype) .SetMethod("quit", base::Bind(&Browser::Quit, browser)) .SetMethod("exit", base::Bind(&Browser::Exit, browser)) .SetMethod("focus", base::Bind(&Browser::Focus, browser)) @@ -484,11 +491,6 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( .SetMethod("makeSingleInstance", &App::MakeSingleInstance); } -// static -mate::Handle App::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new App); -} - } // namespace api } // namespace atom diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index d4102521c0b4..354ea38d884b 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -33,12 +33,15 @@ namespace atom { namespace api { class App : public AtomBrowserClient::Delegate, - public mate::EventEmitter, + public mate::EventEmitter, public BrowserObserver, public content::GpuDataManagerObserver { public: static mate::Handle Create(v8::Isolate* isolate); + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + // Called when window with disposition needs to be created. void OnCreateWindow(const GURL& target_url, const std::string& frame_name, @@ -54,8 +57,8 @@ class App : public AtomBrowserClient::Delegate, #endif protected: - App(); - virtual ~App(); + explicit App(v8::Isolate* isolate); + ~App() override; // BrowserObserver: void OnBeforeQuit(bool* prevent_default) override; @@ -93,10 +96,6 @@ class App : public AtomBrowserClient::Delegate, void OnPlatformThemeChanged() override; #endif - // mate::Wrappable: - mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; - private: // Get/Set the pre-defined path in PathService. base::FilePath GetPath(mate::Arguments* args, const std::string& name); diff --git a/atom/browser/api/atom_api_auto_updater.cc b/atom/browser/api/atom_api_auto_updater.cc index 1a02a54d4533..102bffb71182 100644 --- a/atom/browser/api/atom_api_auto_updater.cc +++ b/atom/browser/api/atom_api_auto_updater.cc @@ -34,8 +34,9 @@ namespace atom { namespace api { -AutoUpdater::AutoUpdater() { +AutoUpdater::AutoUpdater(v8::Isolate* isolate) { auto_updater::AutoUpdater::SetDelegate(this); + Init(isolate); } AutoUpdater::~AutoUpdater() { @@ -78,14 +79,6 @@ void AutoUpdater::OnWindowAllClosed() { QuitAndInstall(); } -mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return mate::ObjectTemplateBuilder(isolate) - .SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL) - .SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates) - .SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall); -} - void AutoUpdater::QuitAndInstall() { // If we don't have any window then quitAndInstall immediately. WindowList* window_list = WindowList::GetInstance(); @@ -102,7 +95,16 @@ void AutoUpdater::QuitAndInstall() { // static mate::Handle AutoUpdater::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new AutoUpdater); + return CreateHandle(isolate, new AutoUpdater(isolate)); +} + +// static +void AutoUpdater::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL) + .SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates) + .SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall); } } // namespace api diff --git a/atom/browser/api/atom_api_auto_updater.h b/atom/browser/api/atom_api_auto_updater.h index 95b91041e9e3..857647258adf 100644 --- a/atom/browser/api/atom_api_auto_updater.h +++ b/atom/browser/api/atom_api_auto_updater.h @@ -16,15 +16,18 @@ namespace atom { namespace api { -class AutoUpdater : public mate::EventEmitter, +class AutoUpdater : public mate::EventEmitter, public auto_updater::Delegate, public WindowListObserver { public: static mate::Handle Create(v8::Isolate* isolate); + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + protected: - AutoUpdater(); - virtual ~AutoUpdater(); + explicit AutoUpdater(v8::Isolate* isolate); + ~AutoUpdater() override; // Delegate implementations. void OnError(const std::string& error) override; @@ -39,10 +42,6 @@ class AutoUpdater : public mate::EventEmitter, // WindowListObserver: void OnWindowAllClosed() override; - // mate::Wrappable implementations: - mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; - private: void QuitAndInstall(); diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index e49a2ee2f676..8698b43485bf 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -186,8 +186,10 @@ void SetCookieOnIO(scoped_refptr getter, } // namespace -Cookies::Cookies(content::BrowserContext* browser_context) - : request_context_getter_(browser_context->GetRequestContext()) { +Cookies::Cookies(v8::Isolate* isolate, + content::BrowserContext* browser_context) + : request_context_getter_(browser_context->GetRequestContext()) { + Init(isolate); } Cookies::~Cookies() { @@ -223,7 +225,7 @@ void Cookies::Set(const base::DictionaryValue& details, mate::Handle Cookies::Create( v8::Isolate* isolate, content::BrowserContext* browser_context) { - return mate::CreateHandle(isolate, new Cookies(browser_context)); + return mate::CreateHandle(isolate, new Cookies(isolate, browser_context)); } // static diff --git a/atom/browser/api/atom_api_cookies.h b/atom/browser/api/atom_api_cookies.h index 302fd1b25110..33fee56960f4 100644 --- a/atom/browser/api/atom_api_cookies.h +++ b/atom/browser/api/atom_api_cookies.h @@ -46,8 +46,8 @@ class Cookies : public mate::TrackableObject { v8::Local prototype); protected: - explicit Cookies(content::BrowserContext* browser_context); - ~Cookies(); + Cookies(v8::Isolate* isolate, content::BrowserContext* browser_context); + ~Cookies() override; void Get(const base::DictionaryValue& filter, const GetCallback& callback); void Remove(const GURL& url, const std::string& name, diff --git a/atom/browser/api/atom_api_debugger.cc b/atom/browser/api/atom_api_debugger.cc index eab60311f3dd..828c573188db 100644 --- a/atom/browser/api/atom_api_debugger.cc +++ b/atom/browser/api/atom_api_debugger.cc @@ -31,9 +31,10 @@ WrapDebuggerCallback g_wrap_debugger; } // namespace -Debugger::Debugger(content::WebContents* web_contents) +Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents) : web_contents_(web_contents), previous_request_id_(0) { + Init(isolate); } Debugger::~Debugger() { @@ -150,7 +151,8 @@ void Debugger::SendCommand(mate::Arguments* args) { mate::Handle Debugger::Create( v8::Isolate* isolate, content::WebContents* web_contents) { - auto handle = mate::CreateHandle(isolate, new Debugger(web_contents)); + auto handle = mate::CreateHandle( + isolate, new Debugger(isolate, web_contents)); g_wrap_debugger.Run(handle.ToV8()); return handle; } diff --git a/atom/browser/api/atom_api_debugger.h b/atom/browser/api/atom_api_debugger.h index 5454108e8b09..1e97fa89abd0 100644 --- a/atom/browser/api/atom_api_debugger.h +++ b/atom/browser/api/atom_api_debugger.h @@ -42,8 +42,8 @@ class Debugger: public mate::TrackableObject, v8::Local prototype); protected: - explicit Debugger(content::WebContents* web_contents); - ~Debugger(); + Debugger(v8::Isolate* isolate, content::WebContents* web_contents); + ~Debugger() override; // content::DevToolsAgentHostClient: void AgentHostClosed(content::DevToolsAgentHost* agent_host, diff --git a/atom/browser/api/atom_api_desktop_capturer.cc b/atom/browser/api/atom_api_desktop_capturer.cc index cdae6f0c44cd..cc978a40b399 100644 --- a/atom/browser/api/atom_api_desktop_capturer.cc +++ b/atom/browser/api/atom_api_desktop_capturer.cc @@ -38,7 +38,8 @@ namespace atom { namespace api { -DesktopCapturer::DesktopCapturer() { +DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) { + Init(isolate); } DesktopCapturer::~DesktopCapturer() { @@ -92,15 +93,16 @@ bool DesktopCapturer::OnRefreshFinished() { return false; } -mate::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return mate::ObjectTemplateBuilder(isolate) - .SetMethod("startHandling", &DesktopCapturer::StartHandling); +// static +mate::Handle DesktopCapturer::Create(v8::Isolate* isolate) { + return mate::CreateHandle(isolate, new DesktopCapturer(isolate)); } // static -mate::Handle DesktopCapturer::Create(v8::Isolate* isolate) { - return mate::CreateHandle(isolate, new DesktopCapturer); +void DesktopCapturer::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("startHandling", &DesktopCapturer::StartHandling); } } // namespace api diff --git a/atom/browser/api/atom_api_desktop_capturer.h b/atom/browser/api/atom_api_desktop_capturer.h index c22c8a44835f..e71141fa5218 100644 --- a/atom/browser/api/atom_api_desktop_capturer.h +++ b/atom/browser/api/atom_api_desktop_capturer.h @@ -14,18 +14,21 @@ namespace atom { namespace api { -class DesktopCapturer: public mate::EventEmitter, +class DesktopCapturer: public mate::EventEmitter, public DesktopMediaListObserver { public: static mate::Handle Create(v8::Isolate* isolate); + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + void StartHandling(bool capture_window, bool capture_screen, const gfx::Size& thumbnail_size); protected: - DesktopCapturer(); - ~DesktopCapturer(); + explicit DesktopCapturer(v8::Isolate* isolate); + ~DesktopCapturer() override; // DesktopMediaListObserver overrides. void OnSourceAdded(int index) override; @@ -36,10 +39,6 @@ class DesktopCapturer: public mate::EventEmitter, bool OnRefreshFinished() override; private: - // mate::Wrappable: - mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; - scoped_ptr media_list_; DISALLOW_COPY_AND_ASSIGN(DesktopCapturer); diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index 3edd5f9c2549..10f7c4546254 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -57,9 +57,11 @@ std::map>> g_download_item_objects; } // namespace -DownloadItem::DownloadItem(content::DownloadItem* download_item) +DownloadItem::DownloadItem(v8::Isolate* isolate, + content::DownloadItem* download_item) : download_item_(download_item) { download_item_->AddObserver(this); + Init(isolate); AttachAsUserData(download_item); } @@ -173,7 +175,7 @@ mate::Handle DownloadItem::Create( if (existing) return mate::CreateHandle(isolate, static_cast(existing)); - auto handle = mate::CreateHandle(isolate, new DownloadItem(item)); + auto handle = mate::CreateHandle(isolate, new DownloadItem(isolate, item)); g_wrap_download_item.Run(handle.ToV8()); // Reference this object in case it got garbage collected. diff --git a/atom/browser/api/atom_api_download_item.h b/atom/browser/api/atom_api_download_item.h index 64469b9b34d1..bc7ddd821bb9 100644 --- a/atom/browser/api/atom_api_download_item.h +++ b/atom/browser/api/atom_api_download_item.h @@ -23,7 +23,6 @@ class DownloadItem : public mate::TrackableObject, static mate::Handle Create(v8::Isolate* isolate, content::DownloadItem* item); - // mate::TrackableObject: static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); @@ -41,7 +40,7 @@ class DownloadItem : public mate::TrackableObject, base::FilePath GetSavePath() const; protected: - explicit DownloadItem(content::DownloadItem* download_item); + DownloadItem(v8::Isolate* isolate, content::DownloadItem* download_item); ~DownloadItem(); // Override content::DownloadItem::Observer methods diff --git a/atom/browser/api/atom_api_global_shortcut.cc b/atom/browser/api/atom_api_global_shortcut.cc index f5a03e4abf90..3a9a3e7ddbe0 100644 --- a/atom/browser/api/atom_api_global_shortcut.cc +++ b/atom/browser/api/atom_api_global_shortcut.cc @@ -19,7 +19,8 @@ namespace atom { namespace api { -GlobalShortcut::GlobalShortcut() { +GlobalShortcut::GlobalShortcut(v8::Isolate* isolate) { + Init(isolate); } GlobalShortcut::~GlobalShortcut() { @@ -66,20 +67,21 @@ void GlobalShortcut::UnregisterAll() { GlobalShortcutListener::GetInstance()->UnregisterAccelerators(this); } -mate::ObjectTemplateBuilder GlobalShortcut::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return mate::ObjectTemplateBuilder(isolate) +// static +mate::Handle GlobalShortcut::Create(v8::Isolate* isolate) { + return CreateHandle(isolate, new GlobalShortcut(isolate)); +} + +// static +void GlobalShortcut::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) .SetMethod("register", &GlobalShortcut::Register) .SetMethod("isRegistered", &GlobalShortcut::IsRegistered) .SetMethod("unregister", &GlobalShortcut::Unregister) .SetMethod("unregisterAll", &GlobalShortcut::UnregisterAll); } -// static -mate::Handle GlobalShortcut::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new GlobalShortcut); -} - } // namespace api } // namespace atom diff --git a/atom/browser/api/atom_api_global_shortcut.h b/atom/browser/api/atom_api_global_shortcut.h index d7057b000320..41eb42f85569 100644 --- a/atom/browser/api/atom_api_global_shortcut.h +++ b/atom/browser/api/atom_api_global_shortcut.h @@ -23,13 +23,12 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer, public: static mate::Handle Create(v8::Isolate* isolate); - protected: - GlobalShortcut(); - ~GlobalShortcut() override; + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); - // mate::Wrappable implementations: - mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; + protected: + explicit GlobalShortcut(v8::Isolate* isolate); + ~GlobalShortcut() override; private: typedef std::map AcceleratorCallbackMap; diff --git a/atom/browser/api/atom_api_menu.cc b/atom/browser/api/atom_api_menu.cc index e40ba17f464f..ec222ba1540c 100644 --- a/atom/browser/api/atom_api_menu.cc +++ b/atom/browser/api/atom_api_menu.cc @@ -19,7 +19,7 @@ namespace atom { namespace api { -Menu::Menu() +Menu::Menu(v8::Isolate* isolate) : model_(new AtomMenuModel(this)), parent_(NULL) { } diff --git a/atom/browser/api/atom_api_menu.h b/atom/browser/api/atom_api_menu.h index 1ae708863a73..5701985ab101 100644 --- a/atom/browser/api/atom_api_menu.h +++ b/atom/browser/api/atom_api_menu.h @@ -20,7 +20,7 @@ namespace api { class Menu : public mate::TrackableObject, public AtomMenuModel::Delegate { public: - static mate::Wrappable* Create(); + static mate::WrappableBase* Create(v8::Isolate* isolate); static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); @@ -36,7 +36,7 @@ class Menu : public mate::TrackableObject, AtomMenuModel* model() const { return model_.get(); } protected: - Menu(); + explicit Menu(v8::Isolate* isolate); ~Menu() override; // mate::Wrappable: diff --git a/atom/browser/api/atom_api_menu_mac.h b/atom/browser/api/atom_api_menu_mac.h index 85227fa2a9d9..293e8ec4edae 100644 --- a/atom/browser/api/atom_api_menu_mac.h +++ b/atom/browser/api/atom_api_menu_mac.h @@ -17,7 +17,7 @@ namespace api { class MenuMac : public Menu { protected: - MenuMac(); + explicit MenuMac(v8::Isolate* isolate); void PopupAt(Window* window, int x, int y, int positioning_item = 0) override; diff --git a/atom/browser/api/atom_api_menu_mac.mm b/atom/browser/api/atom_api_menu_mac.mm index 71c677b0476e..d8ee089c1cba 100644 --- a/atom/browser/api/atom_api_menu_mac.mm +++ b/atom/browser/api/atom_api_menu_mac.mm @@ -15,7 +15,7 @@ namespace atom { namespace api { -MenuMac::MenuMac() { +MenuMac::MenuMac(v8::Isolate* isolate) : Menu(isolate) { } void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) { @@ -68,8 +68,8 @@ void Menu::SendActionToFirstResponder(const std::string& action) { } // static -mate::Wrappable* Menu::Create() { - return new MenuMac(); +mate::WrappableBase* Menu::Create(v8::Isolate* isolate) { + return new MenuMac(isolate); } } // namespace api diff --git a/atom/browser/api/atom_api_menu_views.cc b/atom/browser/api/atom_api_menu_views.cc index 4a3a97dd906e..f0422ed7ba58 100644 --- a/atom/browser/api/atom_api_menu_views.cc +++ b/atom/browser/api/atom_api_menu_views.cc @@ -13,7 +13,7 @@ namespace atom { namespace api { -MenuViews::MenuViews() { +MenuViews::MenuViews(v8::Isolate* isolate) : Menu(isolate) { } void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { @@ -49,7 +49,7 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { } // static -mate::Wrappable* Menu::Create() { +mate::WrappableBase* Menu::Create() { return new MenuViews(); } diff --git a/atom/browser/api/atom_api_menu_views.h b/atom/browser/api/atom_api_menu_views.h index e4d17c77ca65..e1daa4904028 100644 --- a/atom/browser/api/atom_api_menu_views.h +++ b/atom/browser/api/atom_api_menu_views.h @@ -14,7 +14,7 @@ namespace api { class MenuViews : public Menu { public: - MenuViews(); + explicit MenuViews(v8::Isolate* isolate); protected: void PopupAt(Window* window, int x, int y, int positioning_item = 0) override; diff --git a/atom/browser/api/atom_api_power_monitor.cc b/atom/browser/api/atom_api_power_monitor.cc index 31b35e10cea8..c72620c809d3 100644 --- a/atom/browser/api/atom_api_power_monitor.cc +++ b/atom/browser/api/atom_api_power_monitor.cc @@ -14,8 +14,9 @@ namespace atom { namespace api { -PowerMonitor::PowerMonitor() { +PowerMonitor::PowerMonitor(v8::Isolate* isolate) { base::PowerMonitor::Get()->AddObserver(this); + Init(isolate); } PowerMonitor::~PowerMonitor() { @@ -46,7 +47,12 @@ v8::Local PowerMonitor::Create(v8::Isolate* isolate) { return v8::Null(isolate); } - return CreateHandle(isolate, new PowerMonitor).ToV8(); + return CreateHandle(isolate, new PowerMonitor(isolate)).ToV8(); +} + +// static +void PowerMonitor::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { } } // namespace api diff --git a/atom/browser/api/atom_api_power_monitor.h b/atom/browser/api/atom_api_power_monitor.h index 8fb52eeec95e..50d4bb466ca9 100644 --- a/atom/browser/api/atom_api_power_monitor.h +++ b/atom/browser/api/atom_api_power_monitor.h @@ -19,8 +19,11 @@ class PowerMonitor : public mate::TrackableObject, public: static v8::Local Create(v8::Isolate* isolate); + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + protected: - PowerMonitor(); + explicit PowerMonitor(v8::Isolate* isolate); ~PowerMonitor() override; // base::PowerObserver implementations: diff --git a/atom/browser/api/atom_api_power_save_blocker.cc b/atom/browser/api/atom_api_power_save_blocker.cc index 58983e6c846a..5f8272b98489 100644 --- a/atom/browser/api/atom_api_power_save_blocker.cc +++ b/atom/browser/api/atom_api_power_save_blocker.cc @@ -37,9 +37,10 @@ namespace atom { namespace api { -PowerSaveBlocker::PowerSaveBlocker() +PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate) : current_blocker_type_( - content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) { + content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) { + Init(isolate); } PowerSaveBlocker::~PowerSaveBlocker() { @@ -97,17 +98,18 @@ bool PowerSaveBlocker::IsStarted(int id) { return power_save_blocker_types_.find(id) != power_save_blocker_types_.end(); } -mate::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return mate::ObjectTemplateBuilder(isolate) - .SetMethod("start", &PowerSaveBlocker::Start) - .SetMethod("stop", &PowerSaveBlocker::Stop) - .SetMethod("isStarted", &PowerSaveBlocker::IsStarted); +// static +mate::Handle PowerSaveBlocker::Create(v8::Isolate* isolate) { + return CreateHandle(isolate, new PowerSaveBlocker(isolate)); } // static -mate::Handle PowerSaveBlocker::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new PowerSaveBlocker); +void PowerSaveBlocker::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("start", &PowerSaveBlocker::Start) + .SetMethod("stop", &PowerSaveBlocker::Stop) + .SetMethod("isStarted", &PowerSaveBlocker::IsStarted); } } // namespace api diff --git a/atom/browser/api/atom_api_power_save_blocker.h b/atom/browser/api/atom_api_power_save_blocker.h index a698d746ceb0..c24ae0aa4b66 100644 --- a/atom/browser/api/atom_api_power_save_blocker.h +++ b/atom/browser/api/atom_api_power_save_blocker.h @@ -24,13 +24,12 @@ class PowerSaveBlocker : public mate::TrackableObject { public: static mate::Handle Create(v8::Isolate* isolate); - protected: - PowerSaveBlocker(); - ~PowerSaveBlocker() override; + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); - // mate::Wrappable implementations: - mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; + protected: + explicit PowerSaveBlocker(v8::Isolate* isolate); + ~PowerSaveBlocker() override; private: void UpdatePowerSaveBlocker(); diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 09da9c71cadb..3835fac62d7a 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -22,37 +22,11 @@ namespace atom { namespace api { -Protocol::Protocol(AtomBrowserContext* browser_context) +Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context) : request_context_getter_(browser_context->GetRequestContext()), job_factory_(browser_context->job_factory()) { 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); + Init(isolate); } void Protocol::RegisterStandardSchemes( @@ -150,7 +124,35 @@ std::string Protocol::ErrorCodeToString(ProtocolError error) { // static mate::Handle Protocol::Create( v8::Isolate* isolate, AtomBrowserContext* browser_context) { - return mate::CreateHandle(isolate, new Protocol(browser_context)); + return mate::CreateHandle(isolate, new Protocol(isolate, 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 diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index 107fbf1ce712..d7fa7f5211f8 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -30,7 +30,7 @@ class AtomURLRequestJobFactory; namespace api { -class Protocol : public mate::Wrappable { +class Protocol : public mate::Wrappable { public: using Handler = base::Callback)>; @@ -40,12 +40,11 @@ class Protocol : public mate::Wrappable { static mate::Handle Create( v8::Isolate* isolate, AtomBrowserContext* browser_context); - protected: - explicit Protocol(AtomBrowserContext* browser_context); + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); - // mate::Wrappable implementations: - virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate); + protected: + Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context); private: // Possible errors. diff --git a/atom/browser/api/atom_api_screen.cc b/atom/browser/api/atom_api_screen.cc index 407a71f0cc41..61b722d7a44f 100644 --- a/atom/browser/api/atom_api_screen.cc +++ b/atom/browser/api/atom_api_screen.cc @@ -47,9 +47,11 @@ std::vector MetricsToArray(uint32_t metrics) { } // namespace -Screen::Screen(gfx::Screen* screen) : screen_(screen) { +Screen::Screen(v8::Isolate* isolate, gfx::Screen* screen) + : screen_(screen) { displays_ = screen_->GetAllDisplays(); screen_->AddObserver(this); + Init(isolate); } Screen::~Screen() { @@ -100,16 +102,6 @@ void Screen::OnDisplayMetricsChanged(const gfx::Display& display, Emit("display-metrics-changed", display, MetricsToArray(changed_metrics)); } -mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return mate::ObjectTemplateBuilder(isolate) - .SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint) - .SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay) - .SetMethod("getAllDisplays", &Screen::GetAllDisplays) - .SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint) - .SetMethod("getDisplayMatching", &Screen::GetDisplayMatching); -} - // static v8::Local Screen::Create(v8::Isolate* isolate) { if (!Browser::Get()->is_ready()) { @@ -126,7 +118,18 @@ v8::Local Screen::Create(v8::Isolate* isolate) { return v8::Null(isolate); } - return mate::CreateHandle(isolate, new Screen(screen)).ToV8(); + return mate::CreateHandle(isolate, new Screen(isolate, screen)).ToV8(); +} + +// static +void Screen::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint) + .SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay) + .SetMethod("getAllDisplays", &Screen::GetAllDisplays) + .SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint) + .SetMethod("getDisplayMatching", &Screen::GetDisplayMatching); } } // namespace api diff --git a/atom/browser/api/atom_api_screen.h b/atom/browser/api/atom_api_screen.h index f724130fa7fc..14fc8ce30e7b 100644 --- a/atom/browser/api/atom_api_screen.h +++ b/atom/browser/api/atom_api_screen.h @@ -21,14 +21,17 @@ namespace atom { namespace api { -class Screen : public mate::EventEmitter, +class Screen : public mate::EventEmitter, public gfx::DisplayObserver { public: static v8::Local Create(v8::Isolate* isolate); + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + protected: - explicit Screen(gfx::Screen* screen); - virtual ~Screen(); + Screen(v8::Isolate* isolate, gfx::Screen* screen); + ~Screen() override; gfx::Point GetCursorScreenPoint(); gfx::Display GetPrimaryDisplay(); @@ -42,10 +45,6 @@ class Screen : public mate::EventEmitter, void OnDisplayMetricsChanged(const gfx::Display& display, uint32_t changed_metrics) override; - // mate::Wrappable: - mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; - private: gfx::Screen* screen_; std::vector displays_; diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 222591e92e92..140135d329e3 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -288,14 +288,15 @@ void ClearHostResolverCacheInIO( } // namespace -Session::Session(AtomBrowserContext* browser_context) +Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context) : devtools_network_emulation_client_id_(base::GenerateGUID()), browser_context_(browser_context) { - AttachAsUserData(browser_context); - // Observe DownloadManger to get download notifications. content::BrowserContext::GetDownloadManager(browser_context)-> AddObserver(this); + + Init(isolate); + AttachAsUserData(browser_context); } Session::~Session() { @@ -308,6 +309,9 @@ void Session::OnDownloadCreated(content::DownloadManager* manager, auto web_contents = item->GetWebContents(); if (SavePageHandler::IsSavePageTypes(item->GetMimeType())) return; + + v8::Locker locker(isolate()); + v8::HandleScope handle_scope(isolate()); bool prevent_default = Emit( "will-download", DownloadItem::Create(isolate(), item), @@ -454,7 +458,8 @@ mate::Handle Session::CreateFrom( if (existing) return mate::CreateHandle(isolate, static_cast(existing)); - auto handle = mate::CreateHandle(isolate, new Session(browser_context)); + auto handle = mate::CreateHandle( + isolate, new Session(isolate, browser_context)); g_wrap_session.Run(handle.ToV8()); return handle; } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 7da01acdaaa6..5e08a85aa7d1 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -58,7 +58,7 @@ class Session: public mate::TrackableObject, v8::Local prototype); protected: - explicit Session(AtomBrowserContext* browser_context); + Session(v8::Isolate* isolate, AtomBrowserContext* browser_context); ~Session(); // content::DownloadManager::Observer: diff --git a/atom/browser/api/atom_api_tray.cc b/atom/browser/api/atom_api_tray.cc index 5f351f485049..34fe81b92b22 100644 --- a/atom/browser/api/atom_api_tray.cc +++ b/atom/browser/api/atom_api_tray.cc @@ -22,7 +22,7 @@ namespace atom { namespace api { -Tray::Tray(const gfx::Image& image) +Tray::Tray(v8::Isolate* isolate, const gfx::Image& image) : tray_icon_(TrayIcon::Create()) { tray_icon_->SetImage(image); tray_icon_->AddObserver(this); @@ -32,13 +32,13 @@ Tray::~Tray() { } // static -mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) { +mate::WrappableBase* Tray::New(v8::Isolate* isolate, const gfx::Image& image) { if (!Browser::Get()->is_ready()) { isolate->ThrowException(v8::Exception::Error(mate::StringToV8( isolate, "Cannot create Tray before app is ready"))); return nullptr; } - return new Tray(image); + return new Tray(isolate, image); } void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) { diff --git a/atom/browser/api/atom_api_tray.h b/atom/browser/api/atom_api_tray.h index 0e0d153ad0d3..84e68220dba8 100644 --- a/atom/browser/api/atom_api_tray.h +++ b/atom/browser/api/atom_api_tray.h @@ -32,13 +32,14 @@ class Menu; class Tray : public mate::TrackableObject, public TrayIconObserver { public: - static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image); + static mate::WrappableBase* New( + v8::Isolate* isolate, const gfx::Image& image); static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); protected: - explicit Tray(const gfx::Image& image); + Tray(v8::Isolate* isolate, const gfx::Image& image); ~Tray() override; // TrayIconObserver: diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 73aa8ba577ac..cec998a87229 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -215,14 +215,17 @@ content::ServiceWorkerContext* GetServiceWorkerContext( } // namespace -WebContents::WebContents(content::WebContents* web_contents) +WebContents::WebContents(v8::Isolate* isolate, + content::WebContents* web_contents) : content::WebContentsObserver(web_contents), embedder_(nullptr), type_(REMOTE), request_id_(0), background_throttling_(true) { - AttachAsUserData(web_contents); web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); + + Init(isolate); + AttachAsUserData(web_contents); } WebContents::WebContents(v8::Isolate* isolate, @@ -270,7 +273,6 @@ WebContents::WebContents(v8::Isolate* isolate, } Observe(web_contents); - AttachAsUserData(web_contents); InitWithWebContents(web_contents); managed_web_contents()->GetView()->SetDelegate(this); @@ -299,6 +301,9 @@ WebContents::WebContents(v8::Isolate* isolate, if (owner_window) SetOwnerWindow(owner_window); } + + Init(isolate); + AttachAsUserData(web_contents); } WebContents::~WebContents() { @@ -1290,7 +1295,8 @@ mate::Handle WebContents::CreateFrom( return mate::CreateHandle(isolate, static_cast(existing)); // Otherwise create a new WebContents wrapper object. - auto handle = mate::CreateHandle(isolate, new WebContents(web_contents)); + auto handle = mate::CreateHandle( + isolate, new WebContents(isolate, web_contents)); g_wrap_web_contents.Run(handle.ToV8()); return handle; } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index bc2d4106f5f2..9deb1696c411 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -55,6 +55,9 @@ class WebContents : public mate::TrackableObject, static mate::Handle Create( v8::Isolate* isolate, const mate::Dictionary& options); + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + int GetID() const; bool Equal(const WebContents* web_contents) const; void LoadURL(const GURL& url, const mate::Dictionary& options); @@ -156,12 +159,8 @@ class WebContents : public mate::TrackableObject, v8::Local DevToolsWebContents(v8::Isolate* isolate); v8::Local Debugger(v8::Isolate* isolate); - // mate::TrackableObject: - static void BuildPrototype(v8::Isolate* isolate, - v8::Local prototype); - protected: - explicit WebContents(content::WebContents* web_contents); + WebContents(v8::Isolate* isolate, content::WebContents* web_contents); WebContents(v8::Isolate* isolate, const mate::Dictionary& options); ~WebContents(); diff --git a/atom/browser/api/atom_api_web_request.cc b/atom/browser/api/atom_api_web_request.cc index a987369ed82d..867901df065b 100644 --- a/atom/browser/api/atom_api_web_request.cc +++ b/atom/browser/api/atom_api_web_request.cc @@ -36,8 +36,10 @@ namespace atom { namespace api { -WebRequest::WebRequest(AtomBrowserContext* browser_context) +WebRequest::WebRequest(v8::Isolate* isolate, + AtomBrowserContext* browser_context) : browser_context_(browser_context) { + Init(isolate); } WebRequest::~WebRequest() { @@ -81,7 +83,7 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) { mate::Handle WebRequest::Create( v8::Isolate* isolate, AtomBrowserContext* browser_context) { - return mate::CreateHandle(isolate, new WebRequest(browser_context)); + return mate::CreateHandle(isolate, new WebRequest(isolate, browser_context)); } // static diff --git a/atom/browser/api/atom_api_web_request.h b/atom/browser/api/atom_api_web_request.h index 9a6e17a04605..edcdcc5339e3 100644 --- a/atom/browser/api/atom_api_web_request.h +++ b/atom/browser/api/atom_api_web_request.h @@ -21,13 +21,12 @@ class WebRequest : 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 WebRequest(AtomBrowserContext* browser_context); - ~WebRequest(); + WebRequest(v8::Isolate* isolate, AtomBrowserContext* browser_context); + ~WebRequest() override; // C++ can not distinguish overloaded member function. template diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 2bac6fa808d6..c61a7f566c09 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -287,7 +287,7 @@ void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) { #endif // static -mate::Wrappable* Window::New(v8::Isolate* isolate, mate::Arguments* args) { +mate::WrappableBase* Window::New(v8::Isolate* isolate, mate::Arguments* args) { if (!Browser::Get()->is_ready()) { isolate->ThrowException(v8::Exception::Error(mate::StringToV8( isolate, "Cannot create BrowserWindow before app is ready"))); diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 0b8f0e3c491c..a00e063d99f8 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -38,7 +38,7 @@ class WebContents; class Window : public mate::TrackableObject, public NativeWindowObserver { public: - static mate::Wrappable* New(v8::Isolate* isolate, mate::Arguments* args); + static mate::WrappableBase* New(v8::Isolate* isolate, mate::Arguments* args); static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); @@ -51,7 +51,7 @@ class Window : public mate::TrackableObject, protected: Window(v8::Isolate* isolate, const mate::Dictionary& options); - virtual ~Window(); + ~Window() override; // NativeWindowObserver: void WillCloseWindow(bool* prevent_default) override; diff --git a/atom/browser/api/event.cc b/atom/browser/api/event.cc index 5c87292ea52e..74e78a85cd1d 100644 --- a/atom/browser/api/event.cc +++ b/atom/browser/api/event.cc @@ -11,31 +11,15 @@ namespace mate { -namespace { - -v8::Persistent template_; - -} // namespace - -Event::Event() +Event::Event(v8::Isolate* isolate) : sender_(NULL), message_(NULL) { + Init(isolate); } Event::~Event() { } -ObjectTemplateBuilder Event::GetObjectTemplateBuilder(v8::Isolate* isolate) { - if (template_.IsEmpty()) - template_.Reset(isolate, ObjectTemplateBuilder(isolate) - .SetMethod("preventDefault", &Event::PreventDefault) - .SetMethod("sendReply", &Event::SendReply) - .Build()); - - return ObjectTemplateBuilder( - isolate, v8::Local::New(isolate, template_)); -} - void Event::SetSenderAndMessage(content::WebContents* sender, IPC::Message* message) { DCHECK(!sender_); @@ -52,7 +36,7 @@ void Event::WebContentsDestroyed() { } void Event::PreventDefault(v8::Isolate* isolate) { - GetWrapper(isolate)->Set(StringToV8(isolate, "defaultPrevented"), + GetWrapper()->Set(StringToV8(isolate, "defaultPrevented"), v8::True(isolate)); } @@ -66,7 +50,15 @@ bool Event::SendReply(const base::string16& json) { // static Handle Event::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new Event); + return CreateHandle(isolate, new Event(isolate)); +} + +// static +void Event::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("preventDefault", &Event::PreventDefault) + .SetMethod("sendReply", &Event::SendReply); } } // namespace mate diff --git a/atom/browser/api/event.h b/atom/browser/api/event.h index 5cdc08324b72..81db638a0dc2 100644 --- a/atom/browser/api/event.h +++ b/atom/browser/api/event.h @@ -15,11 +15,14 @@ class Message; namespace mate { -class Event : public Wrappable, +class Event : public Wrappable, public content::WebContentsObserver { public: static Handle Create(v8::Isolate* isolate); + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + // Pass the sender and message to be replied. void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message); @@ -30,11 +33,8 @@ class Event : public Wrappable, bool SendReply(const base::string16& json); protected: - Event(); - virtual ~Event(); - - // Wrappable implementations: - ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override; + explicit Event(v8::Isolate* isolate); + ~Event() override; // content::WebContentsObserver implementations: void WebContentsDestroyed() override; diff --git a/atom/browser/api/event_emitter.cc b/atom/browser/api/event_emitter.cc index be7018dafa44..7e392fddee34 100644 --- a/atom/browser/api/event_emitter.cc +++ b/atom/browser/api/event_emitter.cc @@ -34,11 +34,13 @@ v8::Local CreateEventObject(v8::Isolate* isolate) { } // namespace -EventEmitter::EventEmitter() { -} +namespace internal { -v8::Local EventEmitter::CreateJSEvent( - v8::Isolate* isolate, content::WebContents* sender, IPC::Message* message) { +v8::Local CreateJSEvent( + v8::Isolate* isolate, + v8::Local object, + content::WebContents* sender, + IPC::Message* message) { v8::Local event; bool use_native_event = sender && message; @@ -49,16 +51,20 @@ v8::Local EventEmitter::CreateJSEvent( } else { event = CreateEventObject(isolate); } - mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate)); + mate::Dictionary(isolate, event).Set("sender", object); return event; } -v8::Local EventEmitter::CreateCustomEvent( - v8::Isolate* isolate, v8::Local custom_event) { +v8::Local CreateCustomEvent( + v8::Isolate* isolate, + v8::Local object, + v8::Local custom_event) { v8::Local event = CreateEventObject(isolate); (void)event->SetPrototype(custom_event->CreationContext(), custom_event); - mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate)); + mate::Dictionary(isolate, event).Set("sender", object); return event; } +} // namespace internal + } // namespace mate diff --git a/atom/browser/api/event_emitter.h b/atom/browser/api/event_emitter.h index 42816d42a45b..226accfe6269 100644 --- a/atom/browser/api/event_emitter.h +++ b/atom/browser/api/event_emitter.h @@ -20,17 +20,40 @@ class Message; namespace mate { +namespace internal { + +v8::Local CreateJSEvent(v8::Isolate* isolate, + v8::Local object, + content::WebContents* sender, + IPC::Message* message); +v8::Local CreateCustomEvent( + v8::Isolate* isolate, + v8::Local object, + v8::Local event); + +} // namespace internal + // Provide helperers to emit event in JavaScript. -class EventEmitter : public Wrappable { +template +class EventEmitter : public Wrappable { public: typedef std::vector> ValueArray; + // Make the convinient methods visible: + // https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members + v8::Local GetWrapper(v8::Isolate* isolate = nullptr) { + return Wrappable::GetWrapper(); + } + v8::Isolate* isolate() const { return Wrappable::isolate(); } + // this.emit(name, event, args...); template bool EmitCustomEvent(const base::StringPiece& name, v8::Local event, const Args&... args) { - return EmitWithEvent(name, CreateCustomEvent(isolate(), event), args...); + return EmitWithEvent( + name, + internal::CreateCustomEvent(isolate(), GetWrapper(), event), args...); } // this.emit(name, new Event(), args...); @@ -47,12 +70,13 @@ class EventEmitter : public Wrappable { const Args&... args) { v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); - v8::Local event = CreateJSEvent(isolate(), sender, message); + v8::Local event = internal::CreateJSEvent( + isolate(), GetWrapper(), sender, message); return EmitWithEvent(name, event, args...); } protected: - EventEmitter(); + EventEmitter() {} private: // this.emit(name, event, args...); @@ -67,12 +91,6 @@ class EventEmitter : public Wrappable { StringToV8(isolate(), "defaultPrevented"))->BooleanValue(); } - v8::Local CreateJSEvent(v8::Isolate* isolate, - content::WebContents* sender, - IPC::Message* message); - v8::Local CreateCustomEvent( - v8::Isolate* isolate, v8::Local event); - DISALLOW_COPY_AND_ASSIGN(EventEmitter); }; diff --git a/atom/browser/api/trackable_object.cc b/atom/browser/api/trackable_object.cc index 77a936cde02c..5148df627c8d 100644 --- a/atom/browser/api/trackable_object.cc +++ b/atom/browser/api/trackable_object.cc @@ -37,15 +37,6 @@ TrackableObjectBase::~TrackableObjectBase() { cleanup_.Run(); } -void TrackableObjectBase::AfterInit(v8::Isolate* isolate) { - if (wrapped_) - AttachAsUserData(wrapped_); -} - -void TrackableObjectBase::MarkDestroyed() { - GetWrapper(isolate())->SetAlignedPointerInInternalField(0, nullptr); -} - base::Closure TrackableObjectBase::GetDestroyClosure() { return base::Bind(&TrackableObjectBase::Destroy, weak_factory_.GetWeakPtr()); } diff --git a/atom/browser/api/trackable_object.h b/atom/browser/api/trackable_object.h index 7c4ed03fe052..5a036f4297dd 100644 --- a/atom/browser/api/trackable_object.h +++ b/atom/browser/api/trackable_object.h @@ -21,7 +21,7 @@ class SupportsUserData; namespace mate { // Users should use TrackableObject instead. -class TrackableObjectBase : public mate::EventEmitter { +class TrackableObjectBase { public: TrackableObjectBase(); @@ -32,13 +32,7 @@ class TrackableObjectBase : public mate::EventEmitter { void AttachAsUserData(base::SupportsUserData* wrapped); protected: - ~TrackableObjectBase() override; - - // mate::Wrappable: - void AfterInit(v8::Isolate* isolate) override; - - // Mark the JS object as destroyed. - void MarkDestroyed(); + virtual ~TrackableObjectBase(); // Returns a closure that can destroy the native class. base::Closure GetDestroyClosure(); @@ -65,8 +59,14 @@ class TrackableObjectBase : public mate::EventEmitter { // All instances of TrackableObject will be kept in a weak map and can be got // from its ID. template -class TrackableObject : public TrackableObjectBase { +class TrackableObject : public TrackableObjectBase, + public mate::EventEmitter { public: + // Mark the JS object as destroyed. + void MarkDestroyed() { + Wrappable::GetWrapper()->SetAlignedPointerInInternalField(0, nullptr); + } + // Finds out the TrackableObject from its ID in weak map. static T* FromWeakMapID(v8::Isolate* isolate, int32_t id) { if (!weak_map_) @@ -106,6 +106,7 @@ class TrackableObject : public TrackableObjectBase { protected: TrackableObject() {} + ~TrackableObject() override { RemoveFromWeakMap(); } @@ -116,38 +117,22 @@ class TrackableObject : public TrackableObjectBase { RegisterDestructionCallback( base::Bind(&TrackableObject::ReleaseAllWeakReferences)); } - weak_map_id_ = weak_map_->Add(isolate, GetWrapper(isolate)); - TrackableObjectBase::AfterInit(isolate); + weak_map_id_ = weak_map_->Add(isolate, Wrappable::GetWrapper()); + if (wrapped_) + AttachAsUserData(wrapped_); } private: - // mate::Wrappable: - mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override { - if (template_.IsEmpty()) { - auto templ = v8::ObjectTemplate::New(isolate); - T::BuildPrototype(isolate, templ); - template_.Reset(isolate, templ); - } - - return ObjectTemplateBuilder( - isolate, v8::Local::New(isolate, template_)); - } - // Releases all weak references in weak map, called when app is terminating. static void ReleaseAllWeakReferences() { weak_map_.reset(); } - static v8::Persistent template_; static scoped_ptr weak_map_; DISALLOW_COPY_AND_ASSIGN(TrackableObject); }; -template -v8::Persistent TrackableObject::template_; - template scoped_ptr TrackableObject::weak_map_; diff --git a/atom/common/api/atom_api_asar.cc b/atom/common/api/atom_api_asar.cc index 4bfb0ed4c1be..1b0ea799e7d7 100644 --- a/atom/common/api/atom_api_asar.cc +++ b/atom/common/api/atom_api_asar.cc @@ -18,21 +18,39 @@ namespace { -v8::Persistent template_; - -class Archive : public mate::Wrappable { +class Archive : public mate::Wrappable { public: static v8::Local Create(v8::Isolate* isolate, const base::FilePath& path) { scoped_ptr archive(new asar::Archive(path)); if (!archive->Init()) return v8::False(isolate); - return (new Archive(std::move(archive)))->GetWrapper(isolate); + return (new Archive(isolate, std::move(archive)))->GetWrapper(); + } + + static void BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetProperty("path", &Archive::GetPath) + .SetMethod("getFileInfo", &Archive::GetFileInfo) + .SetMethod("stat", &Archive::Stat) + .SetMethod("readdir", &Archive::Readdir) + .SetMethod("realpath", &Archive::Realpath) + .SetMethod("copyFileOut", &Archive::CopyFileOut) + .SetMethod("getFd", &Archive::GetFD) + .SetMethod("destroy", &Archive::Destroy); } protected: - explicit Archive(scoped_ptr archive) - : archive_(std::move(archive)) {} + Archive(v8::Isolate* isolate, scoped_ptr archive) + : archive_(std::move(archive)) { + Init(isolate); + } + + // Returns the path of the file. + base::FilePath GetPath() { + return archive_->path(); + } // Reads the offset and size of file. v8::Local GetFileInfo(v8::Isolate* isolate, @@ -101,24 +119,6 @@ class Archive : public mate::Wrappable { archive_.reset(); } - // mate::Wrappable: - mate::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) { - if (template_.IsEmpty()) - template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate) - .SetValue("path", archive_->path()) - .SetMethod("getFileInfo", &Archive::GetFileInfo) - .SetMethod("stat", &Archive::Stat) - .SetMethod("readdir", &Archive::Readdir) - .SetMethod("realpath", &Archive::Realpath) - .SetMethod("copyFileOut", &Archive::CopyFileOut) - .SetMethod("getFd", &Archive::GetFD) - .SetMethod("destroy", &Archive::Destroy) - .Build()); - - return mate::ObjectTemplateBuilder( - isolate, v8::Local::New(isolate, template_)); - } - private: scoped_ptr archive_; diff --git a/atom/common/api/atom_api_id_weak_map.cc b/atom/common/api/atom_api_id_weak_map.cc index f32e33682dff..0d3ddae3cc09 100644 --- a/atom/common/api/atom_api_id_weak_map.cc +++ b/atom/common/api/atom_api_id_weak_map.cc @@ -12,7 +12,7 @@ namespace atom { namespace api { -IDWeakMap::IDWeakMap() { +IDWeakMap::IDWeakMap(v8::Isolate* isolate) { } IDWeakMap::~IDWeakMap() { @@ -52,8 +52,8 @@ void IDWeakMap::BuildPrototype(v8::Isolate* isolate, } // static -mate::Wrappable* IDWeakMap::Create(v8::Isolate* isolate) { - return new IDWeakMap; +mate::WrappableBase* IDWeakMap::Create(v8::Isolate* isolate) { + return new IDWeakMap(isolate); } } // namespace api diff --git a/atom/common/api/atom_api_id_weak_map.h b/atom/common/api/atom_api_id_weak_map.h index 0cf656f455bc..616112ffe6f4 100644 --- a/atom/common/api/atom_api_id_weak_map.h +++ b/atom/common/api/atom_api_id_weak_map.h @@ -13,15 +13,15 @@ namespace atom { namespace api { -class IDWeakMap : public mate::Wrappable { +class IDWeakMap : public mate::Wrappable { public: - static mate::Wrappable* Create(v8::Isolate* isolate); + static mate::WrappableBase* Create(v8::Isolate* isolate); static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); protected: - IDWeakMap(); + explicit IDWeakMap(v8::Isolate* isolate); ~IDWeakMap(); private: diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 3dda326f59fd..1c90fe7080fb 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -168,35 +168,15 @@ bool ReadImageSkiaFromICO(gfx::ImageSkia* image, const base::FilePath& path) { } #endif -v8::Persistent template_; - } // namespace -NativeImage::NativeImage() {} - -NativeImage::NativeImage(const gfx::Image& image) : image_(image) {} +NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image) + : image_(image) { + Init(isolate); +} NativeImage::~NativeImage() {} -mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - if (template_.IsEmpty()) - template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate) - .SetMethod("toPng", &NativeImage::ToPNG) - .SetMethod("toJpeg", &NativeImage::ToJPEG) - .SetMethod("getNativeHandle", &NativeImage::GetNativeHandle) - .SetMethod("toDataURL", &NativeImage::ToDataURL) - .SetMethod("toDataUrl", &NativeImage::ToDataURL) // deprecated. - .SetMethod("isEmpty", &NativeImage::IsEmpty) - .SetMethod("getSize", &NativeImage::GetSize) - .SetMethod("setTemplateImage", &NativeImage::SetTemplateImage) - .SetMethod("isTemplateImage", &NativeImage::IsTemplateImage) - .Build()); - - return mate::ObjectTemplateBuilder( - isolate, v8::Local::New(isolate, template_)); -} - v8::Local NativeImage::ToPNG(v8::Isolate* isolate) { scoped_refptr png = image_.As1xPNGBytes(); return node::Buffer::Copy(isolate, @@ -255,13 +235,13 @@ bool NativeImage::IsTemplateImage() { // static mate::Handle NativeImage::CreateEmpty(v8::Isolate* isolate) { - return mate::CreateHandle(isolate, new NativeImage); + return mate::CreateHandle(isolate, new NativeImage(isolate, gfx::Image())); } // static mate::Handle NativeImage::Create( v8::Isolate* isolate, const gfx::Image& image) { - return mate::CreateHandle(isolate, new NativeImage(image)); + return mate::CreateHandle(isolate, new NativeImage(isolate, image)); } // static @@ -330,6 +310,21 @@ mate::Handle NativeImage::CreateFromDataURL( return CreateEmpty(isolate); } +// static +void NativeImage::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) + .SetMethod("toPng", &NativeImage::ToPNG) + .SetMethod("toJpeg", &NativeImage::ToJPEG) + .SetMethod("getNativeHandle", &NativeImage::GetNativeHandle) + .SetMethod("toDataURL", &NativeImage::ToDataURL) + .SetMethod("toDataUrl", &NativeImage::ToDataURL) // deprecated. + .SetMethod("isEmpty", &NativeImage::IsEmpty) + .SetMethod("getSize", &NativeImage::GetSize) + .SetMethod("setTemplateImage", &NativeImage::SetTemplateImage) + .SetMethod("isTemplateImage", &NativeImage::IsTemplateImage); +} + } // namespace api } // namespace atom diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index 145f5ff1dcdc..79844604706c 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -29,7 +29,7 @@ namespace atom { namespace api { -class NativeImage : public mate::Wrappable { +class NativeImage : public mate::Wrappable { public: static mate::Handle CreateEmpty(v8::Isolate* isolate); static mate::Handle Create( @@ -45,18 +45,14 @@ class NativeImage : public mate::Wrappable { static mate::Handle CreateFromDataURL( v8::Isolate* isolate, const GURL& url); - // The default constructor should only be used by image_converter.cc. - NativeImage(); + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); const gfx::Image& image() const { return image_; } protected: - explicit NativeImage(const gfx::Image& image); - virtual ~NativeImage(); - - // mate::Wrappable: - mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; + NativeImage(v8::Isolate* isolate, const gfx::Image& image); + ~NativeImage() override; private: v8::Local ToPNG(v8::Isolate* isolate); diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index e00b901bfff6..32b8a84f26d5 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -54,8 +54,9 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback { } // namespace -WebFrame::WebFrame() +WebFrame::WebFrame(v8::Isolate* isolate) : web_frame_(blink::WebLocalFrame::frameForCurrentContext()) { + Init(isolate); } WebFrame::~WebFrame() { @@ -67,7 +68,7 @@ void WebFrame::SetName(const std::string& name) { double WebFrame::SetZoomLevel(double level) { double ret = web_frame_->view()->setZoomLevel(level); - mate::EmitEvent(isolate(), GetWrapper(isolate()), "zoom-level-changed", ret); + mate::EmitEvent(isolate(), GetWrapper(), "zoom-level-changed", ret); return ret; } @@ -162,9 +163,15 @@ void WebFrame::ExecuteJavaScript(const base::string16& code, callback.release()); } -mate::ObjectTemplateBuilder WebFrame::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return mate::ObjectTemplateBuilder(isolate) +// static +mate::Handle WebFrame::Create(v8::Isolate* isolate) { + return CreateHandle(isolate, new WebFrame(isolate)); +} + +// static +void WebFrame::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype) .SetMethod("setName", &WebFrame::SetName) .SetMethod("setZoomLevel", &WebFrame::SetZoomLevel) .SetMethod("getZoomLevel", &WebFrame::GetZoomLevel) @@ -187,11 +194,6 @@ mate::ObjectTemplateBuilder WebFrame::GetObjectTemplateBuilder( .SetMethod("executeJavaScript", &WebFrame::ExecuteJavaScript); } -// static -mate::Handle WebFrame::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new WebFrame); -} - } // namespace api } // namespace atom diff --git a/atom/renderer/api/atom_api_web_frame.h b/atom/renderer/api/atom_api_web_frame.h index d55b24fd25ea..e1eeb224930b 100644 --- a/atom/renderer/api/atom_api_web_frame.h +++ b/atom/renderer/api/atom_api_web_frame.h @@ -26,13 +26,16 @@ namespace api { class SpellCheckClient; -class WebFrame : public mate::Wrappable { +class WebFrame : public mate::Wrappable { public: static mate::Handle Create(v8::Isolate* isolate); + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + private: - WebFrame(); - virtual ~WebFrame(); + explicit WebFrame(v8::Isolate* isolate); + ~WebFrame() override; void SetName(const std::string& name); @@ -66,10 +69,6 @@ class WebFrame : public mate::Wrappable { // Excecuting scripts. void ExecuteJavaScript(const base::string16& code, mate::Arguments* args); - // mate::Wrappable: - virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate); - scoped_ptr spell_check_client_; blink::WebLocalFrame* web_frame_; diff --git a/vendor/native_mate b/vendor/native_mate index 553326b00696..0df2d882ea22 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit 553326b00696fcda106a8866872a8f2ad6caff0d +Subproject commit 0df2d882ea2286e6335f206b7002037fce66c4a5 From 60d2cb8a84d9dd74b5178d5da923e6da66c871fc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 10:19:25 +0900 Subject: [PATCH 079/141] Remove the isolate parameter of GetWrapper --- atom/browser/api/atom_api_menu.cc | 2 +- atom/browser/api/atom_api_window.cc | 4 ++-- atom/browser/api/event_emitter.h | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/atom/browser/api/atom_api_menu.cc b/atom/browser/api/atom_api_menu.cc index ec222ba1540c..996c71739bc4 100644 --- a/atom/browser/api/atom_api_menu.cc +++ b/atom/browser/api/atom_api_menu.cc @@ -28,7 +28,7 @@ Menu::~Menu() { } void Menu::AfterInit(v8::Isolate* isolate) { - mate::Dictionary wrappable(isolate, GetWrapper(isolate)); + mate::Dictionary wrappable(isolate, GetWrapper()); mate::Dictionary delegate; if (!wrappable.Get("delegate", &delegate)) return; diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index c61a7f566c09..ae5eec64cf93 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -151,7 +151,7 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) { api_web_contents_ = web_contents.get(); // Keep a copy of the options for later use. - mate::Dictionary(isolate, web_contents->GetWrapper(isolate)).Set( + mate::Dictionary(isolate, web_contents->GetWrapper()).Set( "browserWindowOptions", options); // Creates BrowserWindow. @@ -817,7 +817,7 @@ v8::Local Window::From(v8::Isolate* isolate, NativeWindow* native_window) { auto existing = TrackableObject::FromWrappedClass(isolate, native_window); if (existing) - return existing->GetWrapper(isolate); + return existing->GetWrapper(); else return v8::Null(isolate); } diff --git a/atom/browser/api/event_emitter.h b/atom/browser/api/event_emitter.h index 226accfe6269..99f6ed46e48f 100644 --- a/atom/browser/api/event_emitter.h +++ b/atom/browser/api/event_emitter.h @@ -41,9 +41,7 @@ class EventEmitter : public Wrappable { // Make the convinient methods visible: // https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members - v8::Local GetWrapper(v8::Isolate* isolate = nullptr) { - return Wrappable::GetWrapper(); - } + v8::Local GetWrapper() { return Wrappable::GetWrapper(); } v8::Isolate* isolate() const { return Wrappable::isolate(); } // this.emit(name, event, args...); @@ -86,7 +84,7 @@ class EventEmitter : public Wrappable { const Args&... args) { v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); - EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...); + EmitEvent(isolate(), GetWrapper(), name, event, args...); return event->Get( StringToV8(isolate(), "defaultPrevented"))->BooleanValue(); } From 993695af07a0c59b5e97445939d7536658eb5660 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 10:23:36 +0900 Subject: [PATCH 080/141] Remove unneeded cleanup code --- atom/browser/api/atom_api_debugger.cc | 8 -------- atom/browser/api/atom_api_download_item.cc | 8 -------- atom/browser/api/atom_api_session.cc | 8 -------- atom/browser/api/atom_api_web_contents.cc | 8 -------- atom/browser/api/trackable_object.h | 7 ------- 5 files changed, 39 deletions(-) diff --git a/atom/browser/api/atom_api_debugger.cc b/atom/browser/api/atom_api_debugger.cc index 828c573188db..03490360133a 100644 --- a/atom/browser/api/atom_api_debugger.cc +++ b/atom/browser/api/atom_api_debugger.cc @@ -167,16 +167,8 @@ 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 diff --git a/atom/browser/api/atom_api_download_item.cc b/atom/browser/api/atom_api_download_item.cc index 10f7c4546254..96826a250f57 100644 --- a/atom/browser/api/atom_api_download_item.cc +++ b/atom/browser/api/atom_api_download_item.cc @@ -184,16 +184,8 @@ mate::Handle DownloadItem::Create( return handle; } -void ClearWrapDownloadItem() { - g_wrap_download_item.Reset(); -} - void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) { g_wrap_download_item = callback; - - // Cleanup the wrapper on exit. - atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback( - base::Bind(ClearWrapDownloadItem)); } } // namespace api diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 140135d329e3..ec4e2aebe4c2 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -494,16 +494,8 @@ void Session::BuildPrototype(v8::Isolate* isolate, .SetProperty("webRequest", &Session::WebRequest); } -void ClearWrapSession() { - g_wrap_session.Reset(); -} - void SetWrapSession(const WrapSessionCallback& callback) { g_wrap_session = callback; - - // Cleanup the wrapper on exit. - atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback( - base::Bind(ClearWrapSession)); } } // namespace api diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index cec998a87229..a48277490b00 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1309,16 +1309,8 @@ mate::Handle WebContents::Create( return handle; } -void ClearWrapWebContents() { - g_wrap_web_contents.Reset(); -} - void SetWrapWebContents(const WrapWebContentsCallback& callback) { g_wrap_web_contents = callback; - - // Cleanup the wrapper on exit. - atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback( - base::Bind(ClearWrapWebContents)); } } // namespace api diff --git a/atom/browser/api/trackable_object.h b/atom/browser/api/trackable_object.h index 5a036f4297dd..1c71d84e42c9 100644 --- a/atom/browser/api/trackable_object.h +++ b/atom/browser/api/trackable_object.h @@ -114,8 +114,6 @@ class TrackableObject : public TrackableObjectBase, void AfterInit(v8::Isolate* isolate) override { if (!weak_map_) { weak_map_.reset(new atom::IDWeakMap); - RegisterDestructionCallback( - base::Bind(&TrackableObject::ReleaseAllWeakReferences)); } weak_map_id_ = weak_map_->Add(isolate, Wrappable::GetWrapper()); if (wrapped_) @@ -123,11 +121,6 @@ class TrackableObject : public TrackableObjectBase, } private: - // Releases all weak references in weak map, called when app is terminating. - static void ReleaseAllWeakReferences() { - weak_map_.reset(); - } - static scoped_ptr weak_map_; DISALLOW_COPY_AND_ASSIGN(TrackableObject); From 272592415d84a0390a567f41eb3cb0634911155b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 10:27:54 +0900 Subject: [PATCH 081/141] Fix building on non-mac --- atom/browser/api/atom_api_menu_views.cc | 4 ++-- atom/renderer/api/atom_api_web_frame.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_menu_views.cc b/atom/browser/api/atom_api_menu_views.cc index f0422ed7ba58..4d1c902e1755 100644 --- a/atom/browser/api/atom_api_menu_views.cc +++ b/atom/browser/api/atom_api_menu_views.cc @@ -49,8 +49,8 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) { } // static -mate::WrappableBase* Menu::Create() { - return new MenuViews(); +mate::WrappableBase* Menu::Create(v8::Isolate* isolate) { + return new MenuViews(isolate); } } // namespace api diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index 32b8a84f26d5..0eebc94fc141 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -165,7 +165,7 @@ void WebFrame::ExecuteJavaScript(const base::string16& code, // static mate::Handle WebFrame::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new WebFrame(isolate)); + return mate::CreateHandle(isolate, new WebFrame(isolate)); } // static From 9fe3dbcfe0aeb02ff0323e2ef5d6961fad7e3c31 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 10:40:19 +0900 Subject: [PATCH 082/141] Make VS happy --- atom/browser/api/atom_api_app.cc | 2 +- atom/browser/api/atom_api_auto_updater.cc | 2 +- atom/browser/api/atom_api_global_shortcut.cc | 2 +- atom/browser/api/atom_api_power_monitor.cc | 2 +- atom/browser/api/atom_api_power_save_blocker.cc | 2 +- atom/browser/api/event.cc | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index a7842c42ce05..b35589ecad33 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -442,7 +442,7 @@ void App::OnCertificateManagerModelCreated( // static mate::Handle App::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new App(isolate)); + return mate::CreateHandle(isolate, new App(isolate)); } // static diff --git a/atom/browser/api/atom_api_auto_updater.cc b/atom/browser/api/atom_api_auto_updater.cc index 102bffb71182..cdf3406ae788 100644 --- a/atom/browser/api/atom_api_auto_updater.cc +++ b/atom/browser/api/atom_api_auto_updater.cc @@ -95,7 +95,7 @@ void AutoUpdater::QuitAndInstall() { // static mate::Handle AutoUpdater::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new AutoUpdater(isolate)); + return mate::CreateHandle(isolate, new AutoUpdater(isolate)); } // static diff --git a/atom/browser/api/atom_api_global_shortcut.cc b/atom/browser/api/atom_api_global_shortcut.cc index 3a9a3e7ddbe0..2b1e5d6591a0 100644 --- a/atom/browser/api/atom_api_global_shortcut.cc +++ b/atom/browser/api/atom_api_global_shortcut.cc @@ -69,7 +69,7 @@ void GlobalShortcut::UnregisterAll() { // static mate::Handle GlobalShortcut::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new GlobalShortcut(isolate)); + return mate::CreateHandle(isolate, new GlobalShortcut(isolate)); } // static diff --git a/atom/browser/api/atom_api_power_monitor.cc b/atom/browser/api/atom_api_power_monitor.cc index c72620c809d3..15220c117c5b 100644 --- a/atom/browser/api/atom_api_power_monitor.cc +++ b/atom/browser/api/atom_api_power_monitor.cc @@ -47,7 +47,7 @@ v8::Local PowerMonitor::Create(v8::Isolate* isolate) { return v8::Null(isolate); } - return CreateHandle(isolate, new PowerMonitor(isolate)).ToV8(); + return mate::CreateHandle(isolate, new PowerMonitor(isolate)).ToV8(); } // static diff --git a/atom/browser/api/atom_api_power_save_blocker.cc b/atom/browser/api/atom_api_power_save_blocker.cc index 5f8272b98489..b8adcb776e56 100644 --- a/atom/browser/api/atom_api_power_save_blocker.cc +++ b/atom/browser/api/atom_api_power_save_blocker.cc @@ -100,7 +100,7 @@ bool PowerSaveBlocker::IsStarted(int id) { // static mate::Handle PowerSaveBlocker::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new PowerSaveBlocker(isolate)); + return mate::CreateHandle(isolate, new PowerSaveBlocker(isolate)); } // static diff --git a/atom/browser/api/event.cc b/atom/browser/api/event.cc index 74e78a85cd1d..f456cf2758bb 100644 --- a/atom/browser/api/event.cc +++ b/atom/browser/api/event.cc @@ -50,7 +50,7 @@ bool Event::SendReply(const base::string16& json) { // static Handle Event::Create(v8::Isolate* isolate) { - return CreateHandle(isolate, new Event(isolate)); + return mate::CreateHandle(isolate, new Event(isolate)); } // static From 13f8599ba10217ceeac413fb5f4bb9ec460aa9a1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 24 Apr 2016 21:13:46 +0900 Subject: [PATCH 083/141] Add systemPreferences module --- .../api/atom_api_system_preferences.cc | 48 +++++++++++++++++++ .../browser/api/atom_api_system_preferences.h | 34 +++++++++++++ .../api/atom_api_system_preferences_mac.mm | 15 ++++++ atom/common/node_bindings.cc | 1 + filenames.gypi | 4 ++ lib/browser/api/exports/electron.js | 6 +++ lib/browser/api/system-preferences.js | 6 +++ 7 files changed, 114 insertions(+) create mode 100644 atom/browser/api/atom_api_system_preferences.cc create mode 100644 atom/browser/api/atom_api_system_preferences.h create mode 100644 atom/browser/api/atom_api_system_preferences_mac.mm create mode 100644 lib/browser/api/system-preferences.js diff --git a/atom/browser/api/atom_api_system_preferences.cc b/atom/browser/api/atom_api_system_preferences.cc new file mode 100644 index 000000000000..53aaabd17328 --- /dev/null +++ b/atom/browser/api/atom_api_system_preferences.cc @@ -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. + +#include "atom/browser/api/atom_api_system_preferences.h" + +#include "atom/common/node_includes.h" +#include "native_mate/dictionary.h" + +namespace atom { + +namespace api { + +SystemPreferences::SystemPreferences(v8::Isolate* isolate) { + Init(isolate); +} + +SystemPreferences::~SystemPreferences() { +} + +// static +mate::Handle SystemPreferences::Create( + v8::Isolate* isolate) { + return mate::CreateHandle(isolate, new SystemPreferences(isolate)); +} + +// static +void SystemPreferences::BuildPrototype( + v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype); +} + +} // 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.Set("systemPreferences", atom::api::SystemPreferences::Create(isolate)); +} + +} // namespace + +NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_system_preferences, Initialize); diff --git a/atom/browser/api/atom_api_system_preferences.h b/atom/browser/api/atom_api_system_preferences.h new file mode 100644 index 000000000000..22c68b2e873e --- /dev/null +++ b/atom/browser/api/atom_api_system_preferences.h @@ -0,0 +1,34 @@ +// 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_API_ATOM_API_SYSTEM_PREFERENCES_H_ +#define ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_ + +#include "atom/browser/api/event_emitter.h" +#include "native_mate/handle.h" + +namespace atom { + +namespace api { + +class SystemPreferences : public mate::EventEmitter { + public: + static mate::Handle Create(v8::Isolate* isolate); + + static void BuildPrototype(v8::Isolate* isolate, + v8::Local prototype); + + protected: + explicit SystemPreferences(v8::Isolate* isolate); + ~SystemPreferences() override; + + private: + DISALLOW_COPY_AND_ASSIGN(SystemPreferences); +}; + +} // namespace api + +} // namespace atom + +#endif // ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_ diff --git a/atom/browser/api/atom_api_system_preferences_mac.mm b/atom/browser/api/atom_api_system_preferences_mac.mm new file mode 100644 index 000000000000..337d0f87ffc2 --- /dev/null +++ b/atom/browser/api/atom_api_system_preferences_mac.mm @@ -0,0 +1,15 @@ +// 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/api/atom_api_system_preferences.h" + +namespace atom { + +namespace api { + + + +} // namespace api + +} // namespace atom diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc index 86fb3a6d03a3..31105886eb7c 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -44,6 +44,7 @@ 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_system_preferences); REFERENCE_MODULE(atom_browser_tray); REFERENCE_MODULE(atom_browser_web_contents); REFERENCE_MODULE(atom_browser_web_view_manager); diff --git a/filenames.gypi b/filenames.gypi index a1c704c348b1..c3eca34528df 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -28,6 +28,7 @@ 'lib/browser/api/protocol.js', 'lib/browser/api/session.js', 'lib/browser/api/screen.js', + 'lib/browser/api/system-preferences.js', 'lib/browser/api/tray.js', 'lib/browser/api/web-contents.js', 'lib/browser/chrome-extension.js', @@ -115,6 +116,9 @@ 'atom/browser/api/atom_api_screen.h', 'atom/browser/api/atom_api_session.cc', 'atom/browser/api/atom_api_session.h', + 'atom/browser/api/atom_api_system_preferences.cc', + 'atom/browser/api/atom_api_system_preferences.h', + 'atom/browser/api/atom_api_system_preferences_mac.mm', 'atom/browser/api/atom_api_tray.cc', 'atom/browser/api/atom_api_tray.h', 'atom/browser/api/atom_api_web_contents.cc', diff --git a/lib/browser/api/exports/electron.js b/lib/browser/api/exports/electron.js index bd8285401c79..9d873663029c 100644 --- a/lib/browser/api/exports/electron.js +++ b/lib/browser/api/exports/electron.js @@ -89,6 +89,12 @@ Object.defineProperties(exports, { return require('../session') } }, + systemPreferences: { + enumerable: true, + get: function () { + return require('../system-preferences') + } + }, Tray: { enumerable: true, get: function () { diff --git a/lib/browser/api/system-preferences.js b/lib/browser/api/system-preferences.js new file mode 100644 index 000000000000..6ba1750507c0 --- /dev/null +++ b/lib/browser/api/system-preferences.js @@ -0,0 +1,6 @@ +const {EventEmitter} = require('events') +const {systemPreferences} = process.atomBinding('system_preferences') + +Object.setPrototypeOf(systemPreferences, EventEmitter.prototype) + +module.exports = systemPreferences From d72a0e452f6fdbc8cf080e94c2b973519ba5b057 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 12:24:11 +0900 Subject: [PATCH 084/141] BuildPrototype should not be empty --- atom/browser/api/atom_api_power_monitor.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/browser/api/atom_api_power_monitor.cc b/atom/browser/api/atom_api_power_monitor.cc index 15220c117c5b..32c50c696c7f 100644 --- a/atom/browser/api/atom_api_power_monitor.cc +++ b/atom/browser/api/atom_api_power_monitor.cc @@ -53,6 +53,7 @@ v8::Local PowerMonitor::Create(v8::Isolate* isolate) { // static void PowerMonitor::BuildPrototype( v8::Isolate* isolate, v8::Local prototype) { + mate::ObjectTemplateBuilder(isolate, prototype); } } // namespace api From ddd8eae661cbb912ee19fa2ffa223596219cfc6a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 12:35:09 +0900 Subject: [PATCH 085/141] Move isAeroGlassEnabled and isDarkMode to systemPreferences --- atom/browser/api/atom_api_app.cc | 10 --------- atom/browser/api/atom_api_app.h | 4 ---- .../api/atom_api_system_preferences.cc | 22 ++++++++++++++++++- .../browser/api/atom_api_system_preferences.h | 5 +++++ .../api/atom_api_system_preferences_mac.mm | 10 ++++++++- atom/browser/browser.h | 3 --- atom/browser/browser_mac.mm | 5 ----- lib/browser/api/app.js | 22 +++++++++---------- 8 files changed, 46 insertions(+), 35 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index b35589ecad33..683ce4520203 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -41,7 +41,6 @@ #if defined(OS_WIN) #include "base/strings/utf_string_conversions.h" -#include "ui/base/win/shell.h" #endif using atom::Browser; @@ -382,12 +381,6 @@ std::string App::GetLocale() { return l10n_util::GetApplicationLocale(""); } -#if defined(OS_WIN) -bool App::IsAeroGlassEnabled() { - return ui::win::IsAeroGlassEnabled(); -} -#endif - bool App::MakeSingleInstance( const ProcessSingleton::NotificationCallback& callback) { if (process_singleton_.get()) @@ -471,13 +464,10 @@ void App::BuildPrototype( #if defined(OS_MACOSX) .SetMethod("hide", base::Bind(&Browser::Hide, browser)) .SetMethod("show", base::Bind(&Browser::Show, browser)) - .SetMethod("isDarkMode", - base::Bind(&Browser::IsDarkMode, browser)) #endif #if defined(OS_WIN) .SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser)) - .SetMethod("isAeroGlassEnabled", &App::IsAeroGlassEnabled) #endif .SetMethod("setPath", &App::SetPath) .SetMethod("getPath", &App::GetPath) diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 354ea38d884b..6a13d4013b64 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -114,10 +114,6 @@ class App : public AtomBrowserClient::Delegate, const net::CompletionCallback& callback); #endif -#if defined(OS_WIN) - bool IsAeroGlassEnabled(); -#endif - scoped_ptr process_singleton_; #if defined(USE_NSS_CERTS) diff --git a/atom/browser/api/atom_api_system_preferences.cc b/atom/browser/api/atom_api_system_preferences.cc index 53aaabd17328..6e4774c196e0 100644 --- a/atom/browser/api/atom_api_system_preferences.cc +++ b/atom/browser/api/atom_api_system_preferences.cc @@ -7,6 +7,10 @@ #include "atom/common/node_includes.h" #include "native_mate/dictionary.h" +#if defined(OS_WIN) +#include "ui/base/win/shell.h" +#endif + namespace atom { namespace api { @@ -18,6 +22,18 @@ SystemPreferences::SystemPreferences(v8::Isolate* isolate) { SystemPreferences::~SystemPreferences() { } +#if defined(OS_WIN) +bool SystemPreferences::IsAeroGlassEnabled() { + return ui::win::IsAeroGlassEnabled(); +} +#endif + +#if !defined(OS_MACOSX) +bool SystemPreferences::IsDarkMode() { + return false; +} +#endif + // static mate::Handle SystemPreferences::Create( v8::Isolate* isolate) { @@ -27,7 +43,11 @@ mate::Handle SystemPreferences::Create( // static void SystemPreferences::BuildPrototype( v8::Isolate* isolate, v8::Local prototype) { - mate::ObjectTemplateBuilder(isolate, prototype); + mate::ObjectTemplateBuilder(isolate, prototype) +#if defined(OS_WIN) + .SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled) +#endif + .SetMethod("isDarkMode", &SystemPreferences::IsDarkMode); } } // namespace api diff --git a/atom/browser/api/atom_api_system_preferences.h b/atom/browser/api/atom_api_system_preferences.h index 22c68b2e873e..993904511207 100644 --- a/atom/browser/api/atom_api_system_preferences.h +++ b/atom/browser/api/atom_api_system_preferences.h @@ -19,6 +19,11 @@ class SystemPreferences : public mate::EventEmitter { static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); +#if defined(OS_WIN) + bool IsAeroGlassEnabled(); +#endif + bool IsDarkMode(); + protected: explicit SystemPreferences(v8::Isolate* isolate); ~SystemPreferences() override; diff --git a/atom/browser/api/atom_api_system_preferences_mac.mm b/atom/browser/api/atom_api_system_preferences_mac.mm index 337d0f87ffc2..8935ab560ec1 100644 --- a/atom/browser/api/atom_api_system_preferences_mac.mm +++ b/atom/browser/api/atom_api_system_preferences_mac.mm @@ -4,11 +4,19 @@ #include "atom/browser/api/atom_api_system_preferences.h" +#import + namespace atom { namespace api { - +#if defined(OS_MACOSX) +bool SystemPreferences::IsDarkMode() { + NSString* mode = [[NSUserDefaults standardUserDefaults] + stringForKey:@"AppleInterfaceStyle"]; + return [mode isEqualToString:@"Dark"]; +} +#endif } // namespace api diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 67aae152c317..366031b56791 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -89,9 +89,6 @@ class Browser : public WindowListObserver { // Show the application. void Show(); - // Check if the system is in Dark Mode. - bool IsDarkMode(); - // Bounce the dock icon. enum BounceType { BOUNCE_CRITICAL = 0, diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 0294894fcd61..11fd3aa6d357 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -27,11 +27,6 @@ void Browser::Show() { [[AtomApplication sharedApplication] unhide:nil]; } -bool Browser::IsDarkMode() { - NSString *mode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; - return [mode isEqualToString: @"Dark"]; -} - void Browser::AddRecentDocument(const base::FilePath& path) { NSString* path_string = base::mac::FilePathToNSString(path); if (!path_string) diff --git a/lib/browser/api/app.js b/lib/browser/api/app.js index 48a27cfc648d..413719a00339 100644 --- a/lib/browser/api/app.js +++ b/lib/browser/api/app.js @@ -1,8 +1,7 @@ 'use strict' -const deprecate = require('electron').deprecate -const session = require('electron').session -const Menu = require('electron').Menu +const electron = require('electron') +const {deprecate, session, Menu} = electron const EventEmitter = require('events').EventEmitter const bindings = process.atomBinding('app') @@ -65,39 +64,40 @@ for (i = 0, len = ref1.length; i < len; i++) { } // Deprecated. - app.getHomeDir = deprecate('app.getHomeDir', 'app.getPath', function () { return this.getPath('home') }) - app.getDataPath = deprecate('app.getDataPath', 'app.getPath', function () { return this.getPath('userData') }) - app.setDataPath = deprecate('app.setDataPath', 'app.setPath', function (path) { return this.setPath('userData', path) }) - app.resolveProxy = deprecate('app.resolveProxy', 'session.defaultSession.resolveProxy', function (url, callback) { return session.defaultSession.resolveProxy(url, callback) }) - deprecate.rename(app, 'terminate', 'quit') - deprecate.event(app, 'finish-launching', 'ready', function () { // give default app a chance to setup default menu. setImmediate(() => { this.emit('finish-launching') }) }) - deprecate.event(app, 'activate-with-no-open-windows', 'activate', function (event, hasVisibleWindows) { if (!hasVisibleWindows) { return this.emit('activate-with-no-open-windows', event) } }) - deprecate.event(app, 'select-certificate', 'select-client-certificate') +if (process.platform === 'win32') { + app.isAeroGlassEnabled = deprecate('app.isAeroGlassEnabled', 'systemPreferences.isAeroGlassEnabled', function () { + return electron.systemPreferences.isAeroGlassEnabled(); + }) +} else if (process.platform === 'darwin') { + app.isDarkMode = deprecate('app.isDarkMode', 'systemPreferences.isDarkMode', function () { + return electron.systemPreferences.isDarkMode(); + }) +} // Wrappers for native classes. var wrapDownloadItem = function (downloadItem) { From 955722622379930fc891372862f35390a0e16ee0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 14:25:14 +0900 Subject: [PATCH 086/141] Add systemPreferences.subscribeNotification --- .../api/atom_api_system_preferences.cc | 6 +++ .../browser/api/atom_api_system_preferences.h | 7 ++++ .../api/atom_api_system_preferences_mac.mm | 39 ++++++++++++++++++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_system_preferences.cc b/atom/browser/api/atom_api_system_preferences.cc index 6e4774c196e0..86d3484b6705 100644 --- a/atom/browser/api/atom_api_system_preferences.cc +++ b/atom/browser/api/atom_api_system_preferences.cc @@ -4,6 +4,7 @@ #include "atom/browser/api/atom_api_system_preferences.h" +#include "atom/common/native_mate_converters/callback.h" #include "atom/common/node_includes.h" #include "native_mate/dictionary.h" @@ -46,6 +47,11 @@ void SystemPreferences::BuildPrototype( mate::ObjectTemplateBuilder(isolate, prototype) #if defined(OS_WIN) .SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled) +#elif defined(OS_MACOSX) + .SetMethod("subscribeNotification", + &SystemPreferences::SubscribeNotification) + .SetMethod("unsubscribeNotification", + &SystemPreferences::UnsubscribeNotification) #endif .SetMethod("isDarkMode", &SystemPreferences::IsDarkMode); } diff --git a/atom/browser/api/atom_api_system_preferences.h b/atom/browser/api/atom_api_system_preferences.h index 993904511207..6fd7ca922dc8 100644 --- a/atom/browser/api/atom_api_system_preferences.h +++ b/atom/browser/api/atom_api_system_preferences.h @@ -5,7 +5,10 @@ #ifndef ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_ #define ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_ +#include + #include "atom/browser/api/event_emitter.h" +#include "base/callback.h" #include "native_mate/handle.h" namespace atom { @@ -21,6 +24,10 @@ class SystemPreferences : public mate::EventEmitter { #if defined(OS_WIN) bool IsAeroGlassEnabled(); +#elif defined(OS_MACOSX) + int SubscribeNotification(const std::string& name, + const base::Closure& callback); + void UnsubscribeNotification(int id); #endif bool IsDarkMode(); diff --git a/atom/browser/api/atom_api_system_preferences_mac.mm b/atom/browser/api/atom_api_system_preferences_mac.mm index 8935ab560ec1..39eb7e6ede82 100644 --- a/atom/browser/api/atom_api_system_preferences_mac.mm +++ b/atom/browser/api/atom_api_system_preferences_mac.mm @@ -4,19 +4,54 @@ #include "atom/browser/api/atom_api_system_preferences.h" +#include + #import +#include "base/strings/sys_string_conversions.h" + namespace atom { namespace api { -#if defined(OS_MACOSX) +namespace { + +int g_next_id = 0; + +// The map to convert |id| to |int|. +std::map g_id_map; + +} // namespace + +int SystemPreferences::SubscribeNotification(const std::string& name, + const base::Closure& callback) { + int request_id = g_next_id++; + __block base::Closure copied_callback = callback; + g_id_map[request_id] = [[NSDistributedNotificationCenter defaultCenter] + addObserverForName:base::SysUTF8ToNSString(name) + object:nil + queue:nil + usingBlock:^(NSNotification* notification) { + copied_callback.Run(); + } + ]; + return request_id; +} + +void SystemPreferences::UnsubscribeNotification(int request_id) { + auto iter = g_id_map.find(request_id); + if (iter != g_id_map.end()) { + id observer = iter->second; + [[NSDistributedNotificationCenter defaultCenter] removeObserver:observer]; + g_id_map.erase(iter); + } +} + bool SystemPreferences::IsDarkMode() { NSString* mode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; return [mode isEqualToString:@"Dark"]; } -#endif } // namespace api From a421c66f3fd194524c751a2ef77c194c9a0ef37e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 14:34:30 +0900 Subject: [PATCH 087/141] Deprecate the platform-theme-changed event --- atom/browser/api/atom_api_app.cc | 6 ------ atom/browser/api/atom_api_app.h | 4 ---- atom/browser/browser.cc | 4 ---- atom/browser/browser.h | 3 --- atom/browser/browser_observer.h | 2 -- atom/browser/mac/atom_application_delegate.mm | 7 ------- lib/browser/api/app.js | 13 +++++++++++-- 7 files changed, 11 insertions(+), 28 deletions(-) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 683ce4520203..ce20ce96deda 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -331,12 +331,6 @@ void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) { Emit("gpu-process-crashed"); } -#if defined(OS_MACOSX) -void App::OnPlatformThemeChanged() { - Emit("platform-theme-changed"); -} -#endif - base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) { bool succeed = false; base::FilePath path; diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 6a13d4013b64..c99d5df77937 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -92,10 +92,6 @@ class App : public AtomBrowserClient::Delegate, // content::GpuDataManagerObserver: void OnGpuProcessCrashed(base::TerminationStatus exit_code) override; -#if defined(OS_MACOSX) - void OnPlatformThemeChanged() override; -#endif - private: // Get/Set the pre-defined path in PathService. base::FilePath GetPath(mate::Arguments* args, const std::string& name); diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index b60df0dd44a5..b3c7a59e08b5 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -187,8 +187,4 @@ void Browser::OnWindowAllClosed() { FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWindowAllClosed()); } -void Browser::PlatformThemeChanged() { - FOR_EACH_OBSERVER(BrowserObserver, observers_, OnPlatformThemeChanged()); -} - } // namespace atom diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 366031b56791..0f1dbe993118 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -148,9 +148,6 @@ class Browser : public WindowListObserver { // Request basic auth login. void RequestLogin(LoginHandler* login_handler); - // 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 da327eb90a02..f6d76bc13fb3 100644 --- a/atom/browser/browser_observer.h +++ b/atom/browser/browser_observer.h @@ -45,8 +45,6 @@ class BrowserObserver { // The browser requests HTTP login. virtual void OnLogin(LoginHandler* login_handler) {} - 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 f4db929bf575..7662162ab618 100644 --- a/atom/browser/mac/atom_application_delegate.mm +++ b/atom/browser/mac/atom_application_delegate.mm @@ -24,9 +24,6 @@ // 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(platformThemeChanged:) name:@"AppleInterfaceThemeChangedNotification" object:nil]; - atom::Browser::Get()->WillFinishLaunching(); } @@ -62,8 +59,4 @@ return flag; } -- (void)platformThemeChanged:(NSNotification *)notify { - atom::Browser::Get()->PlatformThemeChanged(); -} - @end diff --git a/lib/browser/api/app.js b/lib/browser/api/app.js index 413719a00339..0487270ce7b3 100644 --- a/lib/browser/api/app.js +++ b/lib/browser/api/app.js @@ -91,12 +91,21 @@ deprecate.event(app, 'activate-with-no-open-windows', 'activate', function (even deprecate.event(app, 'select-certificate', 'select-client-certificate') if (process.platform === 'win32') { app.isAeroGlassEnabled = deprecate('app.isAeroGlassEnabled', 'systemPreferences.isAeroGlassEnabled', function () { - return electron.systemPreferences.isAeroGlassEnabled(); + return electron.systemPreferences.isAeroGlassEnabled() }) } else if (process.platform === 'darwin') { app.isDarkMode = deprecate('app.isDarkMode', 'systemPreferences.isDarkMode', function () { - return electron.systemPreferences.isDarkMode(); + return electron.systemPreferences.isDarkMode() }) + app.on = app.addListener = function (event, listener) { + if (event === 'platform-theme-changed') { + deprecate.warn('platform-theme-changed event', "systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', callback)") + electron.systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', function () { + app.emit('platform-theme-changed') + }) + } + EventEmitter.prototype.addListener.call(app, event, listener) + } } // Wrappers for native classes. From 067e9c1a850f077943c66a604085c9b38861bcc4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 15:35:52 +0900 Subject: [PATCH 088/141] Add systemPreferences.getUserDefault --- .../api/atom_api_system_preferences.cc | 1 + .../browser/api/atom_api_system_preferences.h | 2 ++ .../api/atom_api_system_preferences_mac.mm | 25 +++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/atom/browser/api/atom_api_system_preferences.cc b/atom/browser/api/atom_api_system_preferences.cc index 86d3484b6705..b8c665456ade 100644 --- a/atom/browser/api/atom_api_system_preferences.cc +++ b/atom/browser/api/atom_api_system_preferences.cc @@ -52,6 +52,7 @@ void SystemPreferences::BuildPrototype( &SystemPreferences::SubscribeNotification) .SetMethod("unsubscribeNotification", &SystemPreferences::UnsubscribeNotification) + .SetMethod("getUserDefault", &SystemPreferences::GetUserDefault) #endif .SetMethod("isDarkMode", &SystemPreferences::IsDarkMode); } diff --git a/atom/browser/api/atom_api_system_preferences.h b/atom/browser/api/atom_api_system_preferences.h index 6fd7ca922dc8..fed1c52247b7 100644 --- a/atom/browser/api/atom_api_system_preferences.h +++ b/atom/browser/api/atom_api_system_preferences.h @@ -28,6 +28,8 @@ class SystemPreferences : public mate::EventEmitter { int SubscribeNotification(const std::string& name, const base::Closure& callback); void UnsubscribeNotification(int id); + v8::Local GetUserDefault(const std::string& name, + const std::string& type); #endif bool IsDarkMode(); diff --git a/atom/browser/api/atom_api_system_preferences_mac.mm b/atom/browser/api/atom_api_system_preferences_mac.mm index 39eb7e6ede82..2d12b278ae92 100644 --- a/atom/browser/api/atom_api_system_preferences_mac.mm +++ b/atom/browser/api/atom_api_system_preferences_mac.mm @@ -8,7 +8,9 @@ #import +#include "atom/common/native_mate_converters/gurl_converter.h" #include "base/strings/sys_string_conversions.h" +#include "net/base/mac/url_conversions.h" namespace atom { @@ -47,6 +49,29 @@ void SystemPreferences::UnsubscribeNotification(int request_id) { } } +v8::Local SystemPreferences::GetUserDefault( + const std::string& name, const std::string& type) { + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + NSString* key = base::SysUTF8ToNSString(name); + if (type == "string") { + return mate::StringToV8( + isolate(), base::SysNSStringToUTF8([defaults stringForKey:key])); + } else if (type == "boolean") { + return v8::Boolean::New(isolate(), [defaults boolForKey:key]); + } else if (type == "float") { + return v8::Number::New(isolate(), [defaults floatForKey:key]); + } else if (type == "integer") { + return v8::Integer::New(isolate(), [defaults integerForKey:key]); + } else if (type == "double") { + return v8::Number::New(isolate(), [defaults doubleForKey:key]); + } else if (type == "url") { + return mate::ConvertToV8( + isolate(), net::GURLWithNSURL([defaults URLForKey:key])); + } else { + return v8::Undefined(isolate()); + } +} + bool SystemPreferences::IsDarkMode() { NSString* mode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; From 11653aa9c8de7ede345fe7bb66195652af47b133 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 15:36:38 +0900 Subject: [PATCH 089/141] docs: systemPreferences --- docs/README.md | 1 + docs/api/app.md | 34 --------------- docs/api/system-preferences.md | 79 ++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 34 deletions(-) create mode 100644 docs/api/system-preferences.md diff --git a/docs/README.md b/docs/README.md index 428d2f8bd7b1..c8bd425d9759 100644 --- a/docs/README.md +++ b/docs/README.md @@ -62,6 +62,7 @@ an issue: * [powerSaveBlocker](api/power-save-blocker.md) * [protocol](api/protocol.md) * [session](api/session.md) +* [systemPreferences](api/system-preferences.md) * [webContents](api/web-contents.md) * [Tray](api/tray.md) diff --git a/docs/api/app.md b/docs/api/app.md index 8a2cdcfd9224..dbe65d0864fc 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -480,40 +480,6 @@ app.on('ready', function() { Changes the [Application User Model ID][app-user-model-id] to `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: - -```javascript -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.isDarkMode()` _OS X_ - -This method returns `true` if the system is in Dark Mode, and `false` otherwise. - ### `app.importCertificate(options, callback)` _LINUX_ * `options` Object diff --git a/docs/api/system-preferences.md b/docs/api/system-preferences.md new file mode 100644 index 000000000000..8fdd2b54cb0b --- /dev/null +++ b/docs/api/system-preferences.md @@ -0,0 +1,79 @@ +# systemPreferences + +> Get system preferences. + +## Methods + +### `systemPreferences.isDarkMode()` _OS X_ + +This method returns `true` if the system is in Dark Mode, and `false` otherwise. + +### `systemPreferences.subscribeNotification(event, callback)` _OS X_ + +* `event` String +* `callback` Function + +Subscribes to native notifications of OS X, `callback` will be called when the +corresponding `event` happens. The `id` of the subscriber is returned, which can +be used to unsubscribe the `event`. + +Under the hood this API subscribes to `NSDistributedNotificationCenter`, +possible values of `event` are: + +* `AppleInterfaceThemeChangedNotification` +* `AppleAquaColorVariantChanged` +* `AppleColorPreferencesChangedNotification` +* `AppleShowScrollBarsSettingChanged` + +### `systemPreferences.unsubscribeNotification(id)` _OS X_ + +* `id` Integer + +Removes the subscriber with `id`. + +### `systemPreferences.getUserDefault(key, type)` _OS X_ + +* `key` String +* `type` String - Can be `string`, `boolean`, `integer`, `float`, `double`, + `url`. + +Get the value of `key` in system preferences. + +This API reads from `NSUserDefaults` on OS X, some popular `key` and `type`s +are: + +* `AppleInterfaceStyle: string` +* `AppleAquaColorVariant: integer` +* `AppleHighlightColor: string` +* `AppleShowScrollBars: string` + +### `systemPreferences.isAeroGlassEnabled()` _Windows_ + +This method returns `true` if [DWM composition][dwm-composition] (Aero Glass) is +enabled, and `false` otherwise. + +An example of using it to determine if you should create a transparent window or +not (transparent windows won't work correctly when DWM composition is disabled): + +```javascript +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. +let 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'); +} +``` + +[dwm-composition]:https://msdn.microsoft.com/en-us/library/windows/desktop/aa969540.aspx From b5d2e51100f71adbe5d613f599f7d217a8aed7fc Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 25 Apr 2016 22:27:44 +0900 Subject: [PATCH 090/141] docs: platform-theme-changed is deprecated --- docs/api/app.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index dbe65d0864fc..0aca703ba51d 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -228,10 +228,6 @@ app.on('login', function(event, webContents, request, authInfo, callback) { Emitted when the gpu process crashes. -### Event: 'platform-theme-changed' _OS X_ - -Emitted when the system's Dark Mode theme is toggled. - ## Methods The `app` object has the following methods: From 62d00163a858fa078dff5a99a4aed5951500c5da Mon Sep 17 00:00:00 2001 From: michal1106 Date: Mon, 25 Apr 2016 16:45:56 +0300 Subject: [PATCH 091/141] Update using-pepper-flash-plugin.md --- docs/tutorial/using-pepper-flash-plugin.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/tutorial/using-pepper-flash-plugin.md b/docs/tutorial/using-pepper-flash-plugin.md index a9918b220ac0..cdb4d04ad082 100644 --- a/docs/tutorial/using-pepper-flash-plugin.md +++ b/docs/tutorial/using-pepper-flash-plugin.md @@ -11,6 +11,9 @@ 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. +_**Attention:** On windows, Pepper Flash plugin is win32 and it won't work with Electron x64 version. +
Get win32 version from [Electron Releases](https://github.com/electron/electron/releases)_ + ## Add Electron Switch You can directly add `--ppapi-flash-path` and `ppapi-flash-version` to the @@ -20,19 +23,20 @@ For example: ```javascript // Specify flash path. -// On Windows, it might be /path/to/pepflashplayer.dll +// On Windows, it might be /path/to/pepflashplayer.dll or just pepflashplayer.dll if it resides main.js // 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 +// Optional: 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': { + // web-preferences is deprecated. Use webPreferences instead. + 'webPreferences': { 'plugins': true } }); @@ -41,6 +45,8 @@ app.on('ready', function() { }); ``` +_**Attention:** You can check if Flash dll was loaded by running `navigator.plugins` on the Console (although you can't know if the plugin's path is correct)_ + ## Enable Flash Plugin in a `` Tag Add `plugins` attribute to `` tag. From d02125bde5892dc6c696cf73de9f542b404186fb Mon Sep 17 00:00:00 2001 From: arifcakiroglu Date: Tue, 26 Apr 2016 00:49:34 +0300 Subject: [PATCH 092/141] Update README --- README.md | 1 + docs-translations/tr-TR/README.md | 86 ++++++++++++++++++++++++ docs-translations/tr-TR/styleguide.md | 95 +++++++++++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 docs-translations/tr-TR/README.md create mode 100644 docs-translations/tr-TR/styleguide.md diff --git a/README.md b/README.md index 52e290f53efb..f8278f18586f 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ contains documents describing how to build and contribute to Electron. - [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es) - [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN) - [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW) +- [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR) - [Ukrainian](https://github.com/electron/electron/tree/master/docs-translations/uk-UA) - [Russian](https://github.com/electron/electron/tree/master/docs-translations/ru-RU) - [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR) diff --git a/docs-translations/tr-TR/README.md b/docs-translations/tr-TR/README.md new file mode 100644 index 000000000000..1d79da1d6671 --- /dev/null +++ b/docs-translations/tr-TR/README.md @@ -0,0 +1,86 @@ +Lütfen kullandığınız dokümanın Electron versiyonunuzla aynı olduğundan emin olun. +Versiyon numarası okuduğunuz dokümanın URL'sindekiyle aynı olmalı. Eğer aynı değilse, muhtemelen geliştirme aşamasındaki API değişikliklerini içerebilecek dokümantasyonudur. +Eğer öyleyse, atom.io üzerinden [mevcut sürümler](http://electron.atom.io/docs/)e göz atabilirsiniz ya da eğer GitHub arayüzünü kullanıyorsanız "Switch branches/tags" açılır menüsünden versiyonunuza uygun olanı seçebilirsiniz. + +## SSS(Sıkça Sorulan Sorular) + +Bir problem(issue) bildirmeden önce sıkça sorulan sorulara göz atın: +* [Electron SSS](faq/electron-faq.md) + +## Klavuzlar + +* [Desteklenen Platformlar ](tutorial/supported-platforms.md) +* [Uygulama Dağıtımı](tutorial/application-distribution.md) +* [Mac Uygulama Mağazası Başvuru Klavuzu](tutorial/mac-app-store-submission-guide.md) +* [Uygulama Paketleme](tutorial/application-packaging.md) +* [Native Node Modüllerini Kullanma](tutorial/using-native-node-modules.md) +* [Ana Süreç(Main Process) Hata ayıklama](tutorial/debugging-main-process.md) +* [Selenium ve WebDriver kullanımı](tutorial/using-selenium-and-webdriver.md) +* [DevTools Eklentisi](tutorial/devtools-extension.md) +* [Pepper Flash Kullanımı](tutorial/using-pepper-flash-plugin.md) +* [Widevine CDM Kullanımı](tutorial/using-widevine-cdm-plugin.md) +* [CI Sistem Testleri (Travis, Jenkins)](tutorial/testing-on-headless-ci.md) + +## Eğitimler + +* [Quick Start](tutorial/quick-start.md) +* [Desktop Environment Integration](tutorial/desktop-environment-integration.md) +* [Online/Offline Event Detection](tutorial/online-offline-events.md) + +## API Kaynakları + +* [Synopsis](api/synopsis.md) +* [Process Object](api/process.md) +* [Desteklenen Chrome Komut Satırı Anahtarları](api/chrome-command-line-switches.md) +* [Environment Değişkenleri](api/environment-variables.md) + +### Özel DOM Elementleri: + +* [`File` Nesnesi](api/file-object.md) +* [`` Etiketi](api/web-view-tag.md) +* [`window.open` Fonksiyonu](api/window-open.md) + +### Ana Süreç(Main Process) Modülleri: + +* [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) + +### Renderer Process Modülelri (Web Page): + +* [desktopCapturer](api/desktop-capturer.md) +* [ipcRenderer](api/ipc-renderer.md) +* [remote](api/remote.md) +* [webFrame](api/web-frame.md) + +### Her İki Süreç İçin Geçerli Modüller: + +* [clipboard](api/clipboard.md) +* [crashReporter](api/crash-reporter.md) +* [nativeImage](api/native-image.md) +* [screen](api/screen.md) +* [shell](api/shell.md) + +## Geliştirme + +* [Kodlama Stili](development/coding-style.md) +* [Kaynak Kod Dizin Yapısı](development/source-code-directory-structure.md) +* [NW.js(node-webkit adıyla bilinen) İle Arasındaki Teknik Farklılıklar](development/atom-shell-vs-node-webkit.md) +* [Build Sisyem Genel Bakış](development/build-system-overview.md) +* [(OS X) Build Komutları](development/build-instructions-osx.md) +* [(Windows) Build Komutları](development/build-instructions-windows.md) +* [(Linux) Build Komutları](development/build-instructions-linux.md) +* [(Windows) Hata Ayıklama Komutları](development/debug-instructions-windows.md) +* [Simge Sunucusu(Symbol Server) Hata Ayıklama Kurulumu](development/setting-up-symbol-server.md) diff --git a/docs-translations/tr-TR/styleguide.md b/docs-translations/tr-TR/styleguide.md new file mode 100644 index 000000000000..d264600f0d56 --- /dev/null +++ b/docs-translations/tr-TR/styleguide.md @@ -0,0 +1,95 @@ +# Electron Dokümantasyonu Stil Rehberi + +Size uygun bölümü bulun: [Electron Dokümantasyonunu okumak](#reading-electron-documentation) +ya da [Electron Dokümantasyonunu yazmak](#writing-electron-documentation). + +## Electron Dokümantasyonunu Yazmak + +Electron Dokümantasyonunu geliştirmek için aşağıdaki yöntemleri takip edin. + +- Her sayfada en fazla bir tane `h1` etiketi olmalıdır. +- Kod bloklarında `cmd` yerine `bash` kullanın.(syntax highlighter için). +- `h1` Başlığı nesne ismiyle eşleşmeli (ör. `browser-window` → + `BrowserWindow`). + - Hyphen separated filenames, however, are fine. +- No headers following headers, add at least a one-sentence description. +- Methods headers are wrapped in `code` ticks. +- Event headers are wrapped in single 'quotation' marks. +- No nesting lists more than 2 levels (unfortunately because of markdown + renderer). +- Add section titles: Events, Class Methods and Instance Methods. +- Use 'will' over 'would' when describing outcomes. +- Events and methods are `h3` headers. +- Optional arguments written as `function (required[, optional])`. +- Optional arguments are denoted when called out in list. +- Line length is 80-column wrapped. +- Platform specific methods are noted in italics following method header. + - ```### `method(foo, bar)` _OS X_``` +- Prefer 'in the ___ process' over 'on' + +### Dokümantasyon Çevirisi + +Electron Dokümantasyonunun çevirileri `docs-translations` klasörü içerisindedir. + +To add another set (or partial set): + +- Create a subdirectory named by language abbreviation. +- Within that subdirectory, duplicate the `docs` directory, keeping the + names of directories and files same. +- Translate the files. +- Update the `README.md` within your language directory to link to the files + you have translated. +- Add a link to your translation directory on the main Electron [README](https://github.com/electron/electron#documentation-translations). + +## Electron Dokümantasyonunu Okumak + +Electron Dokümantasyon sözdizimini(syntax) anlayabileceğiniz bir kaç ipucu: + +### Metodlar + +[Method](https://developer.mozilla.org/en-US/docs/Glossary/Method) dokümantasyonunun bir örneği: + +--- + +`methodName(required[, optional]))` + +* `require` String (**required**) +* `optional` Integer + +--- + +The method name is followed by the arguments it takes. Optional arguments are +notated by brackets surrounding the optional argument as well as the comma +required if this optional argument follows another argument. + +Below the method is more detailed information on each of the arguments. The type +of argument is notated by either the common types: +[`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) +or a custom type like Electron's [`webContent`](api/web-content.md). + +### Events + +[event](https://developer.mozilla.org/en-US/docs/Web/API/Event) Dokümantasyonunun bir örneği: + +--- + +Event: 'wake-up' + +Returns: + +* `time` String + +--- + +The event is a string that is used after a `.on` listener method. If it returns +a value it and its type is noted below. If you were to listen and respond to +this event it might look something like this: + +```javascript +Alarm.on('wake-up', function(time) { + console.log(time) +}) +``` From 64db17dde73272c066ad82fc23d2878b2078799f Mon Sep 17 00:00:00 2001 From: arifcakiroglu Date: Tue, 26 Apr 2016 01:03:17 +0300 Subject: [PATCH 093/141] Added Turkish Docs link to README-ko --- README-ko.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README-ko.md b/README-ko.md index a3dd38124fae..706a5556df9f 100644 --- a/README-ko.md +++ b/README-ko.md @@ -56,6 +56,7 @@ npm install electron-prebuilt --save-dev - [스페인어](https://github.com/electron/electron/tree/master/docs-translations/es) - [중국어 간체](https://github.com/electron/electron/tree/master/docs-translations/zh-CN) - [중국어 번체](https://github.com/electron/electron/tree/master/docs-translations/zh-TW) +- [터키의](https://github.com/electron/electron/tree/master/docs-translations/tr-TR) - [우크라이나어](https://github.com/electron/electron/tree/master/docs-translations/uk-UA) - [러시아어](https://github.com/electron/electron/tree/master/docs-translations/ru-RU) - [프랑스어](https://github.com/electron/electron/tree/master/docs-translations/fr-FR) From a0c14eed046f9a4c4813be28da4512ccdc49687a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 26 Apr 2016 10:24:43 +0900 Subject: [PATCH 094/141] Revise the using-pepper-flash-plugin.md --- docs/tutorial/using-pepper-flash-plugin.md | 28 ++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/docs/tutorial/using-pepper-flash-plugin.md b/docs/tutorial/using-pepper-flash-plugin.md index cdb4d04ad082..de7c7001cf36 100644 --- a/docs/tutorial/using-pepper-flash-plugin.md +++ b/docs/tutorial/using-pepper-flash-plugin.md @@ -1,6 +1,6 @@ # Using Pepper Flash Plugin -Electron now supports the Pepper Flash plugin. To use the Pepper Flash plugin in +Electron 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. @@ -11,14 +11,11 @@ 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. -_**Attention:** On windows, Pepper Flash plugin is win32 and it won't work with Electron x64 version. -
Get win32 version from [Electron Releases](https://github.com/electron/electron/releases)_ - ## 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`. +before the app ready event. Also, turn on `plugins` option of `BrowserWindow`. For example: ```javascript @@ -33,11 +30,10 @@ app.commandLine.appendSwitch('ppapi-flash-version', '17.0.0.169'); app.on('ready', function() { mainWindow = new BrowserWindow({ - 'width': 800, - 'height': 600, - // web-preferences is deprecated. Use webPreferences instead. - 'webPreferences': { - 'plugins': true + width: 800, + height: 600, + webPreferences: { + plugins: true } }); mainWindow.loadURL('file://' + __dirname + '/index.html'); @@ -45,8 +41,6 @@ app.on('ready', function() { }); ``` -_**Attention:** You can check if Flash dll was loaded by running `navigator.plugins` on the Console (although you can't know if the plugin's path is correct)_ - ## Enable Flash Plugin in a `` Tag Add `plugins` attribute to `` tag. @@ -54,3 +48,13 @@ Add `plugins` attribute to `` tag. ```html ``` + +## Troubleshooting + +You can check if Pepper Flash plugin was loaded by inspecting +`navigator.plugins` in the console of devtools (although you can't know if the +plugin's path is correct). + +The architecture of Pepper Flash plugin has to match Electron's one. On Windows, +a common error is to use 32bit version of Flash plugin against 64bit version of +Electron. From 315cd9d2c89c6ad68f50e070a1110a5b28ea88a0 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Tue, 26 Apr 2016 01:35:34 +1000 Subject: [PATCH 095/141] Emit an error if `quitAndInstall` is called without an update being available --- atom/browser/auto_updater_mac.mm | 21 +++++++++++++++---- .../api/auto-updater/auto-updater-win.js | 5 +++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/atom/browser/auto_updater_mac.mm b/atom/browser/auto_updater_mac.mm index a55cdd281265..5f9814fd3474 100644 --- a/atom/browser/auto_updater_mac.mm +++ b/atom/browser/auto_updater_mac.mm @@ -22,6 +22,12 @@ SQRLUpdater* g_updater = nil; } // namespace +namespace { + +bool g_update_available = false; + +} + // static void AutoUpdater::SetFeedURL(const std::string& feed) { if (g_updater == nil) { @@ -69,6 +75,7 @@ void AutoUpdater::CheckForUpdates() { take:1] subscribeNext:^(SQRLDownloadedUpdate *downloadedUpdate) { if (downloadedUpdate) { + g_update_available = true; SQRLUpdate* update = downloadedUpdate.update; // There is a new update that has been downloaded. delegate->OnUpdateDownloaded( @@ -77,6 +84,7 @@ void AutoUpdater::CheckForUpdates() { base::Time::FromDoubleT(update.releaseDate.timeIntervalSince1970), base::SysNSStringToUTF8(update.updateURL.absoluteString)); } else { + g_update_available = false; // When the completed event is sent with no update, then we know there // is no update available. delegate->OnUpdateNotAvailable(); @@ -89,11 +97,16 @@ void AutoUpdater::CheckForUpdates() { } void AutoUpdater::QuitAndInstall() { - [[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) { - Delegate* delegate = AutoUpdater::GetDelegate(); + if (g_update_available) { + [[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) { + Delegate* delegate = AutoUpdater::GetDelegate(); + if (delegate) + delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription)); + }]; + } else { if (delegate) - delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription)); - }]; + delegate->OnError("No update available, can't quit and install"); + } } } // namespace auto_updater diff --git a/lib/browser/api/auto-updater/auto-updater-win.js b/lib/browser/api/auto-updater/auto-updater-win.js index 896b9ffce9d2..5b1127027e9d 100644 --- a/lib/browser/api/auto-updater/auto-updater-win.js +++ b/lib/browser/api/auto-updater/auto-updater-win.js @@ -12,6 +12,9 @@ function AutoUpdater () { util.inherits(AutoUpdater, EventEmitter) AutoUpdater.prototype.quitAndInstall = function () { + if (!this.updateAvailable) { + return this.emitError('No update available, can\'t quit and install') + } squirrelUpdate.processStart() return app.quit() } @@ -33,8 +36,10 @@ AutoUpdater.prototype.checkForUpdates = function () { return this.emitError(error) } if (update == null) { + this.updateAvailable = false return this.emit('update-not-available') } + this.updateAvailable = true this.emit('update-available') squirrelUpdate.update(this.updateURL, (error) => { var date, releaseNotes, version From f081c77422fff1eddc6901a73519e6426686facf Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 26 Apr 2016 11:15:36 +0900 Subject: [PATCH 096/141] Fix compilation error --- atom/browser/auto_updater_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/auto_updater_mac.mm b/atom/browser/auto_updater_mac.mm index 5f9814fd3474..9af920f59299 100644 --- a/atom/browser/auto_updater_mac.mm +++ b/atom/browser/auto_updater_mac.mm @@ -97,9 +97,9 @@ void AutoUpdater::CheckForUpdates() { } void AutoUpdater::QuitAndInstall() { + Delegate* delegate = AutoUpdater::GetDelegate(); if (g_update_available) { [[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) { - Delegate* delegate = AutoUpdater::GetDelegate(); if (delegate) delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription)); }]; From 06cf0406fe8ddcef3a500a689952c77fdfb9c9a8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 26 Apr 2016 16:10:27 +0900 Subject: [PATCH 097/141] Dereference remote objects with native code Previously we rely on the v8util.setDestructor to dereference the remote objects in JavaScript, however as documented in V8, it is forbidden to call V8 APIs in object's destructor (e.g. the weak callback), and doing so would result in crashs. This commit removes the JavaScript setDestructor method, and avoids doing the dereference work with V8. --- atom/common/api/atom_api_v8_util.cc | 13 ++-- atom/common/api/object_life_monitor.cc | 29 +++----- atom/common/api/object_life_monitor.h | 16 ++--- atom/common/api/remote_callback_freer.cc | 70 +++++++++++++++++++ atom/common/api/remote_callback_freer.h | 44 ++++++++++++ atom/common/api/remote_object_freer.cc | 63 +++++++++++++++++ atom/common/api/remote_object_freer.h | 32 +++++++++ .../content_converter.cc | 13 ++++ .../content_converter.h | 2 + filenames.gypi | 4 ++ lib/browser/rpc-server.js | 43 +++++++----- lib/renderer/api/remote.js | 4 +- 12 files changed, 272 insertions(+), 61 deletions(-) create mode 100644 atom/common/api/remote_callback_freer.cc create mode 100644 atom/common/api/remote_callback_freer.h create mode 100644 atom/common/api/remote_object_freer.cc create mode 100644 atom/common/api/remote_object_freer.h diff --git a/atom/common/api/atom_api_v8_util.cc b/atom/common/api/atom_api_v8_util.cc index 0ebd939398f1..109f9f0f36c2 100644 --- a/atom/common/api/atom_api_v8_util.cc +++ b/atom/common/api/atom_api_v8_util.cc @@ -4,7 +4,9 @@ #include -#include "atom/common/api/object_life_monitor.h" +#include "atom/common/api/remote_callback_freer.h" +#include "atom/common/api/remote_object_freer.h" +#include "atom/common/native_mate_converters/content_converter.h" #include "atom/common/node_includes.h" #include "native_mate/dictionary.h" #include "v8/include/v8-profiler.h" @@ -51,12 +53,6 @@ int32_t GetObjectHash(v8::Local object) { return object->GetIdentityHash(); } -void SetDestructor(v8::Isolate* isolate, - v8::Local object, - v8::Local callback) { - atom::ObjectLifeMonitor::BindTo(isolate, object, callback); -} - void TakeHeapSnapshot(v8::Isolate* isolate) { isolate->GetHeapProfiler()->TakeHeapSnapshot(); } @@ -68,8 +64,9 @@ void Initialize(v8::Local exports, v8::Local unused, dict.SetMethod("setHiddenValue", &SetHiddenValue); dict.SetMethod("deleteHiddenValue", &DeleteHiddenValue); dict.SetMethod("getObjectHash", &GetObjectHash); - dict.SetMethod("setDestructor", &SetDestructor); dict.SetMethod("takeHeapSnapshot", &TakeHeapSnapshot); + dict.SetMethod("setRemoteCallbackFreer", &atom::RemoteCallbackFreer::BindTo); + dict.SetMethod("setRemoteObjectFreer", &atom::RemoteObjectFreer::BindTo); } } // namespace diff --git a/atom/common/api/object_life_monitor.cc b/atom/common/api/object_life_monitor.cc index 916ad8a5177a..ffcc0d718420 100644 --- a/atom/common/api/object_life_monitor.cc +++ b/atom/common/api/object_life_monitor.cc @@ -10,30 +10,28 @@ namespace atom { -// static -void ObjectLifeMonitor::BindTo(v8::Isolate* isolate, - v8::Local target, - v8::Local destructor) { - new ObjectLifeMonitor(isolate, target, destructor); -} - ObjectLifeMonitor::ObjectLifeMonitor(v8::Isolate* isolate, - v8::Local target, - v8::Local destructor) + v8::Local target) : isolate_(isolate), context_(isolate, isolate->GetCurrentContext()), target_(isolate, target), - destructor_(isolate, destructor), weak_ptr_factory_(this) { target_.SetWeak(this, OnObjectGC, v8::WeakCallbackType::kParameter); } +ObjectLifeMonitor::~ObjectLifeMonitor() { + if (target_.IsEmpty()) + return; + target_.ClearWeak(); + target_.Reset(); +} + // static void ObjectLifeMonitor::OnObjectGC( const v8::WeakCallbackInfo& data) { ObjectLifeMonitor* self = data.GetParameter(); self->target_.Reset(); - self->RunCallback(); + self->RunDestructor(); data.SetSecondPassCallback(Free); } @@ -43,13 +41,4 @@ void ObjectLifeMonitor::Free( delete data.GetParameter(); } -void ObjectLifeMonitor::RunCallback() { - v8::HandleScope handle_scope(isolate_); - v8::Local context = v8::Local::New( - isolate_, context_); - v8::Context::Scope context_scope(context); - v8::Local::New(isolate_, destructor_)->Call( - context->Global(), 0, nullptr); -} - } // namespace atom diff --git a/atom/common/api/object_life_monitor.h b/atom/common/api/object_life_monitor.h index 82d923fcedb7..59d5fdb5cffd 100644 --- a/atom/common/api/object_life_monitor.h +++ b/atom/common/api/object_life_monitor.h @@ -12,25 +12,19 @@ namespace atom { class ObjectLifeMonitor { - public: - static void BindTo(v8::Isolate* isolate, - v8::Local target, - v8::Local destructor); + protected: + ObjectLifeMonitor(v8::Isolate* isolate, v8::Local target); + virtual ~ObjectLifeMonitor(); + + virtual void RunDestructor() = 0; private: - ObjectLifeMonitor(v8::Isolate* isolate, - v8::Local target, - v8::Local destructor); - static void OnObjectGC(const v8::WeakCallbackInfo& data); static void Free(const v8::WeakCallbackInfo& data); - void RunCallback(); - v8::Isolate* isolate_; v8::Global context_; v8::Global target_; - v8::Global destructor_; base::WeakPtrFactory weak_ptr_factory_; diff --git a/atom/common/api/remote_callback_freer.cc b/atom/common/api/remote_callback_freer.cc new file mode 100644 index 000000000000..24d2897ae756 --- /dev/null +++ b/atom/common/api/remote_callback_freer.cc @@ -0,0 +1,70 @@ +// 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/common/api/remote_callback_freer.h" + +#include "atom/common/api/api_messages.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" + +namespace atom { + +// static +void RemoteCallbackFreer::BindTo(v8::Isolate* isolate, + v8::Local target, + int object_id, + content::WebContents* web_contents) { + new RemoteCallbackFreer(isolate, target, object_id, web_contents); +} + +RemoteCallbackFreer::RemoteCallbackFreer(v8::Isolate* isolate, + v8::Local target, + int object_id, + content::WebContents* web_contents) + : ObjectLifeMonitor(isolate, target), + content::WebContentsObserver(web_contents), + web_contents_(web_contents), + renderer_process_id_(GetRendererProcessID()), + object_id_(object_id) { +} + +RemoteCallbackFreer::~RemoteCallbackFreer() { +} + +void RemoteCallbackFreer::RunDestructor() { + if (!web_contents_) + return; + + if (renderer_process_id_ == GetRendererProcessID()) { + base::string16 channel = + base::ASCIIToUTF16("ELECTRON_RENDERER_RELEASE_CALLBACK"); + base::ListValue args; + args.AppendInteger(object_id_); + Send(new AtomViewMsg_Message(routing_id(), channel, args)); + } + web_contents_ = nullptr; +} + +void RemoteCallbackFreer::WebContentsDestroyed() { + if (!web_contents_) + return; + + web_contents_ = nullptr; + delete this; +} + +int RemoteCallbackFreer::GetRendererProcessID() { + if (!web_contents_) + return -1; + + auto process = web_contents()->GetRenderProcessHost(); + if (!process) + return -1; + + return process->GetID(); +} + +} // namespace atom diff --git a/atom/common/api/remote_callback_freer.h b/atom/common/api/remote_callback_freer.h new file mode 100644 index 000000000000..5c160c2d8ec4 --- /dev/null +++ b/atom/common/api/remote_callback_freer.h @@ -0,0 +1,44 @@ +// 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_COMMON_API_REMOTE_CALLBACK_FREER_H_ +#define ATOM_COMMON_API_REMOTE_CALLBACK_FREER_H_ +#include "atom/common/api/object_life_monitor.h" +#include "content/public/browser/web_contents_observer.h" + +namespace atom { + +class RemoteCallbackFreer : public ObjectLifeMonitor, + public content::WebContentsObserver { + public: + static void BindTo(v8::Isolate* isolate, + v8::Local target, + int object_id, + content::WebContents* web_conents); + + protected: + RemoteCallbackFreer(v8::Isolate* isolate, + v8::Local target, + int object_id, + content::WebContents* web_conents); + ~RemoteCallbackFreer() override; + + void RunDestructor() override; + + // content::WebContentsObserver: + void WebContentsDestroyed() override; + + private: + int GetRendererProcessID(); + + content::WebContents* web_contents_; + int renderer_process_id_; + int object_id_; + + DISALLOW_COPY_AND_ASSIGN(RemoteCallbackFreer); +}; + +} // namespace atom + +#endif // ATOM_COMMON_API_REMOTE_CALLBACK_FREER_H_ diff --git a/atom/common/api/remote_object_freer.cc b/atom/common/api/remote_object_freer.cc new file mode 100644 index 000000000000..1762f1d1e068 --- /dev/null +++ b/atom/common/api/remote_object_freer.cc @@ -0,0 +1,63 @@ +// 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/common/api/remote_object_freer.h" + +#include "atom/common/api/api_messages.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "content/public/renderer/render_view.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "third_party/WebKit/public/web/WebView.h" + +using blink::WebLocalFrame; +using blink::WebView; + +namespace atom { + +namespace { + +content::RenderView* GetCurrentRenderView() { + WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext(); + if (!frame) + return nullptr; + + WebView* view = frame->view(); + if (!view) + return nullptr; // can happen during closing. + + return content::RenderView::FromWebView(view); +} + +} // namespace + +// static +void RemoteObjectFreer::BindTo( + v8::Isolate* isolate, v8::Local target, int object_id) { + new RemoteObjectFreer(isolate, target, object_id); +} + +RemoteObjectFreer::RemoteObjectFreer( + v8::Isolate* isolate, v8::Local target, int object_id) + : ObjectLifeMonitor(isolate, target), + object_id_(object_id) { +} + +RemoteObjectFreer::~RemoteObjectFreer() { +} + +void RemoteObjectFreer::RunDestructor() { + content::RenderView* render_view = GetCurrentRenderView(); + if (!render_view) + return; + + base::string16 channel = base::ASCIIToUTF16("ipc-message"); + base::ListValue args; + args.AppendString("ELECTRON_BROWSER_DEREFERENCE"); + args.AppendInteger(object_id_); + render_view->Send( + new AtomViewHostMsg_Message(render_view->GetRoutingID(), channel, args)); +} + +} // namespace atom diff --git a/atom/common/api/remote_object_freer.h b/atom/common/api/remote_object_freer.h new file mode 100644 index 000000000000..c2b5d8b7d30b --- /dev/null +++ b/atom/common/api/remote_object_freer.h @@ -0,0 +1,32 @@ +// 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_COMMON_API_REMOTE_OBJECT_FREER_H_ +#define ATOM_COMMON_API_REMOTE_OBJECT_FREER_H_ + +#include "atom/common/api/object_life_monitor.h" + +namespace atom { + +class RemoteObjectFreer : public ObjectLifeMonitor { + public: + static void BindTo( + v8::Isolate* isolate, v8::Local target, int object_id); + + protected: + RemoteObjectFreer( + v8::Isolate* isolate, v8::Local target, int object_id); + ~RemoteObjectFreer() override; + + void RunDestructor() override; + + private: + int object_id_; + + DISALLOW_COPY_AND_ASSIGN(RemoteObjectFreer); +}; + +} // namespace atom + +#endif // ATOM_COMMON_API_REMOTE_OBJECT_FREER_H_ diff --git a/atom/common/native_mate_converters/content_converter.cc b/atom/common/native_mate_converters/content_converter.cc index 7e7cd9bd1ff1..154dcf88ce37 100644 --- a/atom/common/native_mate_converters/content_converter.cc +++ b/atom/common/native_mate_converters/content_converter.cc @@ -180,4 +180,17 @@ v8::Local Converter::ToV8( return atom::api::WebContents::CreateFrom(isolate, val).ToV8(); } +// static +bool Converter::FromV8( + v8::Isolate* isolate, + v8::Local val, + content::WebContents** out) { + atom::api::WebContents* web_contents = nullptr; + if (!ConvertFromV8(isolate, val, &web_contents) || !web_contents) + return false; + + *out = web_contents->web_contents(); + return true; +} + } // namespace mate diff --git a/atom/common/native_mate_converters/content_converter.h b/atom/common/native_mate_converters/content_converter.h index b1a42b6897ca..f2e7211ce5d1 100644 --- a/atom/common/native_mate_converters/content_converter.h +++ b/atom/common/native_mate_converters/content_converter.h @@ -57,6 +57,8 @@ template<> struct Converter { static v8::Local ToV8(v8::Isolate* isolate, content::WebContents* val); + static bool FromV8(v8::Isolate* isolate, v8::Local val, + content::WebContents** out); }; } // namespace mate diff --git a/filenames.gypi b/filenames.gypi index c3eca34528df..1c2139497567 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -303,6 +303,10 @@ 'atom/common/api/locker.h', 'atom/common/api/object_life_monitor.cc', 'atom/common/api/object_life_monitor.h', + 'atom/common/api/remote_callback_freer.cc', + 'atom/common/api/remote_callback_freer.h', + 'atom/common/api/remote_object_freer.cc', + 'atom/common/api/remote_object_freer.h', 'atom/common/asar/archive.cc', 'atom/common/asar/archive.h', 'atom/common/asar/asar_util.cc', diff --git a/lib/browser/rpc-server.js b/lib/browser/rpc-server.js index ca193b4115e8..1dff5fdb8ade 100644 --- a/lib/browser/rpc-server.js +++ b/lib/browser/rpc-server.js @@ -12,8 +12,19 @@ const FUNCTION_PROPERTIES = [ ] // The remote functions in renderer processes. -// (webContentsId) => {id: Function} -let rendererFunctions = {} +// id => Function +let rendererFunctions = new IDWeakMap() + +// Merge two IDs together. +let mergeIds = function (webContentsId, metaId) { + const PADDING_BITS = 20 + if ((webContentsId << PADDING_BITS) < 0) { + throw new Error(`webContents ID is too large: ${webContentsId}`) + } else if (metaId > (1 << PADDING_BITS)) { + throw new Error(`Object ID is too large: ${metaId}`) + } + return (webContentsId << PADDING_BITS) + metaId +} // Return the description of object's members: let getObjectMembers = function (object) { @@ -165,32 +176,26 @@ var unwrapArgs = function (sender, args) { return returnValue } case 'function': { + // Merge webContentsId and meta.id, since meta.id can be the same in + // different webContents. + const webContentsId = sender.getId() + const objectId = mergeIds(webContentsId, meta.id) + // Cache the callbacks in renderer. - 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 (rendererFunctions.has(objectId)) { + return rendererFunctions.get(objectId) } - if (callbacks.has(meta.id)) return callbacks.get(meta.id) - let callIntoRenderer = function (...args) { - if ((webContentsId in rendererFunctions) && !sender.isDestroyed()) { + if (!sender.isDestroyed() && webContentsId === sender.getId()) { sender.send('ELECTRON_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}.`) } } - v8Util.setDestructor(callIntoRenderer, function () { - if ((webContentsId in rendererFunctions) && !sender.isDestroyed()) { - sender.send('ELECTRON_RENDERER_RELEASE_CALLBACK', meta.id) - } - }) - callbacks.set(meta.id, callIntoRenderer) + + v8Util.setRemoteCallbackFreer(callIntoRenderer, meta.id, sender) + rendererFunctions.set(objectId, callIntoRenderer) return callIntoRenderer } default: diff --git a/lib/renderer/api/remote.js b/lib/renderer/api/remote.js index d15ebd717ec5..6631ea22575a 100644 --- a/lib/renderer/api/remote.js +++ b/lib/renderer/api/remote.js @@ -210,9 +210,7 @@ let metaToValue = function (meta) { // Track delegate object's life time, and tell the browser to clean up // when the object is GCed. - v8Util.setDestructor(ret, function () { - ipcRenderer.send('ELECTRON_BROWSER_DEREFERENCE', meta.id) - }) + v8Util.setRemoteObjectFreer(ret, meta.id) // Remember object's id. v8Util.setHiddenValue(ret, 'atomId', meta.id) From d9778413e170b70ba52a30eb675dfb8363bf407d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 26 Apr 2016 16:30:26 +0900 Subject: [PATCH 098/141] Should also destory RemoteCallbackFreer when page is reloaded --- atom/common/api/remote_callback_freer.cc | 2 +- atom/common/api/remote_callback_freer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/common/api/remote_callback_freer.cc b/atom/common/api/remote_callback_freer.cc index 24d2897ae756..917128baf9ef 100644 --- a/atom/common/api/remote_callback_freer.cc +++ b/atom/common/api/remote_callback_freer.cc @@ -48,7 +48,7 @@ void RemoteCallbackFreer::RunDestructor() { web_contents_ = nullptr; } -void RemoteCallbackFreer::WebContentsDestroyed() { +void RemoteCallbackFreer::RenderViewDeleted(content::RenderViewHost*) { if (!web_contents_) return; diff --git a/atom/common/api/remote_callback_freer.h b/atom/common/api/remote_callback_freer.h index 5c160c2d8ec4..43a4a215a4d2 100644 --- a/atom/common/api/remote_callback_freer.h +++ b/atom/common/api/remote_callback_freer.h @@ -27,7 +27,7 @@ class RemoteCallbackFreer : public ObjectLifeMonitor, void RunDestructor() override; // content::WebContentsObserver: - void WebContentsDestroyed() override; + void RenderViewDeleted(content::RenderViewHost*) override; private: int GetRendererProcessID(); From 4f21a50d235db3b2cc32b4135a0bc20f20951b83 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 26 Apr 2016 16:31:56 +0900 Subject: [PATCH 099/141] Remove duplicated converter for content::WebContents --- atom/browser/api/atom_api_web_view_manager.cc | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/atom/browser/api/atom_api_web_view_manager.cc b/atom/browser/api/atom_api_web_view_manager.cc index e57c5ffb6bb4..f06c1105526e 100644 --- a/atom/browser/api/atom_api_web_view_manager.cc +++ b/atom/browser/api/atom_api_web_view_manager.cc @@ -2,9 +2,9 @@ // 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_web_contents.h" #include "atom/browser/web_contents_preferences.h" #include "atom/browser/web_view_manager.h" +#include "atom/common/native_mate_converters/content_converter.h" #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/node_includes.h" #include "content/public/browser/browser_context.h" @@ -12,22 +12,6 @@ using atom::WebContentsPreferences; -namespace mate { - -template<> -struct Converter { - static bool FromV8(v8::Isolate* isolate, v8::Local val, - content::WebContents** out) { - atom::api::WebContents* contents; - if (!Converter::FromV8(isolate, val, &contents)) - return false; - *out = contents->web_contents(); - return true; - } -}; - -} // namespace mate - namespace { atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) { From 76a954077d7ed12592c0a8dc62093212dfddfac8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 26 Apr 2016 16:37:46 +0900 Subject: [PATCH 100/141] Simplify RemoteCallbackFreer --- atom/common/api/remote_callback_freer.cc | 35 ++++-------------------- atom/common/api/remote_callback_freer.h | 4 --- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/atom/common/api/remote_callback_freer.cc b/atom/common/api/remote_callback_freer.cc index 917128baf9ef..7bc377efc5e7 100644 --- a/atom/common/api/remote_callback_freer.cc +++ b/atom/common/api/remote_callback_freer.cc @@ -7,8 +7,6 @@ #include "atom/common/api/api_messages.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/web_contents.h" namespace atom { @@ -26,8 +24,6 @@ RemoteCallbackFreer::RemoteCallbackFreer(v8::Isolate* isolate, content::WebContents* web_contents) : ObjectLifeMonitor(isolate, target), content::WebContentsObserver(web_contents), - web_contents_(web_contents), - renderer_process_id_(GetRendererProcessID()), object_id_(object_id) { } @@ -35,36 +31,17 @@ RemoteCallbackFreer::~RemoteCallbackFreer() { } void RemoteCallbackFreer::RunDestructor() { - if (!web_contents_) - return; + base::string16 channel = + base::ASCIIToUTF16("ELECTRON_RENDERER_RELEASE_CALLBACK"); + base::ListValue args; + args.AppendInteger(object_id_); + Send(new AtomViewMsg_Message(routing_id(), channel, args)); - if (renderer_process_id_ == GetRendererProcessID()) { - base::string16 channel = - base::ASCIIToUTF16("ELECTRON_RENDERER_RELEASE_CALLBACK"); - base::ListValue args; - args.AppendInteger(object_id_); - Send(new AtomViewMsg_Message(routing_id(), channel, args)); - } - web_contents_ = nullptr; + Observe(nullptr); } void RemoteCallbackFreer::RenderViewDeleted(content::RenderViewHost*) { - if (!web_contents_) - return; - - web_contents_ = nullptr; delete this; } -int RemoteCallbackFreer::GetRendererProcessID() { - if (!web_contents_) - return -1; - - auto process = web_contents()->GetRenderProcessHost(); - if (!process) - return -1; - - return process->GetID(); -} - } // namespace atom diff --git a/atom/common/api/remote_callback_freer.h b/atom/common/api/remote_callback_freer.h index 43a4a215a4d2..8fe80c8d4774 100644 --- a/atom/common/api/remote_callback_freer.h +++ b/atom/common/api/remote_callback_freer.h @@ -30,10 +30,6 @@ class RemoteCallbackFreer : public ObjectLifeMonitor, void RenderViewDeleted(content::RenderViewHost*) override; private: - int GetRendererProcessID(); - - content::WebContents* web_contents_; - int renderer_process_id_; int object_id_; DISALLOW_COPY_AND_ASSIGN(RemoteCallbackFreer); From 21af03d71ad4dad9bd4a15996884b7a7b7869129 Mon Sep 17 00:00:00 2001 From: Daniel Pham Date: Mon, 25 Apr 2016 23:23:16 -0400 Subject: [PATCH 101/141] :apple: Fix converting from windows virtual keycode back to mac keycode --- atom/browser/ui/accelerator_util_mac.mm | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/atom/browser/ui/accelerator_util_mac.mm b/atom/browser/ui/accelerator_util_mac.mm index be631b021249..d3395884c97f 100644 --- a/atom/browser/ui/accelerator_util_mac.mm +++ b/atom/browser/ui/accelerator_util_mac.mm @@ -13,12 +13,6 @@ namespace accelerator_util { void SetPlatformAccelerator(ui::Accelerator* accelerator) { unichar character; unichar characterIgnoringModifiers; - ui::MacKeyCodeForWindowsKeyCode(accelerator->key_code(), - 0, - &character, - &characterIgnoringModifiers); - NSString* characters = - [[[NSString alloc] initWithCharacters:&character length:1] autorelease]; NSUInteger modifiers = (accelerator->IsCtrlDown() ? NSControlKeyMask : 0) | @@ -26,6 +20,18 @@ void SetPlatformAccelerator(ui::Accelerator* accelerator) { (accelerator->IsAltDown() ? NSAlternateKeyMask : 0) | (accelerator->IsShiftDown() ? NSShiftKeyMask : 0); + ui::MacKeyCodeForWindowsKeyCode(accelerator->key_code(), + modifiers, + &character, + &characterIgnoringModifiers); + + if (character != characterIgnoringModifiers) { + modifiers ^= NSShiftKeyMask; + } + + NSString* characters = + [[[NSString alloc] initWithCharacters:&character length:1] autorelease]; + scoped_ptr platform_accelerator( new ui::PlatformAcceleratorCocoa(characters, modifiers)); accelerator->set_platform_accelerator(std::move(platform_accelerator)); From b1c0e7e2ab5fa3c7b680ec626ad1a14575ac3db6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 26 Apr 2016 10:28:04 -0700 Subject: [PATCH 102/141] web-frame -> webFrame --- docs/api/web-frame.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/web-frame.md b/docs/api/web-frame.md index b2d8aa0f41eb..4b7d04b6f0ff 100644 --- a/docs/api/web-frame.md +++ b/docs/api/web-frame.md @@ -12,7 +12,7 @@ webFrame.setZoomFactor(2); ## Methods -The `web-frame` module has the following methods: +The `webFrame` module has the following methods: ### `webFrame.setZoomFactor(factor)` From 4080442f8006c5e839adf132b25aa5aa1e5da309 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 26 Apr 2016 10:28:20 -0700 Subject: [PATCH 103/141] content-tracing -> contentTracing --- 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 a9414d348764..e347790b63f4 100644 --- a/docs/api/content-tracing.md +++ b/docs/api/content-tracing.md @@ -28,7 +28,7 @@ contentTracing.startRecording(options, function() { ## Methods -The `content-tracing` module has the following methods: +The `contentTracing` module has the following methods: ### `contentTracing.getCategories(callback)` From f3c3042debd0ff59ebb435cf9d4d6311d1e12bb0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 27 Apr 2016 19:55:01 +0900 Subject: [PATCH 104/141] Do not run clean in cibuild --- script/cibuild | 4 ---- 1 file changed, 4 deletions(-) diff --git a/script/cibuild b/script/cibuild index fda5817b6b84..59437837aa16 100755 --- a/script/cibuild +++ b/script/cibuild @@ -53,8 +53,6 @@ def main(): if PLATFORM == 'linux': os.environ['DISPLAY'] = ':99.0' - run_script('clean.py') - # CI's npm is not reliable. npm = 'npm.cmd' if PLATFORM == 'win32' else 'npm' execute([npm, 'install', 'npm@2.12.1']) @@ -81,8 +79,6 @@ def main(): if PLATFORM != 'win32' and target_arch == 'x64': run_script('test.py', ['--ci']) - run_script('clean.py') - def run_script(script, args=[]): sys.stderr.write('\nRunning ' + script +'\n') From 4435cdc576e27c5f6fa4701232e95f2024655319 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 27 Apr 2016 21:46:44 +0900 Subject: [PATCH 105/141] Create user_data_dir before creating singleton lock --- chromium_src/chrome/browser/process_singleton_posix.cc | 3 +++ chromium_src/chrome/browser/process_singleton_win.cc | 3 +++ 2 files changed, 6 insertions(+) diff --git a/chromium_src/chrome/browser/process_singleton_posix.cc b/chromium_src/chrome/browser/process_singleton_posix.cc index c583db0162a0..5c26d7b6157a 100644 --- a/chromium_src/chrome/browser/process_singleton_posix.cc +++ b/chromium_src/chrome/browser/process_singleton_posix.cc @@ -717,6 +717,9 @@ ProcessSingleton::ProcessSingleton( const NotificationCallback& notification_callback) : notification_callback_(notification_callback), current_pid_(base::GetCurrentProcId()) { + // The user_data_dir may have not been created yet. + base::CreateDirectoryAndGetError(user_data_dir, nullptr); + socket_path_ = user_data_dir.Append(kSingletonSocketFilename); lock_path_ = user_data_dir.Append(kSingletonLockFilename); cookie_path_ = user_data_dir.Append(kSingletonCookieFilename); diff --git a/chromium_src/chrome/browser/process_singleton_win.cc b/chromium_src/chrome/browser/process_singleton_win.cc index fd4c22e7405c..b488ad457674 100644 --- a/chromium_src/chrome/browser/process_singleton_win.cc +++ b/chromium_src/chrome/browser/process_singleton_win.cc @@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/process/process.h" #include "base/process/process_info.h" #include "base/strings/string_number_conversions.h" @@ -190,6 +191,8 @@ ProcessSingleton::ProcessSingleton( user_data_dir_(user_data_dir), should_kill_remote_process_callback_( base::Bind(&TerminateAppWithError)) { + // The user_data_dir may have not been created yet. + base::CreateDirectoryAndGetError(user_data_dir, nullptr); } ProcessSingleton::~ProcessSingleton() { From 46208b5b3efa881c66b646ccaf116667fbdd83eb Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Wed, 27 Apr 2016 20:00:31 +0530 Subject: [PATCH 106/141] session: dont attach download dialog to deleted webContents window --- atom/browser/api/atom_api_session.cc | 2 +- atom/browser/atom_download_manager_delegate.cc | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index ec4e2aebe4c2..45281c4112b2 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -315,7 +315,7 @@ void Session::OnDownloadCreated(content::DownloadManager* manager, bool prevent_default = Emit( "will-download", DownloadItem::Create(isolate(), item), - api::WebContents::CreateFrom(isolate(), web_contents)); + web_contents); if (prevent_default) { item->Cancel(true); item->Remove(); diff --git a/atom/browser/atom_download_manager_delegate.cc b/atom/browser/atom_download_manager_delegate.cc index 16c0cf708b85..295747a33c4e 100644 --- a/atom/browser/atom_download_manager_delegate.cc +++ b/atom/browser/atom_download_manager_delegate.cc @@ -70,7 +70,9 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated( return; NativeWindow* window = nullptr; - auto relay = NativeWindowRelay::FromWebContents(item->GetWebContents()); + content::WebContents* web_contents = item->GetWebContents(); + auto relay = web_contents ? NativeWindowRelay::FromWebContents(web_contents) + : nullptr; if (relay) window = relay->window.get(); From bfae925b0ffc4cb58656f5ade92e744fb0a5a248 Mon Sep 17 00:00:00 2001 From: StoneStoneStone Date: Wed, 27 Apr 2016 22:49:07 +0800 Subject: [PATCH 107/141] Translate `testing-on-headless-ci.md` to Chinese --- .../zh-CN/tutorial/testing-on-headless-ci.md | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 docs-translations/zh-CN/tutorial/testing-on-headless-ci.md diff --git a/docs-translations/zh-CN/tutorial/testing-on-headless-ci.md b/docs-translations/zh-CN/tutorial/testing-on-headless-ci.md new file mode 100644 index 000000000000..7da98b0a1a64 --- /dev/null +++ b/docs-translations/zh-CN/tutorial/testing-on-headless-ci.md @@ -0,0 +1,51 @@ +# Testing Electron with headless CI Systems (Travis CI, Jenkins) + +Electron基于Chromium,所以需要一个显示驱动使其运转。如果Chromium无法找到一个显示驱动, +ELectron 会启动失败,因此无论你如何去运行它,Electron不会执行你的任何测试。在Travis, Circle, +Jenkins 或者类似的系统上测试基于Electron的应用时,需要进行一些配置。本质上,我们需要使用一个 +虚拟的显示驱动。 + +## Configuring the Virtual Display Server + +首先安装[Xvfb](https://en.wikipedia.org/wiki/Xvfb)。 +这是一个虚拟的帧缓冲,实现了X11显示服务协议,所有的图形操作都在内存中表现,而不需要显示在 +任何屏幕输出设备上。这正是我们所需要的。 + +然后创建一个虚拟的xvfb屏幕并且导出一个指向他的名为`DISPLAY`的环境变量。Electron中的Chromium +会自动的去寻找`$DISPLAY`,所以你的应用不需要再去进行配置。这一步可以通过Paul Betts's的 +[xvfb-maybe](https://github.com/paulcbetts/xvfb-maybe)实现自动化:如果系统需要,在`xvfb-maybe`前加上你的测试命令 +然后这个小工具会自动的设置xvfb。在Windows或者Mac OS X系统下,它不会执行任何东西。 + +``` +## 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 + +在 Travis 上, 你的 `.travis.yml` 应该和下面的代码相似: + +``` +addons: + apt: + packages: + - xvfb + +install: + - export DISPLAY=':99.0' + - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & +``` + +### Jenkins + +Jenkins下, 有一个可用的[Xvfb插件](https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin). + +### Circle CI + +Circle CI 是非常棒的而且有xvfb,`$DISPLAY`也[已经搭建,所以不需要再进行设置](https://circleci.com/docs/environment#browsers)。 + +### AppVeyor + +AppVeyor运行于Windows上,支持 Selenium, Chromium, Electron 以及一些类似的工具,开箱即用,无需配置。 From 6dbd2ce243a6f01772bceed345239741ef0fbe01 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Wed, 27 Apr 2016 20:29:39 +0530 Subject: [PATCH 108/141] use DownloadItem to determine download initiator --- atom/browser/api/atom_api_session.cc | 7 ++----- atom/browser/api/save_page_handler.cc | 5 ----- atom/browser/api/save_page_handler.h | 2 -- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 45281c4112b2..39c435b723ea 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -9,9 +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_web_contents.h" #include "atom/browser/api/atom_api_web_request.h" -#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" @@ -306,8 +304,7 @@ Session::~Session() { void Session::OnDownloadCreated(content::DownloadManager* manager, content::DownloadItem* item) { - auto web_contents = item->GetWebContents(); - if (SavePageHandler::IsSavePageTypes(item->GetMimeType())) + if (item->IsSavePackageDownload()) return; v8::Locker locker(isolate()); @@ -315,7 +312,7 @@ void Session::OnDownloadCreated(content::DownloadManager* manager, bool prevent_default = Emit( "will-download", DownloadItem::Create(isolate(), item), - web_contents); + item->GetWebContents()); if (prevent_default) { item->Cancel(true); item->Remove(); diff --git a/atom/browser/api/save_page_handler.cc b/atom/browser/api/save_page_handler.cc index 1e5bc094cf63..e07ec3ac0abb 100644 --- a/atom/browser/api/save_page_handler.cc +++ b/atom/browser/api/save_page_handler.cc @@ -73,11 +73,6 @@ void SavePageHandler::Destroy(content::DownloadItem* item) { delete this; } -// static -bool SavePageHandler::IsSavePageTypes(const std::string& type) { - return type == "multipart/related" || type == "text/html"; -} - } // namespace api } // namespace atom diff --git a/atom/browser/api/save_page_handler.h b/atom/browser/api/save_page_handler.h index dd1692a8badc..951a9414e03f 100644 --- a/atom/browser/api/save_page_handler.h +++ b/atom/browser/api/save_page_handler.h @@ -37,8 +37,6 @@ class SavePageHandler : public content::DownloadManager::Observer, bool Handle(const base::FilePath& full_path, const content::SavePageType& save_type); - static bool IsSavePageTypes(const std::string& type); - private: void Destroy(content::DownloadItem* item); From df2141d9e69da138b491122839780260e8548a80 Mon Sep 17 00:00:00 2001 From: Rita Zhang Date: Sun, 24 Apr 2016 22:17:01 -0700 Subject: [PATCH 109/141] :zap: Add API: IsDefaultProtocolClient --- atom/browser/api/atom_api_app.cc | 2 ++ atom/browser/browser.h | 3 +++ atom/browser/browser_linux.cc | 4 +++ atom/browser/browser_mac.mm | 24 +++++++++++++++++ atom/browser/browser_win.cc | 44 ++++++++++++++++++++++++++++++++ docs/api/app.md | 14 ++++++++++ 6 files changed, 91 insertions(+) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index ce20ce96deda..304e53a55540 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -451,6 +451,8 @@ void App::BuildPrototype( base::Bind(&Browser::ClearRecentDocuments, browser)) .SetMethod("setAppUserModelId", base::Bind(&Browser::SetAppUserModelID, browser)) + .SetMethod("isDefaultProtocolClient", + base::Bind(&Browser::IsDefaultProtocolClient, browser)) .SetMethod("setAsDefaultProtocolClient", base::Bind(&Browser::SetAsDefaultProtocolClient, browser)) .SetMethod("removeAsDefaultProtocolClient", diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 0f1dbe993118..8329b14bc2c4 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -82,6 +82,9 @@ class Browser : public WindowListObserver { // Set as default handler for a protocol. bool SetAsDefaultProtocolClient(const std::string& protocol); + // Query the current state of default handler for a protocol. + bool IsDefaultProtocolClient(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 6c7d4abaf645..d994bb4109bb 100644 --- a/atom/browser/browser_linux.cc +++ b/atom/browser/browser_linux.cc @@ -42,6 +42,10 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { return false; } +bool Browser::IsDefaultProtocolClient(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 11fd3aa6d357..c10369a2e7af 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -60,6 +60,30 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { return return_code == noErr; } +bool Browser::IsDefaultProtocolClient(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()]; + + CFStringRef bundle = + LSCopyDefaultHandlerForURLScheme(base::mac::NSToCFCast(protocol_ns)); + NSString* bundleId = static_cast( + base::mac::CFTypeRefToNSObjectAutorelease(bundle)); + if (!bundleId) + return false; + + // Ensure the comparison is case-insensitive + // as LS does not persist the case of the bundle id. + NSComparisonResult result = + [bundleId caseInsensitiveCompare:identifier]; + return result == NSOrderedSame; +} + void Browser::SetAppUserModelID(const base::string16& name) { } diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index 9531406f8cd4..7b1402ba2d2c 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -225,6 +225,50 @@ bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { return true; } +bool Browser::IsDefaultProtocolClient(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 exist, we can confirm that it is not set + return false; + + if (FAILED(commandKey.Open(root, cmdPath.c_str(), KEY_ALL_ACCESS))) + // Key doesn't exist, we can confirm that it is not set + return false; + + std::wstring keyVal; + if (FAILED(commandKey.ReadValue(L"", &keyVal))) + // Default value not set, we can confirm that it is not set + return false; + + std::wstring exePath(path.value()); + std::wstring exe = L"\"" + exePath + L"\" \"%1\""; + if (keyVal == exe) { + // Default value is the same as current file path + return true; + } else { + return false; + } +} + 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 0aca703ba51d..1f682933d233 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -384,6 +384,18 @@ This method checks if the current executable as the default handler for a protoc **Note:** On OS X, removing the app will automatically remove the app as the default protocol handler. +### `app.isDefaultProtocolClient(protocol)` _OS X_ _Windows_ + +* `protocol` String - The name of your protocol, without `://`. + +This method checks if the current executable is the default handler for a protocol +(aka URI scheme). If so, it will return true. Otherwise, it will return false. + +**Note:** On OS X, you can use this method to check if the app has been registered as the default protocol handler for a protocol. You can also verify this by checking `~/Library/Preferences/com.apple.LaunchServices.plist` on the OS X machine. +Please refer to [Apple's documentation][LSCopyDefaultHandlerForURLScheme] for details. + +The API uses the Windows Registry and LSCopyDefaultHandlerForURLScheme internally. + ### `app.setUserTasks(tasks)` _Windows_ * `tasks` Array - Array of `Task` objects @@ -556,3 +568,5 @@ Sets the `image` associated with this dock icon. [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 +[LSCopyDefaultHandlerForURLScheme]: +https://developer.apple.com/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme From 4e6b148eaa93034fb003e9060ef7fc149cf721bb Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Thu, 28 Apr 2016 01:54:08 +0530 Subject: [PATCH 110/141] webContents: fix executejavascript when called before page load --- lib/browser/api/web-contents.js | 6 ++++-- spec/api-browser-window-spec.js | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index dfacf6a02cf1..823351ebe116 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -117,9 +117,11 @@ let wrapWebContents = function (webContents) { hasUserGesture = false } if (this.getURL() && !this.isLoadingMainFrame()) { - return asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture) + asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture) } else { - return this.once('did-finish-load', asyncWebFrameMethods.bind(this, requestId, 'executeJavaScript', callback, code, hasUserGesture)) + this.once('did-finish-load', () => { + asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture) + }) } } diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 1110269e5de1..c364b916c3a4 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -870,6 +870,14 @@ describe('browser-window module', function () { }) w.loadURL(server.url) }) + + it('executes after page load', function (done) { + w.webContents.executeJavaScript(code, function(result) { + assert.equal(result, expected) + done() + }) + w.loadURL(server.url) + }) }) describe('deprecated options', function () { From d64e3784f4df22cde31c3cc924e02548581c685f Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Thu, 28 Apr 2016 02:02:14 +0530 Subject: [PATCH 111/141] renderer: fix desktop capture api not responding different subsequest calls --- atom/browser/api/atom_api_desktop_capturer.cc | 1 - spec/api-desktop-capturer-spec.js | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_desktop_capturer.cc b/atom/browser/api/atom_api_desktop_capturer.cc index cc978a40b399..9200a89224c2 100644 --- a/atom/browser/api/atom_api_desktop_capturer.cc +++ b/atom/browser/api/atom_api_desktop_capturer.cc @@ -89,7 +89,6 @@ void DesktopCapturer::OnSourceThumbnailChanged(int index) { bool DesktopCapturer::OnRefreshFinished() { Emit("finished", media_list_->GetSources()); - media_list_.reset(); return false; } diff --git a/spec/api-desktop-capturer-spec.js b/spec/api-desktop-capturer-spec.js index 9e85a48fbcc5..68ab2463087d 100644 --- a/spec/api-desktop-capturer-spec.js +++ b/spec/api-desktop-capturer-spec.js @@ -24,4 +24,16 @@ describe('desktopCapturer', function () { desktopCapturer.getSources({types: ['window', 'screen']}, callback) desktopCapturer.getSources({types: ['window', 'screen']}, callback) }) + + it('responds to subsequest calls of different options', function (done) { + var callCount = 0 + var callback = function (error, sources) { + callCount++ + assert.equal(error, null) + if (callCount === 2) done() + } + + desktopCapturer.getSources({types: ['window']}, callback) + desktopCapturer.getSources({types: ['screen']}, callback) + }) }) From 1bac04c69d051ece3c6d04f598ecc02f7583cd03 Mon Sep 17 00:00:00 2001 From: StoneStoneStone Date: Thu, 28 Apr 2016 22:30:14 +0800 Subject: [PATCH 112/141] Update desktop-environment-integration.md --- .../desktop-environment-integration.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs-translations/zh-CN/tutorial/desktop-environment-integration.md b/docs-translations/zh-CN/tutorial/desktop-environment-integration.md index f069065cd65e..3f946da34e1c 100644 --- a/docs-translations/zh-CN/tutorial/desktop-environment-integration.md +++ b/docs-translations/zh-CN/tutorial/desktop-environment-integration.md @@ -3,6 +3,47 @@ 本章将会说明怎样使用 Electron APIs 把你的应用和桌面环境集成到一块。 +## Notifications (Windows, Linux, OS X) + +这三个操作系统都为用户提供了发送通知的方法。Electron让开发人员通过 +[HTML5 Notification API](https://notifications.spec.whatwg.org/) +便利的去发送通知,用操作系统自带的通知APIs去显示。 + +**Note:** 因为这是一个HTML5API,所以只在渲染进程中起作用 + +```javascript +var myNotification = new Notification('Title', { + body: 'Lorem Ipsum Dolor Sit Amet' +}); + +myNotification.onclick = function () { + console.log('Notification clicked') +} +``` + +尽管代码和用户体验在不同的操作系统中基本相同,但还是有一些差异。 + +### Windows + +* 在Windows 10上, 通知"可以工作". +* 在Windows 8.1和Windows 8系统下,你需要将你的应用通过一个[Application User +Model ID][app-user-model-id]安装到开始屏幕上。需要注意的是,这不是将你的应用固定到开始屏幕。 +* 在Windows 7以及更低的版本中,通知不被支持。不过你可以使用[Tray API][tray-balloon]发送一个"气泡通知"。 + +此外,通知支持的最大字符长队为250。Windows团队建议通知应该保持在200个字符以下。 + +### Linux + +通知使用`libnotify`发送,它能在任何支持[Desktop Notifications +Specification][notification-spec]的桌面环境中显示,包括 Cinnamon, Enlightenment, Unity, +GNOME, KDE。 + +### OS X + +在OS X系统中,通知是直接转发的,你应该了解[Apple's Human Interface guidelines regarding notifications](https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/OSXHIGuidelines/NotificationCenter.html)。 + +注意通知被限制在256个字节以内,如果超出,则会被截断。 + ## 最近文档 (Windows & OS X) Windows 和 OS X 提供获取最近文档列表的便捷方式,那就是打开跳转列表或者鱼眼菜单。 @@ -165,3 +206,17 @@ window.setDocumentEdited(true); [16]: https://cloud.githubusercontent.com/assets/639601/5082061/670a949a-6f14-11e4-987a-9aaa04b23c1d.png [17]: https://github.com/electron/electron/blob/master/docs-translations/zh-CN/api/browser-window.md [18]: https://github.com/electron/electron/blob/master/docs-translations/zh-CN/api/browser-window.md + +[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#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 340b7220f126e8f9d590a76b34604a085c833cab Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Thu, 28 Apr 2016 17:46:41 +0200 Subject: [PATCH 113/141] Fix #3075 by not caching the displays (id is not persistent on Windows) --- atom/browser/api/atom_api_screen.cc | 14 +------------- atom/browser/api/atom_api_screen.h | 1 - 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/atom/browser/api/atom_api_screen.cc b/atom/browser/api/atom_api_screen.cc index 61b722d7a44f..9d845e390e31 100644 --- a/atom/browser/api/atom_api_screen.cc +++ b/atom/browser/api/atom_api_screen.cc @@ -49,7 +49,6 @@ std::vector MetricsToArray(uint32_t metrics) { Screen::Screen(v8::Isolate* isolate, gfx::Screen* screen) : screen_(screen) { - displays_ = screen_->GetAllDisplays(); screen_->AddObserver(this); Init(isolate); } @@ -67,7 +66,7 @@ gfx::Display Screen::GetPrimaryDisplay() { } std::vector Screen::GetAllDisplays() { - return displays_; + return screen_->GetAllDisplays(); } gfx::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) { @@ -79,26 +78,15 @@ gfx::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) { } void Screen::OnDisplayAdded(const gfx::Display& new_display) { - displays_.push_back(new_display); Emit("display-added", new_display); } void Screen::OnDisplayRemoved(const gfx::Display& old_display) { - auto iter = FindById(&displays_, old_display.id()); - if (iter == displays_.end()) - return; - - displays_.erase(iter); Emit("display-removed", old_display); } void Screen::OnDisplayMetricsChanged(const gfx::Display& display, uint32_t changed_metrics) { - auto iter = FindById(&displays_, display.id()); - if (iter == displays_.end()) - return; - - *iter = display; Emit("display-metrics-changed", display, MetricsToArray(changed_metrics)); } diff --git a/atom/browser/api/atom_api_screen.h b/atom/browser/api/atom_api_screen.h index 14fc8ce30e7b..c17b61288525 100644 --- a/atom/browser/api/atom_api_screen.h +++ b/atom/browser/api/atom_api_screen.h @@ -47,7 +47,6 @@ class Screen : public mate::EventEmitter, private: gfx::Screen* screen_; - std::vector displays_; DISALLOW_COPY_AND_ASSIGN(Screen); }; From 09b036f07b15af5c2cf1d1681699e93161c8155a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 26 Apr 2016 09:16:59 -0700 Subject: [PATCH 114/141] Update header colors --- default_app/index.html | 58 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/default_app/index.html b/default_app/index.html index 5c8440cfdadb..3fab74a31081 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -3,8 +3,8 @@ Electron From 7e9d7900706b36e72b394c38b72f48ab20659bfa Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 26 Apr 2016 09:28:50 -0700 Subject: [PATCH 116/141] Tweak font weight on holder div --- default_app/index.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/default_app/index.html b/default_app/index.html index c11a4e371476..2748c01dcbec 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -6,6 +6,8 @@ color: #205161; background-color: #fff; font-family: Roboto, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Segoe UI", "Oxygen", "Ubuntu", "Cantarell", "Open Sans", sans-serif; + font-style: normal; + font-variant: normal; padding: 0; margin: 0; } @@ -82,6 +84,7 @@ color: #466a72; border-radius: 3px; font-size: 30px; + font-weight: 300; line-height: 275px; text-align: center; -webkit-user-select: none; From c6edab0950a3db6fb2a62685d3458a9293046d16 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 26 Apr 2016 09:30:37 -0700 Subject: [PATCH 117/141] Tweak link style --- default_app/index.html | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/default_app/index.html b/default_app/index.html index 2748c01dcbec..5c266c40dd74 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -46,13 +46,10 @@ vertical-align: middle !important; } - a { - color: #39AEC6; - text-decoration: none; - } - + a, a:hover { - text-decoration: underline; + color: #2ab0cb; + text-decoration: none; } pre, code { From dd337640f5afca9730fccc0c2e0c9ac4aee8867e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 26 Apr 2016 09:30:55 -0700 Subject: [PATCH 118/141] :art: --- default_app/index.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/default_app/index.html b/default_app/index.html index 5c266c40dd74..61f7e01c0eef 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -115,12 +115,12 @@
From 068909dc03b281d55618c12036de1221e27cbfbe Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 26 Apr 2016 10:06:46 -0700 Subject: [PATCH 119/141] Tweak header text color --- default_app/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default_app/index.html b/default_app/index.html index 61f7e01c0eef..f1a1142aa849 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -19,7 +19,7 @@ .header { background-color: #2f3241; border-bottom: 1px solid #1a1b23; - color: #74b1be; + color: #9feaf9; padding: 15px 30px; margin: 0; } @@ -39,7 +39,7 @@ .svg-stroke, .svg-fill { - stroke: #74b1be; + stroke: #9feaf9; } .vertical-middle { From 6979ea7fda87c8145de087c0027653cc53634c72 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 26 Apr 2016 10:07:05 -0700 Subject: [PATCH 120/141] Use default cursor on holder area --- default_app/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/default_app/index.html b/default_app/index.html index f1a1142aa849..aa1ed4e869cb 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -84,6 +84,7 @@ font-weight: 300; line-height: 275px; text-align: center; + cursor: default; -webkit-user-select: none; } From 3e4ecd6d6eb1dfdef6319b98b63fb70c57ec7670 Mon Sep 17 00:00:00 2001 From: simurai Date: Wed, 27 Apr 2016 10:42:03 +0900 Subject: [PATCH 121/141] Fix logo So the inner dot is filled --- default_app/index.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/default_app/index.html b/default_app/index.html index aa1ed4e869cb..f9387cfff7a6 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -37,10 +37,12 @@ margin-right: 0.4em; } - .svg-stroke, - .svg-fill { + .svg-stroke { stroke: #9feaf9; } + .svg-fill { + fill: #9feaf9; + } .vertical-middle { vertical-align: middle !important; From 5995e3f40031ddcbfb879e7992faff4c12ee5e18 Mon Sep 17 00:00:00 2001 From: simurai Date: Wed, 27 Apr 2016 10:50:21 +0900 Subject: [PATCH 122/141] Make drag&drop text wrap-able --- default_app/index.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/default_app/index.html b/default_app/index.html index f9387cfff7a6..27cc69fbd4fb 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -76,7 +76,11 @@ } #holder { + display: flex; + align-items: center; + justify-content: center; margin: 0 auto; + padding: 10px; height: 275px; border: 1px solid #e0e5e6; background-color: #f6f8f8; @@ -84,7 +88,6 @@ border-radius: 3px; font-size: 30px; font-weight: 300; - line-height: 275px; text-align: center; cursor: default; -webkit-user-select: none; From 80bece56406745a9cdab8f2342c9204ded3a4500 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 27 Apr 2016 15:37:03 -0700 Subject: [PATCH 123/141] Add links to nav bar --- default_app/index.html | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/default_app/index.html b/default_app/index.html index 27cc69fbd4fb..ffd99e380bf0 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -24,11 +24,23 @@ margin: 0; } - .header-version { + .header a { + padding-left: 15px; + color: #9feaf9; + font-weight: 300; + } + + .header-nav { float: right; margin-top: 12px; } + .header-version { + font-size: 1em; + padding-left: 10px; + font-weight: 300; + } + .header-icon { width: 48px; height: 48px; @@ -134,8 +146,12 @@ -
- Version + + +
From b0dc7ff841bac49f484767e6bac8c78f1fdf135d Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 27 Apr 2016 15:41:36 -0700 Subject: [PATCH 124/141] Remove header link hover color --- default_app/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/default_app/index.html b/default_app/index.html index ffd99e380bf0..c10d67a089ac 100644 --- a/default_app/index.html +++ b/default_app/index.html @@ -24,7 +24,8 @@ margin: 0; } - .header a { + .header a, + .header a:hover { padding-left: 15px; color: #9feaf9; font-weight: 300; From f7d4ff90eac6c934f280599ce6e73f1b26cd27ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arif=20=C3=87ak=C4=B1ro=C4=9Flu?= Date: Fri, 29 Apr 2016 02:28:46 +0300 Subject: [PATCH 125/141] added accelerator.md to api folders and translated (#5316) * added accelerator.md to api folders and translated :tada: * added file-object.md to api folder and translated * added all folders to /tr-TR for broken links * removed untouched documentation file * broken link fix --- docs-translations/tr-TR/README.md | 108 ++++++++++----------- docs-translations/tr-TR/api/accelerator.md | 49 ++++++++++ docs-translations/tr-TR/api/file-object.md | 29 ++++++ docs-translations/tr-TR/styleguide.md | 2 +- 4 files changed, 133 insertions(+), 55 deletions(-) create mode 100644 docs-translations/tr-TR/api/accelerator.md create mode 100644 docs-translations/tr-TR/api/file-object.md diff --git a/docs-translations/tr-TR/README.md b/docs-translations/tr-TR/README.md index 1d79da1d6671..b055e63f5af1 100644 --- a/docs-translations/tr-TR/README.md +++ b/docs-translations/tr-TR/README.md @@ -5,82 +5,82 @@ Eğer öyleyse, atom.io üzerinden [mevcut sürümler](http://electron.atom.io/d ## SSS(Sıkça Sorulan Sorular) Bir problem(issue) bildirmeden önce sıkça sorulan sorulara göz atın: -* [Electron SSS](faq/electron-faq.md) +* [Electron SSS](https://github.com/electron/electron/tree/master/docs/faq/electron-faq.md) ## Klavuzlar -* [Desteklenen Platformlar ](tutorial/supported-platforms.md) -* [Uygulama Dağıtımı](tutorial/application-distribution.md) -* [Mac Uygulama Mağazası Başvuru Klavuzu](tutorial/mac-app-store-submission-guide.md) -* [Uygulama Paketleme](tutorial/application-packaging.md) -* [Native Node Modüllerini Kullanma](tutorial/using-native-node-modules.md) -* [Ana Süreç(Main Process) Hata ayıklama](tutorial/debugging-main-process.md) -* [Selenium ve WebDriver kullanımı](tutorial/using-selenium-and-webdriver.md) -* [DevTools Eklentisi](tutorial/devtools-extension.md) -* [Pepper Flash Kullanımı](tutorial/using-pepper-flash-plugin.md) -* [Widevine CDM Kullanımı](tutorial/using-widevine-cdm-plugin.md) -* [CI Sistem Testleri (Travis, Jenkins)](tutorial/testing-on-headless-ci.md) +* [Desteklenen Platformlar ](https://github.com/electron/electron/tree/master/docs/tutorial/supported-platforms.md) +* [Uygulama Dağıtımı](https://github.com/electron/electron/tree/master/docs/tutorial/application-distribution.md) +* [Mac Uygulama Mağazası Başvuru Klavuzu](https://github.com/electron/electron/tree/master/docs/tutorial/mac-app-store-submission-guide.md) +* [Uygulama Paketleme](https://github.com/electron/electron/tree/master/docs/tutorial/application-packaging.md) +* [Native Node Modüllerini Kullanma](https://github.com/electron/electron/tree/master/docs/tutorial/using-native-node-modules.md) +* [Ana Süreç(Main Process) Hata ayıklama](https://github.com/electron/electron/tree/master/docs/tutorial/debugging-main-process.md) +* [Selenium ve WebDriver kullanımı](https://github.com/electron/electron/tree/master/docs/tutorial/using-selenium-and-webdriver.md) +* [DevTools Eklentisi](https://github.com/electron/electron/tree/master/docs/tutorial/devtools-extension.md) +* [Pepper Flash Kullanımı](https://github.com/electron/electron/tree/master/docs/tutorial/using-pepper-flash-plugin.md) +* [Widevine CDM Kullanımı](https://github.com/electron/electron/tree/master/docs/tutorial/using-widevine-cdm-plugin.md) +* [CI Sistem Testleri (Travis, Jenkins)](https://github.com/electron/electron/tree/master/docs/tutorial/testing-on-headless-ci.md) ## Eğitimler -* [Quick Start](tutorial/quick-start.md) -* [Desktop Environment Integration](tutorial/desktop-environment-integration.md) -* [Online/Offline Event Detection](tutorial/online-offline-events.md) +* [Quick Start](https://github.com/electron/electron/tree/master/docs/tutorial/quick-start.md) +* [Desktop Environment Integration](https://github.com/electron/electron/tree/master/docs/tutorial/desktop-environment-integration.md) +* [Online/Offline Event Detection](https://github.com/electron/electron/tree/master/docs/tutorial/online-offline-events.md) ## API Kaynakları -* [Synopsis](api/synopsis.md) -* [Process Object](api/process.md) -* [Desteklenen Chrome Komut Satırı Anahtarları](api/chrome-command-line-switches.md) -* [Environment Değişkenleri](api/environment-variables.md) +* [Synopsis](https://github.com/electron/electron/tree/master/docs/api/synopsis.md) +* [Process Object](https://github.com/electron/electron/tree/master/docs/api/process.md) +* [Desteklenen Chrome Komut Satırı Anahtarları](https://github.com/electron/electron/tree/master/docs/api/chrome-command-line-switches.md) +* [Environment Değişkenleri](https://github.com/electron/electron/tree/master/docs/api/environment-variables.md) ### Özel DOM Elementleri: * [`File` Nesnesi](api/file-object.md) -* [`` Etiketi](api/web-view-tag.md) -* [`window.open` Fonksiyonu](api/window-open.md) +* [`` Etiketi](https://github.com/electron/electron/tree/master/docs/api/web-view-tag.md) +* [`window.open` Fonksiyonu](https://github.com/electron/electron/tree/master/docs/api/window-open.md) ### Ana Süreç(Main Process) Modülleri: -* [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) +* [app](https://github.com/electron/electron/tree/master/docs/api/app.md) +* [autoUpdater](https://github.com/electron/electron/tree/master/docs/api/auto-updater.md) +* [BrowserWindow](https://github.com/electron/electron/tree/master/docs/api/browser-window.md) +* [contentTracing](https://github.com/electron/electron/tree/master/docs/api/content-tracing.md) +* [dialog](https://github.com/electron/electron/tree/master/docs/api/dialog.md) +* [globalShortcut](https://github.com/electron/electron/tree/master/docs/api/global-shortcut.md) +* [ipcMain](https://github.com/electron/electron/tree/master/docs/api/ipc-main.md) +* [Menu](https://github.com/electron/electron/tree/master/docs/api/menu.md) +* [MenuItem](https://github.com/electron/electron/tree/master/docs/api/menu-item.md) +* [powerMonitor](https://github.com/electron/electron/tree/master/docs/api/power-monitor.md) +* [powerSaveBlocker](https://github.com/electron/electron/tree/master/docs/api/power-save-blocker.md) +* [protocol](https://github.com/electron/electron/tree/master/docs/api/protocol.md) +* [session](https://github.com/electron/electron/tree/master/docs/api/session.md) +* [webContents](https://github.com/electron/electron/tree/master/docs/api/web-contents.md) +* [Tray](https://github.com/electron/electron/tree/master/docs/api/tray.md) ### Renderer Process Modülelri (Web Page): -* [desktopCapturer](api/desktop-capturer.md) -* [ipcRenderer](api/ipc-renderer.md) -* [remote](api/remote.md) -* [webFrame](api/web-frame.md) +* [desktopCapturer](https://github.com/electron/electron/tree/master/docs/api/desktop-capturer.md) +* [ipcRenderer](https://github.com/electron/electron/tree/master/docs/api/ipc-renderer.md) +* [remote](https://github.com/electron/electron/tree/master/docs/api/remote.md) +* [webFrame](https://github.com/electron/electron/tree/master/docs/api/web-frame.md) ### Her İki Süreç İçin Geçerli Modüller: -* [clipboard](api/clipboard.md) -* [crashReporter](api/crash-reporter.md) -* [nativeImage](api/native-image.md) -* [screen](api/screen.md) -* [shell](api/shell.md) +* [clipboard](https://github.com/electron/electron/tree/master/docs/api/clipboard.md) +* [crashReporter](https://github.com/electron/electron/tree/master/docs/api/crash-reporter.md) +* [nativeImage](https://github.com/electron/electron/tree/master/docs/api/native-image.md) +* [screen](https://github.com/electron/electron/tree/master/docs/api/screen.md) +* [shell](https://github.com/electron/electron/tree/master/docs/api/shell.md) ## Geliştirme -* [Kodlama Stili](development/coding-style.md) -* [Kaynak Kod Dizin Yapısı](development/source-code-directory-structure.md) -* [NW.js(node-webkit adıyla bilinen) İle Arasındaki Teknik Farklılıklar](development/atom-shell-vs-node-webkit.md) -* [Build Sisyem Genel Bakış](development/build-system-overview.md) -* [(OS X) Build Komutları](development/build-instructions-osx.md) -* [(Windows) Build Komutları](development/build-instructions-windows.md) -* [(Linux) Build Komutları](development/build-instructions-linux.md) -* [(Windows) Hata Ayıklama Komutları](development/debug-instructions-windows.md) -* [Simge Sunucusu(Symbol Server) Hata Ayıklama Kurulumu](development/setting-up-symbol-server.md) +* [Kodlama Stili](https://github.com/electron/electron/tree/master/docs/development/coding-style.md) +* [Kaynak Kod Dizin Yapısı](https://github.com/electron/electron/tree/master/docs/development/source-code-directory-structure.md) +* [NW.js(node-webkit adıyla bilinen) İle Arasındaki Teknik Farklılıklar](https://github.com/electron/electron/tree/master/docs/development/atom-shell-vs-node-webkit.md) +* [Build Sisyem Genel Bakış](https://github.com/electron/electron/tree/master/docs/development/build-system-overview.md) +* [(OS X) Build Komutları](https://github.com/electron/electron/tree/master/docs/development/build-instructions-osx.md) +* [(Windows) Build Komutları](https://github.com/electron/electron/tree/master/docs/development/build-instructions-windows.md) +* [(Linux) Build Komutları](https://github.com/electron/electron/tree/master/docs/development/build-instructions-linux.md) +* [(Windows) Hata Ayıklama Komutları](https://github.com/electron/electron/tree/master/docs/development/debug-instructions-windows.md) +* [Simge Sunucusu(Symbol Server) Hata Ayıklama Kurulumu](https://github.com/electron/electron/tree/master/docs/development/setting-up-symbol-server.md) diff --git a/docs-translations/tr-TR/api/accelerator.md b/docs-translations/tr-TR/api/accelerator.md new file mode 100644 index 000000000000..9105e5c6e460 --- /dev/null +++ b/docs-translations/tr-TR/api/accelerator.md @@ -0,0 +1,49 @@ +# Hızlandırıcı + +> Kısayol Tanımlama. + +Hızlandırıcılar `+` karakteriyle birden fazla niteleyici ile kombinlenebilir. + +Örnek: + +* `CommandOrControl+A` +* `CommandOrControl+Shift+Z` + +## Platform bilgileri + +Linux ve Windows'ta `Command` tuşu herhangi bir etki göstermez. Bunun yerine +`CommandOrControl` niteleyicisini kullanın. Bu işlem OS X'te `Command`, +Linux ve Windows'ta `Control` tuşunun işlevini sağlar. `Alt` ise tüm platformlarda mevcuttur. + +`Super` tuşu Windows ve Linux'te `Windows` tuşuna, OS X'te ise `Cmd` tuşuna eşleştirilmiştir. + +## Mevcut düzenleyiciler + +* `Command` (ya da kısa tanım için `Cmd`) +* `Control` (ya da kısa tanım için `Ctrl`) +* `CommandOrControl` (ya da kısa tanım için `CmdOrCtrl`) +* `Alt` +* `Option` +* `AltGr` +* `Shift` +* `Super` + +## Mevcut tuş kodları + +* `0`dan `9`a +* `A`dan `Z`ye +* `F1`dan `F24`e +* Noktalama işaretleri `~`, `!`, `@`, `#`, `$`, vb. +* `Plus` +* `Space` +* `Backspace` +* `Delete` +* `Insert` +* `Return` (ya da `Enter`) +* `Up`, `Down`, `Left` ve `Right` +* `Home` ve `End` +* `PageUp` ve `PageDown` +* `Escape` (ya da kısa tanım için `Esc`) +* `VolumeUp`, `VolumeDown` ve `VolumeMute` +* `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` ve `MediaPlayPause` +* `PrintScreen` diff --git a/docs-translations/tr-TR/api/file-object.md b/docs-translations/tr-TR/api/file-object.md new file mode 100644 index 000000000000..a99bdb329c5d --- /dev/null +++ b/docs-translations/tr-TR/api/file-object.md @@ -0,0 +1,29 @@ +# `File` nesnesi + +> Dosya ve dosya sistemlerinde HTML5 `File` nesnesini native olarak çalışır. + +DOM Dosya arayüzü HTML5 dosya API'sini kullanarak kullanıcılara doğrudan native dosyalar üzerinde çalışmasına olanak sağlar. Electron'da `File` arayüzü için `path` özelliğini eklemiştir. + +`dragged-onto-the-app`'dan tam dosya yolu alma örneği: + +```html +
+ Dosyalarınızı buraya sürükleyin +
+ + +``` diff --git a/docs-translations/tr-TR/styleguide.md b/docs-translations/tr-TR/styleguide.md index d264600f0d56..5e8f75240721 100644 --- a/docs-translations/tr-TR/styleguide.md +++ b/docs-translations/tr-TR/styleguide.md @@ -68,7 +68,7 @@ of argument is notated by either the common types: [`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) -or a custom type like Electron's [`webContent`](api/web-content.md). +or a custom type like Electron's [`webContent`](https://github.com/electron/electron/tree/master/docs/api/web-content.md). ### Events From 66853344c0fdf1c8bcea50bd58a95e4a94b63575 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 29 Apr 2016 20:20:52 +0900 Subject: [PATCH 126/141] Make sure the userData directory is created before ready event --- atom/browser/browser.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index b3c7a59e08b5..093209ef7c47 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -9,7 +9,10 @@ #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/native_window.h" #include "atom/browser/window_list.h" +#include "base/files/file_util.h" #include "base/message_loop/message_loop.h" +#include "base/path_service.h" +#include "brightray/browser/brightray_paths.h" namespace atom { @@ -139,6 +142,11 @@ void Browser::WillFinishLaunching() { } void Browser::DidFinishLaunching() { + // Make sure the userData directory is created. + base::FilePath user_data; + if (PathService::Get(brightray::DIR_USER_DATA, &user_data)) + base::CreateDirectoryAndGetError(user_data, nullptr); + is_ready_ = true; FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching()); } From edb73fb7346d5abc31cbff4d991f2cf89b86b62f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 29 Apr 2016 19:55:59 +0900 Subject: [PATCH 127/141] Bump v0.37.8 --- atom/browser/resources/mac/Info.plist | 4 ++-- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- electron.gyp | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 8cfb63688910..9d04617b2098 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,9 +17,9 @@ CFBundleIconFile electron.icns CFBundleVersion - 0.37.7 + 0.37.8 CFBundleShortVersionString - 0.37.7 + 0.37.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 bcd4a829369f..9f74c14d4461 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,7,0 - PRODUCTVERSION 0,37,7,0 + FILEVERSION 0,37,8,0 + PRODUCTVERSION 0,37,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.37.7" + VALUE "FileVersion", "0.37.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.37.7" + VALUE "ProductVersion", "0.37.8" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index dab2966bb997..4ce73bc0aeec 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 7 +#define ATOM_PATCH_VERSION 8 #define ATOM_VERSION_IS_RELEASE 1 diff --git a/electron.gyp b/electron.gyp index e6134df117b8..66ff2fd5baf8 100644 --- a/electron.gyp +++ b/electron.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.37.7', + 'version%': '0.37.8', }, 'includes': [ 'filenames.gypi', diff --git a/package.json b/package.json index aa7ca37e5eb8..7d40098f099a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electron", - "version": "0.37.7", + "version": "0.37.8", "devDependencies": { "asar": "^0.11.0", "request": "*", From 2f71d6afe000fc61d2c9b5c56b42815ea3a3df86 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 29 Apr 2016 13:17:50 -0700 Subject: [PATCH 128/141] update quick-start code to match quick-start repo --- docs/tutorial/quick-start.md | 65 ++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index ddbda3782449..3a1b7a2d8acd 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -80,45 +80,60 @@ The `main.js` should create windows and handle system events, a typical example being: ```javascript -'use strict'; - -const electron = require('electron'); -const app = electron.app; // Module to control application life. -const BrowserWindow = electron.BrowserWindow; // Module to create native browser window. +const electron = require('electron') +// Module to control application life. +const app = electron.app +// Module to create native browser window. +const BrowserWindow = electron.BrowserWindow // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. -var mainWindow = null; +let mainWindow -// Quit when all windows are closed. -app.on('window-all-closed', function() { - // On OS X it is common for applications and their menu bar - // to stay active until the user quits explicitly with Cmd + Q - if (process.platform != 'darwin') { - app.quit(); - } -}); - -// This method will be called when Electron has finished -// initialization and is ready to create browser windows. -app.on('ready', function() { +function createWindow () { // Create the browser window. - mainWindow = new BrowserWindow({width: 800, height: 600}); + mainWindow = new BrowserWindow({width: 800, height: 600}) // and load the index.html of the app. - mainWindow.loadURL('file://' + __dirname + '/index.html'); + mainWindow.loadURL('file://' + __dirname + '/index.html') // Open the DevTools. - mainWindow.webContents.openDevTools(); + mainWindow.webContents.openDevTools() // Emitted when the window is closed. - mainWindow.on('closed', function() { + mainWindow.on('closed', function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. - mainWindow = null; - }); -}); + mainWindow = null + }) +} + +// This method will be called when Electron has finished +// initialization and is ready to create browser windows. +// Some APIs can only be used after this event occurs. +app.on('ready', createWindow) + +// Quit when all windows are closed. +app.on('window-all-closed', function () { + // On OS X it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + if (process.platform !== 'darwin') { + app.quit() + } +}) + +app.on('activate', function () { + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (mainWindow === null) { + createWindow() + } +}) + +// In this file you can include the rest of your app's specific main process +// code. You can also put them in separate files and require them here. + ``` Finally the `index.html` is the web page you want to show: From 95476a81ae0737683b4fb4496b28de4dfcd27e2d Mon Sep 17 00:00:00 2001 From: rhedshi Date: Fri, 29 Apr 2016 13:28:41 -0700 Subject: [PATCH 129/141] Update mac-app-store-submission-guide.md --- docs/tutorial/mac-app-store-submission-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorial/mac-app-store-submission-guide.md b/docs/tutorial/mac-app-store-submission-guide.md index 404dcb80efbf..15b6142b57a9 100644 --- a/docs/tutorial/mac-app-store-submission-guide.md +++ b/docs/tutorial/mac-app-store-submission-guide.md @@ -65,8 +65,8 @@ And then sign your app with the following script: # Name of your app. APP="YourApp" -# The path of you app to sign. -APP_PATH="/path/to/YouApp.app" +# The path of your app to sign. +APP_PATH="/path/to/YourApp.app" # The path to the location you want to put the signed package. RESULT_PATH="~/Desktop/$APP.pkg" # The name of certificates you requested. From 0c9c1229e3a87fdab80a0fbc991d2dd24cede763 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 29 Apr 2016 13:32:00 -0700 Subject: [PATCH 130/141] describe electron-prebuilt and link to it --- docs/tutorial/quick-start.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index ddbda3782449..c2b759a04912 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -147,8 +147,11 @@ working as expected. ### electron-prebuilt -If you've installed `electron-prebuilt` globally with `npm`, then you will only -need to run the following in your app's source directory: +[`electron-prebuilt`](https://github.com/electron-userland/electron-prebuilt) is +an `npm` module that contains pre-compiled versions of Electron. + +If you've installed it globally with `npm`, then you will only need to run the +following in your app's source directory: ```bash electron . From 9f99ba3b73cf2fab0cf9245b739f64f406a2b90e Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 29 Apr 2016 18:35:02 -0700 Subject: [PATCH 131/141] update all references to old atom-log bracket notation --- docs-translations/es/api/process.md | 4 ++-- docs-translations/es/tutorial/quick-start.md | 2 +- docs-translations/jp/api/process.md | 4 ++-- docs-translations/ko-KR/api/process.md | 4 ++-- docs-translations/ko-KR/tutorial/quick-start.md | 2 +- docs-translations/pt-BR/api/process.md | 4 ++-- docs-translations/pt-BR/tutorial/quick-start.md | 2 +- docs-translations/zh-CN/api/process.md | 4 ++-- docs-translations/zh-CN/tutorial/quick-start.md | 2 +- docs-translations/zh-TW/api/process.md | 4 ++-- docs/api/process.md | 4 ++-- spec/api-crash-reporter-spec.js | 2 +- 12 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docs-translations/es/api/process.md b/docs-translations/es/api/process.md index 9e95ba988541..e50a2c1aac62 100644 --- a/docs-translations/es/api/process.md +++ b/docs-translations/es/api/process.md @@ -5,8 +5,8 @@ al node convencional: * `process.type` String - El tipo del proceso puede ser `browser` (ej. proceso principal) o `renderer`. -* `process.versions['electron']` String - Versión de Electron. -* `process.versions['chrome']` String - Versión de Chromium. +* `process.versions.electron` String - Versión de Electron. +* `process.versions.chrome` String - Versión de Chromium. * `process.resourcesPath` String - Ruta al código fuente JavaScript. ## Events diff --git a/docs-translations/es/tutorial/quick-start.md b/docs-translations/es/tutorial/quick-start.md index a760fccad2c8..9e65042c5035 100644 --- a/docs-translations/es/tutorial/quick-start.md +++ b/docs-translations/es/tutorial/quick-start.md @@ -115,7 +115,7 @@ Finalmente el `index.html` es la página web que mostraremos:

Hello World!

We are using io.js - and Electron . + and Electron . ``` diff --git a/docs-translations/jp/api/process.md b/docs-translations/jp/api/process.md index ea15fc747a20..6ad3c32d76fe 100644 --- a/docs-translations/jp/api/process.md +++ b/docs-translations/jp/api/process.md @@ -3,8 +3,8 @@ Electronの`process`オブジェクトは上流nodeの1つから次のような違いがあります。 * `process.type` String - プロセスの種類で、`browser` (例 メインプロセス)または `renderer`を設定できます。 -* `process.versions['electron']` String - Electronのバージョン -* `process.versions['chrome']` String - Chromiumのバージョン +* `process.versions.electron` String - Electronのバージョン +* `process.versions.chrome` String - Chromiumのバージョン * `process.resourcesPath` String - JavaScriptのソースコードのパスを設定します。 * `process.mas` Boolean - Mac app Store用のビルドで、値は`true`です。ほかのビルドの場合は`undefined`です。 diff --git a/docs-translations/ko-KR/api/process.md b/docs-translations/ko-KR/api/process.md index 3cdc10dd78cf..a7377a629b20 100644 --- a/docs-translations/ko-KR/api/process.md +++ b/docs-translations/ko-KR/api/process.md @@ -4,8 +4,8 @@ Electron의 `process` 객체는 기존의 node와는 달리 약간의 차이점 * `process.type` String - 프로세스의 타입, `browser` (메인 프로세스) 또는 `renderer`가 됩니다. -* `process.versions['electron']` String - Electron의 버전. -* `process.versions['chrome']` String - Chromium의 버전. +* `process.versions.electron` String - Electron의 버전. +* `process.versions.chrome` String - Chromium의 버전. * `process.resourcesPath` String - JavaScript 소스 코드의 경로. * `process.mas` Boolean - Mac 앱 스토어용 빌드일 때 `true`로 지정됩니다. 다른 빌드일 땐 `undefined`로 지정됩니다. diff --git a/docs-translations/ko-KR/tutorial/quick-start.md b/docs-translations/ko-KR/tutorial/quick-start.md index eb95232a06fc..f7eb700d037c 100644 --- a/docs-translations/ko-KR/tutorial/quick-start.md +++ b/docs-translations/ko-KR/tutorial/quick-start.md @@ -129,7 +129,7 @@ app.on('ready', function() {

헬로 월드!

이 어플리케이션은 node , Chrome , - Electron 을 사용합니다. + Electron 을 사용합니다. ``` diff --git a/docs-translations/pt-BR/api/process.md b/docs-translations/pt-BR/api/process.md index 1c20e2df1187..71502de80d62 100644 --- a/docs-translations/pt-BR/api/process.md +++ b/docs-translations/pt-BR/api/process.md @@ -3,8 +3,8 @@ O objeto `process` no Electron tem as seguintes diferenças do objeto no upstrea * `process.type` String - Tipo de processo, pode ser `browser` (processo principal) ou `renderer`. -* `process.versions['electron']` String - Versão do Electron. -* `process.versions['chrome']` String - Versão do Chromium. +* `process.versions.electron` String - Versão do Electron. +* `process.versions.chrome` String - Versão do Chromium. * `process.resourcesPath` String - Caminho para o código fonte JavaScript. * `process.mas` Boolean - Para build da Mac App Store, este valor é `true`, para outros builds é `undefined`. diff --git a/docs-translations/pt-BR/tutorial/quick-start.md b/docs-translations/pt-BR/tutorial/quick-start.md index 76b128df5d04..6a21123ecf6e 100644 --- a/docs-translations/pt-BR/tutorial/quick-start.md +++ b/docs-translations/pt-BR/tutorial/quick-start.md @@ -130,7 +130,7 @@ Finalmente o `index.html` é a página web que você quer mostrar:

Hello World!

Nós estamos usando io.js - e Electron . + e Electron . ``` diff --git a/docs-translations/zh-CN/api/process.md b/docs-translations/zh-CN/api/process.md index 7e8173dfb3b3..89a5e02a6758 100644 --- a/docs-translations/zh-CN/api/process.md +++ b/docs-translations/zh-CN/api/process.md @@ -4,8 +4,8 @@ Electron 中的 `process` 对象 与 upstream node 中的有以下的不同点: * `process.type` String - 进程类型, 可以是 `browser` (i.e. main process) 或 `renderer`. -* `process.versions['electron']` String - Electron的版本. -* `process.versions['chrome']` String - Chromium的版本. +* `process.versions.electron` String - Electron的版本. +* `process.versions.chrome` String - Chromium的版本. * `process.resourcesPath` String - JavaScript源代码路径. * `process.mas` Boolean - 在Mac App Store 创建, 它的值为 `true`, 在其它的地方值为 `undefined`. diff --git a/docs-translations/zh-CN/tutorial/quick-start.md b/docs-translations/zh-CN/tutorial/quick-start.md index 8bdcc05cb027..d267d3146051 100644 --- a/docs-translations/zh-CN/tutorial/quick-start.md +++ b/docs-translations/zh-CN/tutorial/quick-start.md @@ -89,7 +89,7 @@ app.on('ready', function() {

Hello World!

We are using io.js - and Electron . + and Electron . ``` diff --git a/docs-translations/zh-TW/api/process.md b/docs-translations/zh-TW/api/process.md index a4f45352b9c4..ba3dd245f7a9 100644 --- a/docs-translations/zh-TW/api/process.md +++ b/docs-translations/zh-TW/api/process.md @@ -3,8 +3,8 @@ 在 Electron 裡的 `process` 物件具有以下幾個與 upstream node 的不同點: * `process.type` String - Process 的型態,可以是 `browser` (i.e. 主行程) 或 `renderer`. -* `process.versions['electron']` String - Electron 的版本 -* `process.versions['chrome']` String - Chromium 的版本 +* `process.versions.electron` String - Electron 的版本 +* `process.versions.chrome` String - Chromium 的版本 * `process.resourcesPath` String - JavaScript 源碼的路徑 # 方法 (Methods) diff --git a/docs/api/process.md b/docs/api/process.md index 79bd9bd5572f..1becdd46df09 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -7,8 +7,8 @@ upstream node: * `process.type` String - Process's type, can be `browser` (i.e. main process) or `renderer`. -* `process.versions['electron']` String - Version of Electron. -* `process.versions['chrome']` String - Version of Chromium. +* `process.versions.electron` String - Version of Electron. +* `process.versions.chrome` String - Version of Chromium. * `process.resourcesPath` String - Path to JavaScript source code. * `process.mas` Boolean - For Mac App Store build, this value is `true`, for other builds it is `undefined`. diff --git a/spec/api-crash-reporter-spec.js b/spec/api-crash-reporter-spec.js index 2e49fdc36c5c..e5a3223eed8f 100644 --- a/spec/api-crash-reporter-spec.js +++ b/spec/api-crash-reporter-spec.js @@ -44,7 +44,7 @@ describe('crash-reporter module', function () { if (called) return called = true assert.equal(fields['prod'], 'Electron') - assert.equal(fields['ver'], process.versions['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') From 6756f8c7af799c4a99cc7c9f5d7faaff655fd4d0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Apr 2016 15:38:23 +0900 Subject: [PATCH 132/141] Make win32 CI machine run tests --- script/cibuild | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/script/cibuild b/script/cibuild index 59437837aa16..8d21e3a40244 100755 --- a/script/cibuild +++ b/script/cibuild @@ -39,6 +39,7 @@ def main(): if os.environ.has_key('TARGET_ARCH'): target_arch = os.environ['TARGET_ARCH'] + is_appveyor = (os.getenv('APPVEYOR') == 'True') is_travis = (os.getenv('TRAVIS') == 'true') if is_travis and PLATFORM == 'linux': print 'Setup travis CI' @@ -76,7 +77,7 @@ def main(): run_script('upload.py') else: run_script('build.py', ['-c', 'D']) - if PLATFORM != 'win32' and target_arch == 'x64': + if not is_appveyor and target_arch == 'x64': run_script('test.py', ['--ci']) From 8aa88067ca0cef906e7f7bda97239c09335b4fcf Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Apr 2016 17:05:52 +0900 Subject: [PATCH 133/141] Do not write to stdout in Electron when running on win32 CI machine This makes Electron crash on CI machine somehow. --- script/cibuild | 5 +++-- script/test.py | 5 +++++ spec/static/main.js | 21 ++++++++++++++------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/script/cibuild b/script/cibuild index 8d21e3a40244..3a141eac0997 100755 --- a/script/cibuild +++ b/script/cibuild @@ -39,7 +39,6 @@ def main(): if os.environ.has_key('TARGET_ARCH'): target_arch = os.environ['TARGET_ARCH'] - is_appveyor = (os.getenv('APPVEYOR') == 'True') is_travis = (os.getenv('TRAVIS') == 'true') if is_travis and PLATFORM == 'linux': print 'Setup travis CI' @@ -76,8 +75,10 @@ def main(): run_script('create-dist.py') run_script('upload.py') else: + if PLATFORM == 'win32': + os.environ['OUTPUT_TO_FILE'] = 'output.log' run_script('build.py', ['-c', 'D']) - if not is_appveyor and target_arch == 'x64': + if target_arch == 'x64': run_script('test.py', ['--ci']) diff --git a/script/test.py b/script/test.py index 28aeac9dc1ff..2acf1f7154a8 100755 --- a/script/test.py +++ b/script/test.py @@ -32,6 +32,11 @@ def main(): subprocess.check_call([atom_shell, 'spec'] + sys.argv[1:]) + if os.environ.has_key('OUTPUT_TO_FILE'): + output_to_file = os.environ['OUTPUT_TO_FILE'] + with open(output_to_file, 'r') as f: + print f.read() + if __name__ == '__main__': sys.exit(main()) diff --git a/spec/static/main.js b/spec/static/main.js index 84e9ba3da55d..025ff394bc66 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -7,8 +7,10 @@ const ipcMain = electron.ipcMain const dialog = electron.dialog const BrowserWindow = electron.BrowserWindow +const fs = require('fs') const path = require('path') const url = require('url') +const util = require('util') var argv = require('yargs') .boolean('ci') @@ -35,13 +37,18 @@ 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.error', function (event, args) { - console.error.apply(console, args) -}) +// Write output to file if OUTPUT_TO_FILE is defined. +const outputToFile = process.env.OUTPUT_TO_FILE +const print = function (_, args) { + let output = util.format.apply(null, args) + if (outputToFile) { + fs.appendFileSync(outputToFile, output + '\n') + } else { + console.error(output) + } +} +ipcMain.on('console.log', print) +ipcMain.on('console.error', print) ipcMain.on('process.exit', function (event, code) { process.exit(code) From 3dcf69eab3d6deabd26f5c05c8f6e2cc409794af Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Apr 2016 17:17:23 +0900 Subject: [PATCH 134/141] Also run tests on 32bit Windows --- script/cibuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/cibuild b/script/cibuild index 3a141eac0997..7d025b4e82cd 100755 --- a/script/cibuild +++ b/script/cibuild @@ -78,7 +78,7 @@ def main(): if PLATFORM == 'win32': os.environ['OUTPUT_TO_FILE'] = 'output.log' run_script('build.py', ['-c', 'D']) - if target_arch == 'x64': + if PLATFORM == 'win32' or target_arch == 'x64': run_script('test.py', ['--ci']) From b68a25835fe68d7a8cab44ad47aabd5e005f7236 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Apr 2016 17:47:29 +0900 Subject: [PATCH 135/141] Make sure output is written when test fails --- script/test.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/script/test.py b/script/test.py index 2acf1f7154a8..85061db5746e 100755 --- a/script/test.py +++ b/script/test.py @@ -30,13 +30,19 @@ def main(): else: atom_shell = os.path.join(SOURCE_ROOT, 'out', config, PROJECT_NAME) - subprocess.check_call([atom_shell, 'spec'] + sys.argv[1:]) + returncode = 0 + try: + subprocess.check_call([atom_shell, 'spec'] + sys.argv[1:]) + except subprocess.CalledProcessError as e: + returncode = e.returncode if os.environ.has_key('OUTPUT_TO_FILE'): output_to_file = os.environ['OUTPUT_TO_FILE'] with open(output_to_file, 'r') as f: print f.read() + return returncode + if __name__ == '__main__': sys.exit(main()) From 2a55d935015e73baaae87dd341ad01ef13b54152 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Apr 2016 17:52:53 +0900 Subject: [PATCH 136/141] Remove the output file after testing --- script/test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/script/test.py b/script/test.py index 85061db5746e..5adfd4eed6c5 100755 --- a/script/test.py +++ b/script/test.py @@ -4,7 +4,7 @@ import os import subprocess import sys -from lib.util import atom_gyp +from lib.util import atom_gyp, rm_rf SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) @@ -40,6 +40,8 @@ def main(): output_to_file = os.environ['OUTPUT_TO_FILE'] with open(output_to_file, 'r') as f: print f.read() + rm_rf(output_to_file) + return returncode From 214eb0430c823f5196cc5989a6189bd774caa142 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Apr 2016 18:21:18 +0900 Subject: [PATCH 137/141] Fix a few failing tests on Windows --- spec/api-browser-window-spec.js | 5 +++-- spec/chromium-spec.js | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index c364b916c3a4..e76821020bdc 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -173,11 +173,12 @@ describe('browser-window module', function () { }) it('does not crash in did-fail-provisional-load handler', function (done) { + this.timeout(10000) w.webContents.once('did-fail-provisional-load', function () { - w.loadURL('http://localhost:11111') + w.loadURL('http://127.0.0.1:11111') done() }) - w.loadURL('http://localhost:11111') + w.loadURL('http://127.0.0.1:11111') }) }) diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 1d37d0fe051d..706447c00dd8 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -97,6 +97,9 @@ describe('chromium feature', function () { if (isCI && process.platform === 'linux') { return } + if (isCI && process.platform === 'win32') { + return + } it('can return labels of enumerated devices', function (done) { navigator.mediaDevices.enumerateDevices().then((devices) => { @@ -327,6 +330,10 @@ describe('chromium feature', function () { }) describe('webgl', function () { + if (isCI && process.platform === 'win32') { + return + } + it('can be get as context in canvas', function () { if (process.platform === 'linux') return From 33370b18b3f468a3eb501e45c35626cdb031a81d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Apr 2016 20:41:45 +0900 Subject: [PATCH 138/141] Run tests for branches on appveyor --- appveyor.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0fa0c0d9bddd..a3fd51925588 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,10 +14,6 @@ install: - cmd: SET PATH=C:\python27;%PATH% - cmd: python script/cibuild -branches: - only: - - master - # disable build and test pahses build: off test: off From f65f8918c95ed2b83651309d48a91bb9b60f211d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Apr 2016 20:51:09 +0900 Subject: [PATCH 139/141] Fix specs on Windows when running without desktop session --- spec/api-desktop-capturer-spec.js | 6 ++++++ spec/chromium-spec.js | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/spec/api-desktop-capturer-spec.js b/spec/api-desktop-capturer-spec.js index 68ab2463087d..35b7248ed5ee 100644 --- a/spec/api-desktop-capturer-spec.js +++ b/spec/api-desktop-capturer-spec.js @@ -1,7 +1,13 @@ const assert = require('assert') const desktopCapturer = require('electron').desktopCapturer +const isCI = require('electron').remote.getGlobal('isCi') + describe('desktopCapturer', function () { + if (isCI && process.platform === 'win32') { + return + } + it('should return a non-empty array of sources', function (done) { desktopCapturer.getSources({ types: ['window', 'screen'] diff --git a/spec/chromium-spec.js b/spec/chromium-spec.js index 706447c00dd8..577f020128ad 100644 --- a/spec/chromium-spec.js +++ b/spec/chromium-spec.js @@ -62,6 +62,10 @@ describe('chromium feature', function () { w.loadURL(url) }) + if (isCI && process.platform === 'win32') { + return + } + it('is set correctly when window is inactive', function (done) { w = new BrowserWindow({ show: false From d91cd424fec788bb1e5ee490e265964fd4022b63 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Apr 2016 21:21:11 +0900 Subject: [PATCH 140/141] Revert "Run tests for branches on appveyor" This reverts commit 33370b18b3f468a3eb501e45c35626cdb031a81d. This commit was wrongly pushed. --- appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index a3fd51925588..0fa0c0d9bddd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,10 @@ install: - cmd: SET PATH=C:\python27;%PATH% - cmd: python script/cibuild +branches: + only: + - master + # disable build and test pahses build: off test: off From 47f7f7b02e5c8f064fc7af4bf68a320040a6a77b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 30 Apr 2016 21:43:33 +0900 Subject: [PATCH 141/141] Revert "Don't upload PDB files in CI" This reverts commit 7ab8134613577b9092f5e8e81f1c883174bee222. --- script/upload.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/script/upload.py b/script/upload.py index fd795172a679..80d9e5e9e090 100755 --- a/script/upload.py +++ b/script/upload.py @@ -101,6 +101,10 @@ def main(): upload_atom_shell(github, release, os.path.join(DIST_DIR, mksnapshot)) if PLATFORM == 'win32' and not tag_exists: + # Upload PDBs to Windows symbol server. + execute([sys.executable, + os.path.join(SOURCE_ROOT, 'script', 'upload-windows-pdb.py')]) + # Upload node headers. execute([sys.executable, os.path.join(SOURCE_ROOT, 'script', 'upload-node-headers.py'),