Merge branch 'master' into publish-prebuilt

This commit is contained in:
Vanessa Yuen 2017-08-02 14:57:28 -04:00
commit c8e2e37146
30 changed files with 201 additions and 67 deletions

2
.gitignore vendored
View file

@ -14,6 +14,7 @@
*.vcxproj.filters *.vcxproj.filters
*.vcxproj.user *.vcxproj.user
*.xcodeproj *.xcodeproj
node_modules/
/.idea/ /.idea/
/brightray/brightray.opensdf /brightray/brightray.opensdf
/brightray/brightray.sdf /brightray/brightray.sdf
@ -25,7 +26,6 @@
/build/ /build/
/dist/ /dist/
/external_binaries/ /external_binaries/
node_modules
/out/ /out/
/vendor/.gclient /vendor/.gclient
/vendor/debian_jessie_amd64-sysroot/ /vendor/debian_jessie_amd64-sysroot/

View file

@ -3,6 +3,9 @@ git:
notifications: notifications:
email: false email: false
before_install:
- export BOTO_CONFIG=/dev/null
language: node_js language: node_js
node_js: node_js:
- "4" - "4"

View file

@ -57,6 +57,23 @@ void AutoUpdater::OnError(const std::string& message) {
message); message);
} }
void AutoUpdater::OnError(const std::string& message,
const int code, const std::string& domain) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
auto errorObject = error->ToObject(
isolate()->GetCurrentContext()).ToLocalChecked();
// add two new params for better error handling
errorObject->Set(mate::StringToV8(isolate(), "code"),
v8::Integer::New(isolate(), code));
errorObject->Set(mate::StringToV8(isolate(), "domain"),
mate::StringToV8(isolate(), domain));
mate::EmitEvent(isolate(), GetWrapper(), "error", errorObject, message);
}
void AutoUpdater::OnCheckingForUpdate() { void AutoUpdater::OnCheckingForUpdate() {
Emit("checking-for-update"); Emit("checking-for-update");
} }

View file

@ -32,6 +32,8 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
// Delegate implementations. // Delegate implementations.
void OnError(const std::string& error) override; void OnError(const std::string& error) override;
void OnError(const std::string& message, const int code,
const std::string& domain);
void OnCheckingForUpdate() override; void OnCheckingForUpdate() override;
void OnUpdateAvailable() override; void OnUpdateAvailable() override;
void OnUpdateNotAvailable() override; void OnUpdateNotAvailable() override;

View file

@ -152,7 +152,8 @@ void Initialize(v8::Local<v8::Object> exports,
mate::Dictionary browser_view( mate::Dictionary browser_view(
isolate, BrowserView::GetConstructor(isolate)->GetFunction()); isolate, BrowserView::GetConstructor(isolate)->GetFunction());
browser_view.SetMethod("fromId",
&mate::TrackableObject<BrowserView>::FromWeakMapID);
mate::Dictionary dict(isolate, exports); mate::Dictionary dict(isolate, exports);
dict.Set("BrowserView", browser_view); dict.Set("BrowserView", browser_view);
} }

View file

@ -22,6 +22,9 @@ class Delegate {
// An error happened. // An error happened.
virtual void OnError(const std::string& error) {} virtual void OnError(const std::string& error) {}
virtual void OnError(const std::string& error, const int code,
const std::string& domain) {}
// Checking to see if there is an update // Checking to see if there is an update
virtual void OnCheckingForUpdate() {} virtual void OnCheckingForUpdate() {}

View file

@ -104,7 +104,7 @@ void AutoUpdater::CheckForUpdates() {
delegate->OnUpdateNotAvailable(); delegate->OnUpdateNotAvailable();
} }
} error:^(NSError *error) { } error:^(NSError *error) {
NSMutableString* failureString = NSMutableString *failureString =
[NSMutableString stringWithString:error.localizedDescription]; [NSMutableString stringWithString:error.localizedDescription];
if (error.localizedFailureReason) { if (error.localizedFailureReason) {
[failureString appendString:@": "]; [failureString appendString:@": "];
@ -116,7 +116,8 @@ void AutoUpdater::CheckForUpdates() {
[failureString appendString:@" "]; [failureString appendString:@" "];
[failureString appendString:error.localizedRecoverySuggestion]; [failureString appendString:error.localizedRecoverySuggestion];
} }
delegate->OnError(base::SysNSStringToUTF8(failureString)); delegate->OnError(base::SysNSStringToUTF8(failureString), error.code,
base::SysNSStringToUTF8(error.domain));
}]; }];
} }
@ -125,7 +126,8 @@ void AutoUpdater::QuitAndInstall() {
if (g_update_available) { if (g_update_available) {
[[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) { [[g_updater relaunchToInstallUpdate] subscribeError:^(NSError* error) {
if (delegate) if (delegate)
delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription)); delegate->OnError(base::SysNSStringToUTF8(error.localizedDescription),
error.code, base::SysNSStringToUTF8(error.domain));
}]; }];
} else { } else {
if (delegate) if (delegate)

View file

@ -15,6 +15,7 @@
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/task_runner.h" #include "base/task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/file_stream.h" #include "net/base/file_stream.h"
#include "net/base/filename_util.h" #include "net/base/filename_util.h"
#include "net/base/io_buffer.h" #include "net/base/io_buffer.h"
@ -119,8 +120,11 @@ void URLRequestAsarJob::Start() {
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
base::Owned(meta_info))); base::Owned(meta_info)));
} else { } else {
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, base::ThreadTaskRunnerHandle::Get()->PostTask(
net::ERR_FILE_NOT_FOUND)); FROM_HERE,
base::Bind(&URLRequestAsarJob::DidOpen,
weak_ptr_factory_.GetWeakPtr(),
net::ERR_FILE_NOT_FOUND));
} }
} }

View file

@ -89,7 +89,6 @@ class URLRequestAsarJob : public net::URLRequestJob {
// Callback after fetching file info on a background thread. // Callback after fetching file info on a background thread.
void DidFetchMetaInfo(const FileMetaInfo* meta_info); void DidFetchMetaInfo(const FileMetaInfo* meta_info);
// Callback after opening file on a background thread. // Callback after opening file on a background thread.
void DidOpen(int result); void DidOpen(int result);

View file

@ -165,6 +165,18 @@ void SetMenuItemID(DbusmenuMenuitem* item, int id) {
g_object_set_data(G_OBJECT(item), "menu-id", GINT_TO_POINTER(id + 1)); g_object_set_data(G_OBJECT(item), "menu-id", GINT_TO_POINTER(id + 1));
} }
std::string GetMenuModelStatus(AtomMenuModel* model) {
std::string ret;
for (int i = 0; i < model->GetItemCount(); ++i) {
int status = model->GetTypeAt(i) | (model->IsVisibleAt(i) << 3)
| (model->IsEnabledAt(i) << 4)
| (model->IsItemCheckedAt(i) << 5);
ret += base::StringPrintf(
"%s-%X\n", base::UTF16ToUTF8(model->GetLabelAt(i)).c_str(), status);
}
return ret;
}
} // namespace } // namespace
GlobalMenuBarX11::GlobalMenuBarX11(NativeWindowViews* window) GlobalMenuBarX11::GlobalMenuBarX11(NativeWindowViews* window)
@ -309,6 +321,16 @@ void GlobalMenuBarX11::OnSubMenuShow(DbusmenuMenuitem* item) {
if (!model || !GetMenuItemID(item, &id)) if (!model || !GetMenuItemID(item, &id))
return; return;
// Do not update menu if the submenu has not been changed.
std::string status = GetMenuModelStatus(model);
char* old = static_cast<char*>(g_object_get_data(G_OBJECT(item), "status"));
if (old && status == old)
return;
// Save the new status.
g_object_set_data_full(G_OBJECT(item), "status", g_strdup(status.c_str()),
g_free);
// Clear children. // Clear children.
GList *children = menuitem_take_children(item); GList *children = menuitem_take_children(item);
g_list_foreach(children, reinterpret_cast<GFunc>(g_object_unref), NULL); g_list_foreach(children, reinterpret_cast<GFunc>(g_object_unref), NULL);

View file

@ -268,11 +268,10 @@ v8::Local<v8::Value> NativeImage::ToPNG(mate::Arguments* args) {
const SkBitmap bitmap = const SkBitmap bitmap =
image_.AsImageSkia().GetRepresentation(scale_factor).sk_bitmap(); image_.AsImageSkia().GetRepresentation(scale_factor).sk_bitmap();
std::unique_ptr<std::vector<unsigned char>> encoded( std::vector<unsigned char> encoded;
new std::vector<unsigned char>()); gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &encoded);
gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, encoded.get()); const char* data = reinterpret_cast<char*>(encoded.data());
const char* data = reinterpret_cast<char*>(encoded->data()); size_t size = encoded.size();
size_t size = encoded->size();
return node::Buffer::Copy(args->isolate(), data, size).ToLocalChecked(); return node::Buffer::Copy(args->isolate(), data, size).ToLocalChecked();
} }
@ -292,6 +291,8 @@ v8::Local<v8::Value> NativeImage::ToBitmap(mate::Arguments* args) {
v8::Local<v8::Value> NativeImage::ToJPEG(v8::Isolate* isolate, int quality) { v8::Local<v8::Value> NativeImage::ToJPEG(v8::Isolate* isolate, int quality) {
std::vector<unsigned char> output; std::vector<unsigned char> output;
gfx::JPEG1xEncodedDataFromImage(image_, quality, &output); gfx::JPEG1xEncodedDataFromImage(image_, quality, &output);
if (output.empty())
return node::Buffer::New(isolate, 0).ToLocalChecked();
return node::Buffer::Copy( return node::Buffer::Copy(
isolate, isolate,
reinterpret_cast<const char*>(&output.front()), reinterpret_cast<const char*>(&output.front()),

View file

@ -56,7 +56,8 @@ struct V8FunctionInvoker<v8::Local<v8::Value>(ArgTypes...)> {
v8::Local<v8::Context> context = holder->CreationContext(); v8::Local<v8::Context> context = holder->CreationContext();
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
std::vector<v8::Local<v8::Value>> args { ConvertToV8(isolate, raw)... }; std::vector<v8::Local<v8::Value>> args { ConvertToV8(isolate, raw)... };
v8::Local<v8::Value> ret(holder->Call(holder, args.size(), &args.front())); v8::Local<v8::Value> ret(holder->Call(
holder, args.size(), args.empty() ? nullptr : &args.front()));
return handle_scope.Escape(ret); return handle_scope.Escape(ret);
} }
}; };
@ -76,7 +77,8 @@ struct V8FunctionInvoker<void(ArgTypes...)> {
v8::Local<v8::Context> context = holder->CreationContext(); v8::Local<v8::Context> context = holder->CreationContext();
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
std::vector<v8::Local<v8::Value>> args { ConvertToV8(isolate, raw)... }; std::vector<v8::Local<v8::Value>> args { ConvertToV8(isolate, raw)... };
holder->Call(holder, args.size(), &args.front()); holder->Call(
holder, args.size(), args.empty() ? nullptr : &args.front());
} }
}; };
@ -97,8 +99,8 @@ struct V8FunctionInvoker<ReturnType(ArgTypes...)> {
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
std::vector<v8::Local<v8::Value>> args { ConvertToV8(isolate, raw)... }; std::vector<v8::Local<v8::Value>> args { ConvertToV8(isolate, raw)... };
v8::Local<v8::Value> result; v8::Local<v8::Value> result;
auto maybe_result = auto maybe_result = holder->Call(
holder->Call(context, holder, args.size(), &args.front()); context, holder, args.size(), args.empty() ? nullptr : &args.front());
if (maybe_result.ToLocal(&result)) if (maybe_result.ToLocal(&result))
Converter<ReturnType>::FromV8(isolate, result, &ret); Converter<ReturnType>::FromV8(isolate, result, &ret);
return ret; return ret;

View file

@ -132,7 +132,12 @@ void AtomRendererClient::WillReleaseScriptContext(
node_bindings_->set_uv_env(nullptr); node_bindings_->set_uv_env(nullptr);
// Destroy the node environment. // Destroy the node environment.
node::FreeEnvironment(env); // This is disabled because pending async tasks may still use the environment
// and would cause crashes later. Node does not seem to clear all async tasks
// when the environment is destroyed.
// node::FreeEnvironment(env);
// AtomBindings is tracking node environments.
atom_bindings_->EnvironmentDestroyed(env); atom_bindings_->EnvironmentDestroyed(env);
} }

View file

@ -203,12 +203,12 @@
'BasicRuntimeChecks': '3', # 3 = all checks enabled, 0 = off 'BasicRuntimeChecks': '3', # 3 = all checks enabled, 0 = off
}, },
'VCLinkerTool': { 'VCLinkerTool': {
'OptimizeReferences': 2, # /OPT:REF 'OptimizeReferences': 2, # /OPT:REF
'EnableCOMDATFolding': 2, # /OPT:ICF 'EnableCOMDATFolding': 2, # /OPT:ICF
}, },
}, },
'conditions': [ 'conditions': [
['OS=="linux"', { ['OS=="linux" and target_arch=="x64"', {
'defines': [ 'defines': [
'_GLIBCXX_DEBUG', '_GLIBCXX_DEBUG',
], ],

View file

@ -1,4 +1,4 @@
# Class: BrowserView ## Class: BrowserView
> Create and control views. > Create and control views.
@ -38,6 +38,14 @@ view.webContents.loadURL('https://electron.atom.io')
* `options` Object (optional) * `options` Object (optional)
* `webPreferences` Object (optional) - See [BrowserWindow](browser-window.md). * `webPreferences` Object (optional) - See [BrowserWindow](browser-window.md).
### Static Methods
#### `BrowserView.fromId(id)`
* `id` Integer
Returns `BrowserView` - The view with the given `id`.
### Instance Properties ### Instance Properties
Objects created with `new BrowserView` have the following properties: Objects created with `new BrowserView` have the following properties:

View file

@ -1,4 +1,5 @@
# Class: Menu ## Class: Menu
> Create native application menus and context menus. > Create native application menus and context menus.

View file

@ -22,12 +22,12 @@ Process: [Main](../tutorial/quick-start.md#main-process)
The following properties are available on instances of `TouchBarScrubber`: The following properties are available on instances of `TouchBarScrubber`:
#### `touchBarSegmentedControl.items` #### `touchBarScrubber.items`
A `ScrubberItem[]` array representing the items in this scrubber. Updating this value immediately A `ScrubberItem[]` array representing the items in this scrubber. Updating this value immediately
updates the control in the touch bar. Updating deep properties inside this array **does not update the touch bar**. updates the control in the touch bar. Updating deep properties inside this array **does not update the touch bar**.
#### `touchBarSegmentedControl.selectedStyle` #### `touchBarScrubber.selectedStyle`
A `String` representing the style that selected items in the scrubber should have. Updating this value immediately A `String` representing the style that selected items in the scrubber should have. Updating this value immediately
updates the control in the touch bar. Possible values: updates the control in the touch bar. Possible values:
@ -36,7 +36,7 @@ updates the control in the touch bar. Possible values:
* `outline` - Maps to `[NSScrubberSelectionStyle outlineOverlayStyle]` * `outline` - Maps to `[NSScrubberSelectionStyle outlineOverlayStyle]`
* `null` - Actually null, not a string, removes all styles * `null` - Actually null, not a string, removes all styles
#### `touchBarSegmentedControl.overlayStyle` #### `touchBarScrubber.overlayStyle`
A `String` representing the style that selected items in the scrubber should have. This style is overlayed on top A `String` representing the style that selected items in the scrubber should have. This style is overlayed on top
of the scrubber item instead of being placed behind it. Updating this value immediately updates the control in the of the scrubber item instead of being placed behind it. Updating this value immediately updates the control in the
@ -46,12 +46,12 @@ touch bar. Possible values:
* `outline` - Maps to `[NSScrubberSelectionStyle outlineOverlayStyle]` * `outline` - Maps to `[NSScrubberSelectionStyle outlineOverlayStyle]`
* `null` - Actually null, not a string, removes all styles * `null` - Actually null, not a string, removes all styles
#### `touchBarSegmentedControl.showArrowButtons` #### `touchBarScrubber.showArrowButtons`
A `Boolean` representing whether to show the left / right selection arrows in this scrubber. Updating this value A `Boolean` representing whether to show the left / right selection arrows in this scrubber. Updating this value
immediately updates the control in the touch bar. immediately updates the control in the touch bar.
#### `touchBarSegmentedControl.mode` #### `touchBarScrubber.mode`
A `String` representing the mode of this scrubber. Updating this value immediately A `String` representing the mode of this scrubber. Updating this value immediately
updates the control in the touch bar. Possible values: updates the control in the touch bar. Possible values:
@ -59,7 +59,7 @@ updates the control in the touch bar. Possible values:
* `fixed` - Maps to `NSScrubberModeFixed` * `fixed` - Maps to `NSScrubberModeFixed`
* `free` - Maps to `NSScrubberModeFree` * `free` - Maps to `NSScrubberModeFree`
#### `touchBarSegmentedControl.continuous` #### `touchBarScrubber.continuous`
A `Boolean` representing whether this scrubber is continuous or not. Updating this value immediately A `Boolean` representing whether this scrubber is continuous or not. Updating this value immediately
updates the control in the touch bar. updates the control in the touch bar.

View file

@ -1,4 +1,4 @@
# Class: TouchBar ## Class: TouchBar
> Create TouchBar layouts for native macOS applications > Create TouchBar layouts for native macOS applications

View file

@ -8,10 +8,10 @@ Follow the guidelines below for building Electron on Linux.
* Python 2.7.x. Some distributions like CentOS 6.x still use Python 2.6.x * Python 2.7.x. Some distributions like CentOS 6.x still use Python 2.6.x
so you may need to check your Python version with `python -V`. so you may need to check your Python version with `python -V`.
* Node.js. There are various ways to install Node. You can download * Node.js. There are various ways to install Node. You can download
source code from [Node.js](http://nodejs.org) and compile from source. source code from [nodejs.org](http://nodejs.org) and compile it.
Doing so permits installing Node on your own home directory as a standard user. Doing so permits installing Node on your own home directory as a standard user.
Or try repositories such as [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories). Or try repositories such as [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories).
* Clang 3.4 or later. * [clang](https://clang.llvm.org/get_started.html) 3.4 or later.
* Development headers of GTK+ and libnotify. * Development headers of GTK+ and libnotify.
On Ubuntu, install the following libraries: On Ubuntu, install the following libraries:
@ -48,7 +48,7 @@ managers such as pacman. Or one can compile from source code.
## Getting the Code ## Getting the Code
```bash ```bash
$ git clone https://github.com/electron/electron.git $ git clone https://github.com/electron/electron
``` ```
## Bootstrapping ## Bootstrapping
@ -60,7 +60,7 @@ Downloading certain files can take a long time. Notice that we are using
```bash ```bash
$ cd electron $ cd electron
$ ./script/bootstrap.py -v $ ./script/bootstrap.py --verbose
``` ```
### Cross compilation ### Cross compilation
@ -73,7 +73,7 @@ $ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \
g++-arm-linux-gnueabihf g++-arm-linux-gnueabihf
``` ```
And to cross compile for `arm` or `ia32` targets, you should pass the And to cross-compile for `arm` or `ia32` targets, you should pass the
`--target_arch` parameter to the `bootstrap.py` script: `--target_arch` parameter to the `bootstrap.py` script:
```bash ```bash
@ -98,7 +98,7 @@ $ ./script/create-dist.py
``` ```
This will put a working distribution with much smaller file sizes in This will put a working distribution with much smaller file sizes in
the `dist` directory. After running the create-dist.py script, you the `dist` directory. After running the `create-dist.py` script, you
may want to remove the 1.3+ gigabyte binary which is still in `out/R`. may want to remove the 1.3+ gigabyte binary which is still in `out/R`.
You can also build the `Debug` target only: You can also build the `Debug` target only:
@ -143,17 +143,29 @@ See [Build System Overview: Tests](build-system-overview.md#tests)
## Advanced topics ## Advanced topics
The default building configuration is targeted for major desktop Linux The default building configuration is targeted for major desktop Linux
distributions, to build for a specific distribution or device, following distributions. To build for a specific distribution or device, the following
information may help you. information may help you.
### Building `libchromiumcontent` locally ### Building `libchromiumcontent` locally
To avoid using the prebuilt binaries of `libchromiumcontent`, you can pass the To avoid using the prebuilt binaries of `libchromiumcontent`, you can build `libchromiumcontent` locally. To do so, follow these steps:
`--build_libchromiumcontent` switch to `bootstrap.py` script: 1. Install [depot_tools](https://chromium.googlesource.com/chromium/src/+/master/docs/linux_build_instructions.md#Install)
2. Install [additional build dependencies](https://chromium.googlesource.com/chromium/src/+/master/docs/linux_build_instructions.md#Install-additional-build-dependencies)
3. Fetch the git submodules:
```bash
$ git submodule update --init --recursive
```
4. Copy the .gclient config file
```bash ```bash
$ ./script/bootstrap.py -v --build_libchromiumcontent $ cp vendor/libchromiumcontent/.gclient .
``` ```
5. Pass the `--build_libchromiumcontent` switch to `bootstrap.py` script:
```bash
$ ./script/bootstrap.py -v --build_libchromiumcontent
```
Note that by default the `shared_library` configuration is not built, so you can Note that by default the `shared_library` configuration is not built, so you can
only build `Release` version of Electron if you use this mode: only build `Release` version of Electron if you use this mode:
@ -164,10 +176,12 @@ $ ./script/build.py -c R
### Using system `clang` instead of downloaded `clang` binaries ### Using system `clang` instead of downloaded `clang` binaries
By default Electron is built with prebuilt `clang` binaries provided by Chromium By default Electron is built with prebuilt
project. If for some reason you want to build with the `clang` installed in your [`clang`](https://clang.llvm.org/get_started.html) binaries provided by the
system, you can call `bootstrap.py` with `--clang_dir=<path>` switch. By passing Chromium project. If for some reason you want to build with the `clang`
it the build script will assume the `clang` binaries reside in `<path>/bin/`. installed in your system, you can call `bootstrap.py` with `--clang_dir=<path>`
switch. By passing it the build script will assume the `clang` binaries reside
in `<path>/bin/`.
For example if you installed `clang` under `/user/local/bin/clang`: For example if you installed `clang` under `/user/local/bin/clang`:
@ -176,7 +190,7 @@ $ ./script/bootstrap.py -v --build_libchromiumcontent --clang_dir /usr/local
$ ./script/build.py -c R $ ./script/build.py -c R
``` ```
### Using other compilers other than `clang` ### Using compilers other than `clang`
To build Electron with compilers like `g++`, you first need to disable `clang` To build Electron with compilers like `g++`, you first need to disable `clang`
with `--disable_clang` switch first, and then set `CC` and `CXX` environment with `--disable_clang` switch first, and then set `CC` and `CXX` environment
@ -209,4 +223,4 @@ custom the building configurations:
* `LDFLAGS` * `LDFLAGS`
The environment variables have to be set when executing the `bootstrap.py` The environment variables have to be set when executing the `bootstrap.py`
script, it won't work in the `build.py` script. script, it won't work in the `build.py` script.

View file

@ -12,11 +12,9 @@ The ASAR format was created primarily to improve performance on Windows... TODO
### Brightray ### Brightray
Brightray is a static library that makes [libchromiumcontent] Brightray [was](https://github.com/electron-archive/brightray) a static library
easier to use in applications. that made [libchromiumcontent] easier to use in applications. It is now
deprecated and has been merged into Electron's codebase.
Brightray is a low-level dependency of Electron that does not concern the
majority of Electron users.
### CRT ### CRT
@ -44,8 +42,10 @@ serialized JSON messages between the [main] and [renderer] processes.
### libchromiumcontent ### libchromiumcontent
A single, shared library that includes the Chromium Content module and all its A shared library that includes the [Chromium Content module] and all its
dependencies (e.g., Blink, [V8], etc.). dependencies (e.g., Blink, [V8], etc.). Also referred to as "libcc".
- [github.com/electron/libchromiumcontent](https://github.com/electron/libchromiumcontent)
### main process ### main process
@ -142,8 +142,17 @@ available in "core".
### V8 ### V8
V8 is Google's open source JavaScript engine. It is written in C++ and is V8 is Google's open source JavaScript engine. It is written in C++ and is
used in Google Chrome. V8 can run used in Google Chrome. V8 can run standalone, or can be embedded into any C++ application.
standalone, or can be embedded into any C++ application.
Electron builds V8 as part of Chromium and then points Node to that V8 when
building it.
V8's version numbers always correspond to those of Google Chrome. Chrome 59
includes V8 5.9, Chrome 58 includes V8 5.8, etc.
- [developers.google.com/v8](https://developers.google.com/v8)
- [nodejs.org/api/v8.html](https://nodejs.org/api/v8.html)
- [docs/development/v8-development.md](development/v8-development.md)
### webview ### webview
@ -157,11 +166,12 @@ embedded content.
[addons]: https://nodejs.org/api/addons.html [addons]: https://nodejs.org/api/addons.html
[asar]: https://github.com/electron/asar [asar]: https://github.com/electron/asar
[autoUpdater]: api/auto-updater.md [autoUpdater]: api/auto-updater.md
[Chromium Content module]: https://www.chromium.org/developers/content-module
[electron-builder]: https://github.com/electron-userland/electron-builder [electron-builder]: https://github.com/electron-userland/electron-builder
[libchromiumcontent]: #libchromiumcontent [libchromiumcontent]: #libchromiumcontent
[Mac App Store Submission Guide]: tutorial/mac-app-store-submission-guide.md [Mac App Store Submission Guide]: tutorial/mac-app-store-submission-guide.md
[main]: #main-process [main]: #main-process
[renderer]: #renderer-process [renderer]: #renderer-process
[Using Native Node Modules]: tutorial/using-native-node-modules.md
[userland]: #userland [userland]: #userland
[Using Native Node Modules]: tutorial/using-native-node-modules.md
[V8]: #v8 [V8]: #v8

View file

@ -292,7 +292,7 @@ TouchBar.TouchBarScrubber = class TouchBarScrubber extends TouchBarItem {
this._addLiveProperty('overlayStyle', overlayStyle || null) this._addLiveProperty('overlayStyle', overlayStyle || null)
this._addLiveProperty('showArrowButtons', showArrowButtons || false) this._addLiveProperty('showArrowButtons', showArrowButtons || false)
this._addLiveProperty('mode', mode || 'free') this._addLiveProperty('mode', mode || 'free')
this._addLiveProperty('continuous', continuous || true) this._addLiveProperty('continuous', typeof continuous === 'undefined' ? true : continuous)
if (typeof select === 'function' || typeof highlight === 'function') { if (typeof select === 'function' || typeof highlight === 'function') {
if (select == null) select = () => {} if (select == null) select = () => {}

View file

@ -18,14 +18,20 @@ LINUX_DEPS = [
'libnotify-dev', 'libnotify-dev',
'libnss3-dev', 'libnss3-dev',
'libxtst-dev', 'libxtst-dev',
]
LINUX_DEPS_NO_ARM = [
'gcc-multilib', 'gcc-multilib',
'g++-multilib', 'g++-multilib',
] ]
LINUX_DEPS_ARM = [ LINUX_DEPS_ARM = [
'libc6-dev-armhf-cross', 'binutils-aarch64-linux-gnu',
'linux-libc-dev-armhf-cross', 'libc6-dev-armhf-cross',
'g++-arm-linux-gnueabihf', 'linux-libc-dev-armhf-cross',
'g++-arm-linux-gnueabihf',
'g++-4.8-multilib-arm-linux-gnueabihf',
'gcc-4.8-multilib-arm-linux-gnueabihf',
] ]
@ -53,6 +59,8 @@ def main():
deps = LINUX_DEPS deps = LINUX_DEPS
if target_arch == 'arm': if target_arch == 'arm':
deps += LINUX_DEPS_ARM deps += LINUX_DEPS_ARM
else:
deps += LINUX_DEPS_NO_ARM
execute(['sudo', 'apt-get', 'install'] + deps) execute(['sudo', 'apt-get', 'install'] + deps)
execute(['sh', '-e', '/etc/init.d/xvfb', 'start']) execute(['sh', '-e', '/etc/init.d/xvfb', 'start'])

View file

@ -81,6 +81,14 @@ def parse_args():
help='Run tests in CI mode', help='Run tests in CI mode',
action='store_true', action='store_true',
required=False) required=False)
parser.add_argument('-g', '--grep',
help='Only run tests matching <pattern>',
metavar='pattern',
required=False)
parser.add_argument('-i', '--invert',
help='Inverts --grep matches',
action='store_true',
required=False)
parser.add_argument('-v', '--verbose', parser.add_argument('-v', '--verbose',
action='store_true', action='store_true',
help='Prints the output of the subprocesses') help='Prints the output of the subprocesses')

View file

@ -208,7 +208,7 @@ describe('app module', function () {
}) })
}) })
describe('app.importCertificate', function () { xdescribe('app.importCertificate', function () {
if (process.platform !== 'linux') return if (process.platform !== 'linux') return
var w = null var w = null
@ -405,7 +405,7 @@ describe('app module', function () {
}) })
}) })
describe('select-client-certificate event', function () { xdescribe('select-client-certificate event', function () {
let w = null let w = null
beforeEach(function () { beforeEach(function () {

View file

@ -100,4 +100,14 @@ describe('BrowserView module', function () {
assert.ok(!view.webContents.getOwnerBrowserWindow()) assert.ok(!view.webContents.getOwnerBrowserWindow())
}) })
}) })
describe('BrowserView.fromId()', function () {
it('returns the view with given id', function () {
view = new BrowserView()
w.setBrowserView(view)
assert.notEqual(view.id, null)
let view2 = BrowserView.fromId(view.id)
assert.equal(view2.webContents.id, view.webContents.id)
})
})
}) })

View file

@ -1144,13 +1144,16 @@ describe('BrowserWindow module', function () {
w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?window-events')) w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?window-events'))
}) })
it('works for web contents events', function (done) { it('works for stop events', function (done) {
waitForEvents(w.webContents, [ waitForEvents(w.webContents, [
'did-navigate', 'did-navigate',
'did-fail-load', 'did-fail-load',
'did-stop-loading' 'did-stop-loading'
], done) ], done)
w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?webcontents-stop')) w.loadURL('file://' + path.join(fixtures, 'api', 'sandbox.html?webcontents-stop'))
})
it('works for web contents events', function (done) {
waitForEvents(w.webContents, [ waitForEvents(w.webContents, [
'did-finish-load', 'did-finish-load',
'did-frame-finish-load', 'did-frame-finish-load',

View file

@ -12,7 +12,7 @@ const {remote} = require('electron')
const {app, BrowserWindow, crashReporter} = remote.require('electron') const {app, BrowserWindow, crashReporter} = remote.require('electron')
describe('crashReporter module', function () { describe('crashReporter module', function () {
if (process.mas) { if (process.mas || process.env.DISABLE_CRASH_REPORTER_TESTS) {
return return
} }

View file

@ -590,6 +590,12 @@ describe('webContents module', function () {
}) })
describe('destroy()', () => { describe('destroy()', () => {
// Destroying webContents in its event listener is going to crash when
// Electron is built in Debug mode.
if (process.platform !== 'darwin') {
return
}
let server let server
before(function (done) { before(function (done) {

View file

@ -62,16 +62,17 @@
if (query.invert) mocha.invert(); if (query.invert) mocha.invert();
// Read all test files. // Read all test files.
var walker = require('walkdir').walk(require('path').dirname(__dirname), { var walker = require('walkdir').walk(path.dirname(__dirname), {
no_recurse: true no_recurse: true
}); });
walker.on('file', function(file) { walker.on('file', function(file) {
if (/-spec\.js$/.test(file)) if (/-spec\.js$/.test(file) && !file.includes('api-crash-reporter-spec.js'))
mocha.addFile(file); mocha.addFile(file);
}); });
walker.on('end', function() { walker.on('end', function() {
mocha.addFile(path.resolve(__dirname, '..', 'api-crash-reporter-spec.js'))
var runner = mocha.run(function() { var runner = mocha.run(function() {
if (isCi && runner.hasOnly) { if (isCi && runner.hasOnly) {
try { try {

View file

@ -141,6 +141,10 @@ app.on('ready', function () {
}) })
if (chosen === 0) window.destroy() if (chosen === 0) window.destroy()
}) })
window.webContents.on('crashed', function () {
console.error('Renderer process crashed')
process.exit(1)
})
// For session's download test, listen 'will-download' event in browser, and // For session's download test, listen 'will-download' event in browser, and
// reply the result to renderer for verifying // reply the result to renderer for verifying