mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1f8fda78a | ||
|
|
6b890d2a44 | ||
|
|
a287b086d0 | ||
|
|
16cbd94b27 | ||
|
|
9ba95e2018 | ||
|
|
7ba432113f | ||
|
|
48fe0649cb | ||
|
|
d9afe43cee | ||
|
|
c74d7b3c33 | ||
|
|
f26dcaeaf3 | ||
|
|
d08f47510d | ||
|
|
3928b7cba8 | ||
|
|
48a279cbb5 | ||
|
|
266f5a24cd | ||
|
|
79b6e6f1af | ||
|
|
3db872e004 | ||
|
|
028c807975 | ||
|
|
ce5a440d9f | ||
|
|
556e15fcb9 | ||
|
|
3d4bedda0c | ||
|
|
a7f23b862b | ||
|
|
68ae725b47 | ||
|
|
f2c1f255ef | ||
|
|
2046d8052a | ||
|
|
6de26d3b4a | ||
|
|
688b345033 | ||
|
|
10b642506f | ||
|
|
b8c8a6f4b9 | ||
|
|
ab4fa2a820 |
2
DEPS
2
DEPS
@@ -2,7 +2,7 @@ vars = {
|
||||
'chromium_version':
|
||||
'63.0.3239.150',
|
||||
'libchromiumcontent_revision':
|
||||
'd9e39391cfae447a84e276a402342cf8b4b5bcba',
|
||||
'1b74a92a80c2077fb0848d81b58ee6f0e4db752d',
|
||||
'node_version':
|
||||
'v9.7.0-33-g538a5023af',
|
||||
'native_mate_revision':
|
||||
|
||||
@@ -24,10 +24,14 @@
|
||||
#include "base/win/windows_version.h"
|
||||
#include "content/public/app/sandbox_helper_win.h"
|
||||
#include "sandbox/win/src/sandbox_types.h"
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include "atom/app/atom_main_delegate.h" // NOLINT
|
||||
#include "content/public/app/content_main.h"
|
||||
#else // defined(OS_LINUX)
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include "atom/app/atom_library_main.h"
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
@@ -55,6 +59,25 @@ bool IsEnvSet(const char* name) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
void FixStdioStreams() {
|
||||
// libuv may mark stdin/stdout/stderr as close-on-exec, which interferes
|
||||
// with chromium's subprocess spawning. As a workaround, we detect if these
|
||||
// streams are closed on startup, and reopen them as /dev/null if necessary.
|
||||
// Otherwise, an unrelated file descriptor will be assigned as stdout/stderr
|
||||
// which may cause various errors when attempting to write to them.
|
||||
//
|
||||
// For details see https://github.com/libuv/libuv/issues/2062
|
||||
struct stat st;
|
||||
if (fstat(STDIN_FILENO, &st) < 0 && errno == EBADF)
|
||||
freopen("/dev/null", "r", stdin);
|
||||
if (fstat(STDOUT_FILENO, &st) < 0 && errno == EBADF)
|
||||
freopen("/dev/null", "w", stdout);
|
||||
if (fstat(STDERR_FILENO, &st) < 0 && errno == EBADF)
|
||||
freopen("/dev/null", "w", stderr);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -157,6 +180,8 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef ENABLE_RUN_AS_NODE
|
||||
FixStdioStreams();
|
||||
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
base::i18n::InitializeICU();
|
||||
base::AtExitManager atexit_manager;
|
||||
@@ -176,6 +201,8 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef ENABLE_RUN_AS_NODE
|
||||
FixStdioStreams();
|
||||
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
return AtomInitializeICUandStartNode(argc, argv);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,12 @@ void BrowserWindow::OverrideNSWindowContentView(
|
||||
NSView* webView = iwc->GetView()->GetNativeView();
|
||||
NSView* contentView = [window()->GetNativeWindow() contentView];
|
||||
[webView setFrame:[contentView bounds]];
|
||||
[contentView addSubview:webView];
|
||||
|
||||
// ensure that buttons view is floated to top of view hierarchy
|
||||
NSArray* subviews = [contentView subviews];
|
||||
NSView* last = subviews.lastObject;
|
||||
[contentView addSubview:webView positioned:NSWindowBelow relativeTo:last];
|
||||
|
||||
[contentView viewDidMoveToWindow];
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "content/public/browser/tracing_controller.h"
|
||||
@@ -23,15 +24,27 @@ struct Converter<base::trace_event::TraceConfig> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::trace_event::TraceConfig* out) {
|
||||
// (alexeykuzmin): A combination of "categoryFilter" and "traceOptions"
|
||||
// has to be checked first because none of the fields
|
||||
// in the `memory_dump_config` dict below are mandatory
|
||||
// and we cannot check the config format.
|
||||
Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
std::string category_filter, trace_options;
|
||||
if (!options.Get("categoryFilter", &category_filter) ||
|
||||
!options.Get("traceOptions", &trace_options))
|
||||
return false;
|
||||
*out = base::trace_event::TraceConfig(category_filter, trace_options);
|
||||
return true;
|
||||
if (ConvertFromV8(isolate, val, &options)) {
|
||||
std::string category_filter, trace_options;
|
||||
if (options.Get("categoryFilter", &category_filter) &&
|
||||
options.Get("traceOptions", &trace_options)) {
|
||||
*out = base::trace_event::TraceConfig(category_filter, trace_options);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
base::DictionaryValue memory_dump_config;
|
||||
if (ConvertFromV8(isolate, val, &memory_dump_config)) {
|
||||
*out = base::trace_event::TraceConfig(memory_dump_config);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ void NativeBrowserViewViews::SetBounds(const gfx::Rect& bounds) {
|
||||
void NativeBrowserViewViews::SetBackgroundColor(SkColor color) {
|
||||
auto* view = GetInspectableWebContentsView()->GetView();
|
||||
view->SetBackground(views::CreateSolidBackground(color));
|
||||
view->SchedulePaint();
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -74,9 +74,7 @@
|
||||
forStyleMask:NSTitledWindowMask];
|
||||
NSButton* miniaturize_button =
|
||||
[NSWindow standardWindowButton:NSWindowMiniaturizeButton
|
||||
forStyleMask:NSTitledWindowMask];
|
||||
NSButton* zoom_button = [NSWindow standardWindowButton:NSWindowZoomButton
|
||||
forStyleMask:NSTitledWindowMask];
|
||||
forStyleMask:NSWindowStyleMaskTitled];
|
||||
|
||||
CGFloat x = 0;
|
||||
const CGFloat space_between = 20;
|
||||
@@ -89,11 +87,7 @@
|
||||
x += space_between;
|
||||
[self addSubview:miniaturize_button];
|
||||
|
||||
[zoom_button setFrameOrigin:NSMakePoint(x, 0)];
|
||||
x += space_between;
|
||||
[self addSubview:zoom_button];
|
||||
|
||||
const auto last_button_frame = zoom_button.frame;
|
||||
const auto last_button_frame = miniaturize_button.frame;
|
||||
[self setFrameSize:NSMakeSize(last_button_frame.origin.x +
|
||||
last_button_frame.size.width,
|
||||
last_button_frame.size.height)];
|
||||
@@ -478,7 +472,8 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
|
||||
}
|
||||
|
||||
NativeWindowMac::~NativeWindowMac() {
|
||||
[NSEvent removeMonitor:wheel_event_monitor_];
|
||||
if (wheel_event_monitor_)
|
||||
[NSEvent removeMonitor:wheel_event_monitor_];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetContentView(views::View* view) {
|
||||
@@ -515,6 +510,13 @@ void NativeWindowMac::Close() {
|
||||
}
|
||||
|
||||
void NativeWindowMac::CloseImmediately() {
|
||||
// Remove event monitor before destroying window, otherwise the monitor may
|
||||
// call its callback after window has been destroyed.
|
||||
if (wheel_event_monitor_) {
|
||||
[NSEvent removeMonitor:wheel_event_monitor_];
|
||||
wheel_event_monitor_ = nil;
|
||||
}
|
||||
|
||||
// Retain the child window before closing it. If the last reference to the
|
||||
// NSWindow goes away inside -[NSWindow close], then bad stuff can happen.
|
||||
// See e.g. http://crbug.com/616701.
|
||||
@@ -1356,6 +1358,8 @@ void NativeWindowMac::AddContentViewLayers() {
|
||||
if (title_bar_style_ == CUSTOM_BUTTONS_ON_HOVER) {
|
||||
buttons_view_.reset(
|
||||
[[CustomWindowButtonView alloc] initWithFrame:NSZeroRect]);
|
||||
// NSWindowStyleMaskFullSizeContentView does not work with zoom button
|
||||
SetFullScreenable(false);
|
||||
[[window_ contentView] addSubview:buttons_view_];
|
||||
} else {
|
||||
if (title_bar_style_ != NORMAL) {
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3.0.10</string>
|
||||
<string>3.0.14</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.0.10</string>
|
||||
<string>3.0.14</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -56,8 +56,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,0,10,0
|
||||
PRODUCTVERSION 3,0,10,0
|
||||
FILEVERSION 3,0,14,0
|
||||
PRODUCTVERSION 3,0,14,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -74,12 +74,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "3.0.10"
|
||||
VALUE "FileVersion", "3.0.14"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "3.0.10"
|
||||
VALUE "ProductVersion", "3.0.14"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "atom/browser/ui/views/menu_bar.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/ui/views/menu_delegate.h"
|
||||
#include "atom/browser/ui/views/submenu_button.h"
|
||||
@@ -129,13 +128,11 @@ void MenuBar::RefreshColorCache(const ui::NativeTheme* theme) {
|
||||
theme = ui::NativeTheme::GetInstanceForNativeUi();
|
||||
if (theme) {
|
||||
#if defined(USE_X11)
|
||||
const std::string menubar_selector = "GtkMenuBar#menubar";
|
||||
background_color_ = libgtkui::GetBgColor(menubar_selector);
|
||||
|
||||
enabled_color_ = theme->GetSystemColor(
|
||||
ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor);
|
||||
disabled_color_ = theme->GetSystemColor(
|
||||
ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor);
|
||||
background_color_ = libgtkui::GetBgColor("GtkMenuBar#menubar");
|
||||
enabled_color_ = libgtkui::GetFgColor(
|
||||
"GtkMenuBar#menubar GtkMenuItem#menuitem GtkLabel");
|
||||
disabled_color_ = libgtkui::GetFgColor(
|
||||
"GtkMenuBar#menubar GtkMenuItem#menuitem:disabled GtkLabel");
|
||||
#else
|
||||
background_color_ =
|
||||
theme->GetSystemColor(ui::NativeTheme::kColorId_MenuBackgroundColor);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#define ATOM_MAJOR_VERSION 3
|
||||
#define ATOM_MINOR_VERSION 0
|
||||
#define ATOM_PATCH_VERSION 10
|
||||
#define ATOM_PATCH_VERSION 14
|
||||
// #define ATOM_PRE_RELEASE_VERSION
|
||||
|
||||
#ifndef ATOM_STRINGIFY
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/sys_info.h"
|
||||
|
||||
extern "C" {
|
||||
#include "vendor/node/deps/uv/src/win/internal.h"
|
||||
@@ -15,7 +16,20 @@ extern "C" {
|
||||
namespace atom {
|
||||
|
||||
NodeBindingsWin::NodeBindingsWin(BrowserEnvironment browser_env)
|
||||
: NodeBindings(browser_env) {}
|
||||
: NodeBindings(browser_env) {
|
||||
// on single-core the io comp port NumberOfConcurrentThreads needs to be 2
|
||||
// to avoid cpu pegging likely caused by a busy loop in PollEvents
|
||||
if (base::SysInfo::NumberOfProcessors() == 1) {
|
||||
// the expectation is the uv_loop_ has just been initialized
|
||||
// which makes iocp replacement safe
|
||||
CHECK_EQ(0u, uv_loop_->active_handles);
|
||||
CHECK_EQ(0u, uv_loop_->active_reqs.count);
|
||||
|
||||
if (uv_loop_->iocp && uv_loop_->iocp != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(uv_loop_->iocp);
|
||||
uv_loop_->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
NodeBindingsWin::~NodeBindingsWin() {}
|
||||
|
||||
|
||||
@@ -222,11 +222,11 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
the top left.
|
||||
* `hiddenInset` - Results in a hidden title bar with an alternative look
|
||||
where the traffic light buttons are slightly more inset from the window edge.
|
||||
* `customButtonsOnHover` Boolean (optional) - Draw custom close, minimize,
|
||||
and full screen buttons on macOS frameless windows. These buttons will not
|
||||
display unless hovered over in the top left of the window. These custom
|
||||
buttons prevent issues with mouse events that occur with the standard
|
||||
window toolbar buttons. **Note:** This option is currently experimental.
|
||||
* `customButtonsOnHover` Boolean (optional) - Draw custom close,
|
||||
and minimize buttons on macOS frameless windows. These buttons will not display
|
||||
unless hovered over in the top left of the window. These custom buttons prevent
|
||||
issues with mouse events that occur with the standard window toolbar buttons.
|
||||
**Note:** This option is currently experimental.
|
||||
* `fullscreenWindowTitle` Boolean (optional) - Shows the title in the
|
||||
title bar in full screen mode on macOS for all `titleBarStyle` options.
|
||||
Default is `false`.
|
||||
|
||||
@@ -51,9 +51,7 @@ Once all child processes have acknowledged the `getCategories` request the
|
||||
|
||||
### `contentTracing.startRecording(options, callback)`
|
||||
|
||||
* `options` Object
|
||||
* `categoryFilter` String
|
||||
* `traceOptions` String
|
||||
* `options` ([TraceCategoriesAndOptions](structures/trace-categories-and-options.md) | [TraceConfig](structures/trace-config.md))
|
||||
* `callback` Function
|
||||
|
||||
Start recording on all processes.
|
||||
@@ -62,35 +60,6 @@ Recording begins immediately locally and asynchronously on child processes
|
||||
as soon as they receive the EnableRecording request. The `callback` will be
|
||||
called once all child processes have acknowledged the `startRecording` request.
|
||||
|
||||
`categoryFilter` is a filter to control what category groups should be
|
||||
traced. A filter can have an optional `-` prefix to exclude category groups
|
||||
that contain a matching category. Having both included and excluded
|
||||
category patterns in the same list is not supported.
|
||||
|
||||
Examples:
|
||||
|
||||
* `test_MyTest*`,
|
||||
* `test_MyTest*,test_OtherStuff`,
|
||||
* `"-excluded_category1,-excluded_category2`
|
||||
|
||||
`traceOptions` controls what kind of tracing is enabled, it is a comma-delimited
|
||||
list. Possible options are:
|
||||
|
||||
* `record-until-full`
|
||||
* `record-continuously`
|
||||
* `trace-to-console`
|
||||
* `enable-sampling`
|
||||
* `enable-systrace`
|
||||
|
||||
The first 3 options are trace recording modes and hence mutually exclusive.
|
||||
If more than one trace recording modes appear in the `traceOptions` string,
|
||||
the last one takes precedence. If none of the trace recording modes are
|
||||
specified, recording mode is `record-until-full`.
|
||||
|
||||
The trace option will first be reset to the default option (`record_mode` set to
|
||||
`record-until-full`, `enable_sampling` and `enable_systrace` set to `false`)
|
||||
before options parsed from `traceOptions` are applied on it.
|
||||
|
||||
### `contentTracing.stopRecording(resultFilePath, callback)`
|
||||
|
||||
* `resultFilePath` String
|
||||
|
||||
@@ -50,10 +50,12 @@ win.show()
|
||||
|
||||
#### `customButtonsOnHover`
|
||||
|
||||
Uses custom drawn close, miniaturize, and fullscreen buttons that display
|
||||
when hovering in the top left of the window. These custom buttons prevent issues
|
||||
with mouse events that occur with the standard window toolbar buttons. This
|
||||
option is only applicable for frameless windows.
|
||||
Uses custom drawn close, and miniaturize buttons that display
|
||||
when hovering in the top left of the window. The fullscreen button
|
||||
is not available due to restrictions of frameless windows as they
|
||||
interface with Apple's MacOS window masks. These custom buttons prevent
|
||||
issues with mouse events that occur with the standard window toolbar buttons.
|
||||
This option is only applicable for frameless windows.
|
||||
|
||||
```javascript
|
||||
const {BrowserWindow} = require('electron')
|
||||
|
||||
18
docs/api/structures/trace-categories-and-options.md
Normal file
18
docs/api/structures/trace-categories-and-options.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# TraceCategoriesAndOptions Object
|
||||
|
||||
* `categoryFilter` String – is a filter to control what category groups
|
||||
should be traced. A filter can have an optional `-` prefix to exclude
|
||||
category groups that contain a matching category. Having both included
|
||||
and excluded category patterns in the same list is not supported. Examples:
|
||||
`test_MyTest*`, `test_MyTest*,test_OtherStuff`, `-excluded_category1,-excluded_category2`.
|
||||
* `traceOptions` String - Controls what kind of tracing is enabled,
|
||||
it is a comma-delimited sequence of the following strings:
|
||||
`record-until-full`, `record-continuously`, `trace-to-console`, `enable-sampling`, `enable-systrace`,
|
||||
e.g. `'record-until-full,enable-sampling'`.
|
||||
The first 3 options are trace recording modes and hence mutually exclusive.
|
||||
If more than one trace recording modes appear in the `traceOptions` string,
|
||||
the last one takes precedence. If none of the trace recording modes are
|
||||
specified, recording mode is `record-until-full`.
|
||||
The trace option will first be reset to the default option (`record_mode` set
|
||||
to `record-until-full`, `enable_sampling` and `enable_systrace`
|
||||
set to `false`) before options parsed from `traceOptions` are applied on it.
|
||||
9
docs/api/structures/trace-config.md
Normal file
9
docs/api/structures/trace-config.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# TraceConfig Object
|
||||
|
||||
* `included_categories` String[] (optional)
|
||||
* `excluded_categories` String[] (optional)
|
||||
* `memory_dump_config` Object (optional)
|
||||
|
||||
See an example in the [Chromium docs][1].
|
||||
|
||||
[1]: https://chromium.googlesource.com/chromium/src/+/master/docs/memory-infra/memory_infra_startup_tracing.md#the-advanced-way
|
||||
@@ -36,26 +36,7 @@ the following Python modules:
|
||||
If you're developing Electron and don't plan to redistribute your
|
||||
custom Electron build, you may skip this section.
|
||||
|
||||
For certain features (e.g. pinch-zoom) to work properly, you must target the
|
||||
macOS 10.10 SDK.
|
||||
|
||||
Official Electron builds are built with [Xcode 8.2.1](http://adcdownload.apple.com/Developer_Tools/Xcode_8.2.1/Xcode_8.2.1.xip), which does not contain
|
||||
the 10.10 SDK by default. To obtain it, first download and mount the
|
||||
[Xcode 6.4](http://developer.apple.com/devcenter/download.action?path=/Developer_Tools/Xcode_6.4/Xcode_6.4.dmg)
|
||||
DMG.
|
||||
|
||||
Then, assuming that the Xcode 6.4 DMG has been mounted at `/Volumes/Xcode` and
|
||||
that your Xcode 8.2.1 install is at `/Applications/Xcode.app`, run:
|
||||
|
||||
```sh
|
||||
cp -r /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
|
||||
```
|
||||
|
||||
You will also need to enable Xcode to build against the 10.10 SDK:
|
||||
|
||||
- Open `/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Info.plist`
|
||||
- Set the `MinimumSDKVersion` to `10.10`
|
||||
- Save the file
|
||||
Official Electron builds are built with [Xcode 8.3.3](http://adcdownload.apple.com/Developer_Tools/Xcode_8.3.3/Xcode_8.3.3.xip), and the MacOS 10.12 SDK. Building with a newer SDK works too, but the releases currently use the 10.12 SDK.
|
||||
|
||||
## Getting the Code
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '3.0.10',
|
||||
'version%': '3.0.14',
|
||||
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
|
||||
},
|
||||
'includes': [
|
||||
|
||||
@@ -424,7 +424,7 @@ app.once('ready', function () {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (process.env.ELECTRON_ENABLE_LOGGING) {
|
||||
if (process.env.ELECTRON_ENABLE_LOGGING && error.code !== 'ENOENT') {
|
||||
console.error('Failed to load browser extensions from directory:', loadedDevToolsExtensionsPath)
|
||||
console.error(error)
|
||||
}
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "3.0.9",
|
||||
"version": "3.0.13",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "3.0.10",
|
||||
"version": "3.0.14",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -149,7 +149,7 @@ async function createRelease (branchToTarget, isBeta) {
|
||||
console.log(`Checking for existing draft release.`)
|
||||
let releases = await github.repos.getReleases(githubOpts)
|
||||
.catch(err => {
|
||||
console.log('$fail} Could not get releases. Error was', err)
|
||||
console.log(`${fail} Could not get releases. Error was: `, err)
|
||||
})
|
||||
let drafts = releases.data.filter(release => release.draft &&
|
||||
release.tag_name === newVersion)
|
||||
@@ -180,13 +180,13 @@ async function createRelease (branchToTarget, isBeta) {
|
||||
}
|
||||
githubOpts.tag_name = newVersion
|
||||
githubOpts.target_commitish = newVersion.indexOf('nightly') !== -1 ? 'master' : branchToTarget
|
||||
console.log('creating release with github opts', githubOpts)
|
||||
await github.repos.createRelease(githubOpts)
|
||||
const release = await github.repos.createRelease(githubOpts)
|
||||
.catch(err => {
|
||||
console.log(`${fail} Error creating new release: `, err)
|
||||
process.exit(1)
|
||||
})
|
||||
console.log(`${pass} Draft release for ${newVersion} has been created.`)
|
||||
console.log(`Release has been created with id: ${release.data.id}.`)
|
||||
console.log(`${pass} Draft release for ${newVersion} successful.`)
|
||||
}
|
||||
|
||||
async function pushRelease (branch) {
|
||||
|
||||
@@ -50,13 +50,14 @@ async function revertBumpCommit (tag) {
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteDraft (tag, targetRepo) {
|
||||
async function deleteDraft (releaseID, targetRepo) {
|
||||
try {
|
||||
const result = await github.repos.getReleaseByTag({
|
||||
const result = await github.repos.getRelease({
|
||||
owner: 'electron',
|
||||
repo: targetRepo,
|
||||
tag
|
||||
id: parseInt(releaseID, 10)
|
||||
})
|
||||
console.log(result)
|
||||
if (!result.draft) {
|
||||
console.log(`Published releases cannot be deleted.`)
|
||||
process.exit(1)
|
||||
@@ -67,9 +68,9 @@ async function deleteDraft (tag, targetRepo) {
|
||||
release_id: result.id
|
||||
})
|
||||
}
|
||||
console.log(`Successfully deleted draft with tag ${tag} from ${targetRepo}`)
|
||||
console.log(`Successfully deleted draft with id ${releaseID} from ${targetRepo}`)
|
||||
} catch (err) {
|
||||
console.error(`Couldn't delete draft with tag ${tag} from ${targetRepo}: `, err)
|
||||
console.error(`Couldn't delete draft with id ${releaseID} from ${targetRepo}: `, err)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
@@ -89,18 +90,19 @@ async function deleteTag (tag, targetRepo) {
|
||||
}
|
||||
|
||||
async function cleanReleaseArtifacts () {
|
||||
const tag = args.tag
|
||||
const releaseID = args.releaseID
|
||||
const isNightly = args.tag.includes('nightly')
|
||||
|
||||
if (isNightly) {
|
||||
await deleteDraft(tag, 'nightlies')
|
||||
await deleteTag(tag, 'nightlies')
|
||||
await deleteDraft(releaseID, 'nightlies')
|
||||
await deleteTag(args.tag, 'nightlies')
|
||||
} else {
|
||||
await deleteDraft(tag, 'electron')
|
||||
console.log('we are here')
|
||||
await deleteDraft(releaseID, 'electron')
|
||||
}
|
||||
|
||||
await deleteTag(tag, 'electron')
|
||||
await revertBumpCommit(tag)
|
||||
await deleteTag(args.tag, 'electron')
|
||||
await revertBumpCommit(args.tag)
|
||||
|
||||
console.log('Failed release artifact cleanup complete')
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ function uploadToGitHub () {
|
||||
console.log(`Error uploading ${fileName} to GitHub, will retry. Error was:`, err)
|
||||
retry++
|
||||
github.repos.getRelease(githubOpts).then(release => {
|
||||
console.log('Got list of assets for existing release:')
|
||||
console.log(JSON.stringify(release.data.assets, null, ' '))
|
||||
let existingAssets = release.data.assets.filter(asset => asset.name === fileName)
|
||||
if (existingAssets.length > 0) {
|
||||
console.log(`${fileName} already exists; will delete before retrying upload.`)
|
||||
@@ -41,10 +43,15 @@ function uploadToGitHub () {
|
||||
owner: 'electron',
|
||||
repo: targetRepo,
|
||||
id: existingAssets[0].id
|
||||
}).then(uploadToGitHub).catch(uploadToGitHub)
|
||||
}).catch((deleteErr) => {
|
||||
console.log(`Failed to delete existing asset ${fileName}. Error was:`, deleteErr)
|
||||
}).then(uploadToGitHub)
|
||||
} else {
|
||||
console.log(`Current asset ${fileName} not found in existing assets; retrying upload.`)
|
||||
uploadToGitHub()
|
||||
}
|
||||
}).catch((getReleaseErr) => {
|
||||
console.log(`Fatal: Unable to get current release assets via getRelease! Error was:`, getReleaseErr)
|
||||
})
|
||||
} else {
|
||||
console.log(`Error retrying uploading ${fileName} to GitHub:`, err)
|
||||
|
||||
145
spec/api-content-tracing-spec.js
Normal file
145
spec/api-content-tracing-spec.js
Normal file
@@ -0,0 +1,145 @@
|
||||
const { remote } = require('electron')
|
||||
const chai = require('chai')
|
||||
const dirtyChai = require('dirty-chai')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const { expect } = chai
|
||||
const { app, contentTracing } = remote
|
||||
|
||||
chai.use(dirtyChai)
|
||||
|
||||
const timeout = async (milliseconds) => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, milliseconds)
|
||||
})
|
||||
}
|
||||
|
||||
const getPathInATempFolder = (filename) => {
|
||||
return path.join(app.getPath('temp'), filename)
|
||||
}
|
||||
|
||||
describe('contentTracing', () => {
|
||||
beforeEach(function () {
|
||||
// FIXME: The tests are skipped on arm/arm64.
|
||||
if (process.platform === 'linux' &&
|
||||
['arm', 'arm64'].includes(process.arch)) {
|
||||
this.skip()
|
||||
}
|
||||
})
|
||||
|
||||
const startRecording = async (options) => {
|
||||
return new Promise((resolve) => {
|
||||
contentTracing.startRecording(options, () => {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const stopRecording = async (filePath) => {
|
||||
return new Promise((resolve) => {
|
||||
contentTracing.stopRecording(filePath, (resultFilePath) => {
|
||||
resolve(resultFilePath)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const record = async (options, outputFilePath, recordTimeInMilliseconds = 1e3) => {
|
||||
await app.whenReady()
|
||||
|
||||
await startRecording(options)
|
||||
await timeout(recordTimeInMilliseconds)
|
||||
const resultFilePath = await stopRecording(outputFilePath)
|
||||
|
||||
return resultFilePath
|
||||
}
|
||||
|
||||
const outputFilePath = getPathInATempFolder('trace.json')
|
||||
beforeEach(() => {
|
||||
if (fs.existsSync(outputFilePath)) {
|
||||
fs.unlinkSync(outputFilePath)
|
||||
}
|
||||
})
|
||||
|
||||
describe('startRecording', function () {
|
||||
this.timeout(5e3)
|
||||
|
||||
const getFileSizeInKiloBytes = (filePath) => {
|
||||
const stats = fs.statSync(filePath)
|
||||
const fileSizeInBytes = stats.size
|
||||
const fileSizeInKiloBytes = fileSizeInBytes / 1024
|
||||
return fileSizeInKiloBytes
|
||||
}
|
||||
|
||||
it('accepts an empty config', async () => {
|
||||
const config = {}
|
||||
await record(config, outputFilePath)
|
||||
|
||||
expect(fs.existsSync(outputFilePath)).to.be.true()
|
||||
|
||||
const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath)
|
||||
expect(fileSizeInKiloBytes).to.be.above(0,
|
||||
`the trace output file is empty, check "${outputFilePath}"`)
|
||||
})
|
||||
|
||||
it('accepts a trace config', async () => {
|
||||
// (alexeykuzmin): All categories are excluded on purpose,
|
||||
// so only metadata gets into the output file.
|
||||
const config = {
|
||||
excluded_categories: ['*']
|
||||
}
|
||||
await record(config, outputFilePath)
|
||||
|
||||
expect(fs.existsSync(outputFilePath)).to.be.true()
|
||||
|
||||
// If the `excluded_categories` param above is not respected
|
||||
// the file size will be above 50KB.
|
||||
const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath)
|
||||
const expectedMaximumFileSize = 10 // Depends on a platform.
|
||||
|
||||
expect(fileSizeInKiloBytes).to.be.above(0,
|
||||
`the trace output file is empty, check "${outputFilePath}"`)
|
||||
expect(fileSizeInKiloBytes).to.be.below(expectedMaximumFileSize,
|
||||
`the trace output file is suspiciously large (${fileSizeInKiloBytes}KB),
|
||||
check "${outputFilePath}"`)
|
||||
})
|
||||
|
||||
it('accepts "categoryFilter" and "traceOptions" as a config', async () => {
|
||||
// (alexeykuzmin): All categories are excluded on purpose,
|
||||
// so only metadata gets into the output file.
|
||||
const config = {
|
||||
categoryFilter: '__ThisIsANonexistentCategory__',
|
||||
traceOptions: ''
|
||||
}
|
||||
await record(config, outputFilePath)
|
||||
|
||||
expect(fs.existsSync(outputFilePath)).to.be.true()
|
||||
|
||||
// If the `categoryFilter` param above is not respected
|
||||
// the file size will be above 50KB.
|
||||
const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath)
|
||||
const expectedMaximumFileSize = 10 // Depends on a platform.
|
||||
|
||||
expect(fileSizeInKiloBytes).to.be.above(0,
|
||||
`the trace output file is empty, check "${outputFilePath}"`)
|
||||
expect(fileSizeInKiloBytes).to.be.below(expectedMaximumFileSize,
|
||||
`the trace output file is suspiciously large (${fileSizeInKiloBytes}KB),
|
||||
check "${outputFilePath}"`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('stopRecording', function () {
|
||||
this.timeout(5e3)
|
||||
|
||||
it('calls its callback with a result file path', async () => {
|
||||
const resultFilePath = await record(/* options */ {}, outputFilePath)
|
||||
expect(resultFilePath).to.be.a('string').and.be.equal(outputFilePath)
|
||||
})
|
||||
|
||||
// FIXME(alexeykuzmin): https://github.com/electron/electron/issues/16019
|
||||
xit('creates a temporary file when an empty string is passed', async function () {
|
||||
const resultFilePath = await record(/* options */ {}, /* outputFilePath */ '')
|
||||
expect(resultFilePath).to.be.a('string').that.is.not.empty()
|
||||
})
|
||||
})
|
||||
})
|
||||
2
vendor/libchromiumcontent
vendored
2
vendor/libchromiumcontent
vendored
Submodule vendor/libchromiumcontent updated: d9e39391cf...1b74a92a80
6
vsts.yml
6
vsts.yml
@@ -6,6 +6,12 @@ steps:
|
||||
displayName: Skip build on older branch
|
||||
condition: ne(variables['ELECTRON_RELEASE'], '1')
|
||||
|
||||
- bash: |
|
||||
git clean -fdx
|
||||
displayName: Clean unneeded git directories
|
||||
timeoutInMinutes: 2
|
||||
condition: eq(variables['ELECTRON_RELEASE'], '1')
|
||||
|
||||
- bash: |
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
|
||||
Reference in New Issue
Block a user