mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
83 Commits
fix-codesp
...
v1.8.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ddf6188f4 | ||
|
|
2695a68869 | ||
|
|
ba016f3949 | ||
|
|
c7a5c079f7 | ||
|
|
c1dad25f33 | ||
|
|
120bc964c6 | ||
|
|
c3da3ae3f0 | ||
|
|
d1f1210044 | ||
|
|
c9febc49d1 | ||
|
|
87d2571663 | ||
|
|
d94970e81a | ||
|
|
acbf1c9f94 | ||
|
|
e14b7d9bc6 | ||
|
|
712b5fe0fd | ||
|
|
eedb0b778f | ||
|
|
ed0676e167 | ||
|
|
f39763d7f5 | ||
|
|
5889bbe27c | ||
|
|
ae1a54d33e | ||
|
|
71a93aec5d | ||
|
|
ad1929c4b6 | ||
|
|
6aa0c44f5d | ||
|
|
5e0111abc6 | ||
|
|
1860930b7e | ||
|
|
c285bdb2bc | ||
|
|
9b44c764dc | ||
|
|
75ce746885 | ||
|
|
d0aa740720 | ||
|
|
5e8735c968 | ||
|
|
13cb27f7ab | ||
|
|
43bc858c0b | ||
|
|
6bc2894bf5 | ||
|
|
a784804349 | ||
|
|
b3e6597317 | ||
|
|
6413a7f0f3 | ||
|
|
0e9b0fff46 | ||
|
|
0b7fd96629 | ||
|
|
03add24cd7 | ||
|
|
36f0a74b17 | ||
|
|
92f4e5ea7d | ||
|
|
5aee1cefff | ||
|
|
7bfb3f4141 | ||
|
|
cd3f36a968 | ||
|
|
8681dc4a26 | ||
|
|
95c7499775 | ||
|
|
470b31d1af | ||
|
|
e912091aca | ||
|
|
281e1748ef | ||
|
|
f15ce53dca | ||
|
|
d45b8dfe83 | ||
|
|
ba933e2998 | ||
|
|
cb1ee8982d | ||
|
|
290f985571 | ||
|
|
08f36c1383 | ||
|
|
7659c16b09 | ||
|
|
daf6dd99a8 | ||
|
|
8d220141a5 | ||
|
|
a1f23064e1 | ||
|
|
64ede04002 | ||
|
|
dab7f7f18d | ||
|
|
9ceef5f1d3 | ||
|
|
a250089a40 | ||
|
|
6efa33043a | ||
|
|
445781ce33 | ||
|
|
ec088c7940 | ||
|
|
71034f8008 | ||
|
|
c9d2b071ab | ||
|
|
d0ca62b173 | ||
|
|
6982fb6dd0 | ||
|
|
be46ba1849 | ||
|
|
5eefde63b9 | ||
|
|
2a97f2636a | ||
|
|
ab3811e6dd | ||
|
|
686dd664de | ||
|
|
1e5ba47731 | ||
|
|
7ef262cab3 | ||
|
|
19d70e5f1f | ||
|
|
d0a9379b37 | ||
|
|
0ac7106e6c | ||
|
|
f19f125f68 | ||
|
|
79385dcb74 | ||
|
|
a71a20ee32 | ||
|
|
99a1161fe4 |
@@ -6,7 +6,7 @@ jobs:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
environment:
|
||||
TARGET_ARCH: arm
|
||||
resource_class: xlarge
|
||||
resource_class: 2xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
- image: electronbuilds/electron:0.0.3
|
||||
environment:
|
||||
TARGET_ARCH: arm64
|
||||
resource_class: xlarge
|
||||
resource_class: 2xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@@ -236,7 +236,7 @@ jobs:
|
||||
environment:
|
||||
TARGET_ARCH: x64
|
||||
DISPLAY: ':99.0'
|
||||
resource_class: xlarge
|
||||
resource_class: 2xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@@ -262,6 +262,7 @@ jobs:
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
@@ -339,3 +340,6 @@ workflows:
|
||||
build-x64:
|
||||
jobs:
|
||||
- electron-linux-x64
|
||||
build-mips64el:
|
||||
jobs:
|
||||
- electron-linux-mips64el
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -28,6 +28,7 @@
|
||||
/external_binaries/
|
||||
/out/
|
||||
/vendor/.gclient
|
||||
/vendor/cross-gcc-4.9.3-n64-loongson-rc5.4
|
||||
/vendor/debian_jessie_amd64-sysroot/
|
||||
/vendor/debian_jessie_arm-sysroot/
|
||||
/vendor/debian_jessie_arm64-sysroot/
|
||||
@@ -36,8 +37,6 @@
|
||||
/vendor/debian_wheezy_amd64-sysroot/
|
||||
/vendor/debian_wheezy_arm-sysroot/
|
||||
/vendor/debian_wheezy_i386-sysroot/
|
||||
/vendor/gcc-4.8.3-d197-n64-loongson/
|
||||
/vendor/readme-gcc483-loongson.txt
|
||||
/vendor/download/
|
||||
/vendor/llvm-build/
|
||||
/vendor/llvm/
|
||||
|
||||
63
Dockerfile.arm64v8
Normal file
63
Dockerfile.arm64v8
Normal file
@@ -0,0 +1,63 @@
|
||||
FROM arm64v8/ubuntu:16.04
|
||||
|
||||
RUN groupadd --gid 1000 builduser \
|
||||
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||
|
||||
RUN groupadd --gid 114 jenkins \
|
||||
&& useradd --uid 110 --gid jenkins --shell /bin/bash --create-home jenkins
|
||||
|
||||
# Set up TEMP directory
|
||||
ENV TEMP=/tmp
|
||||
RUN chmod a+rwx /tmp
|
||||
|
||||
RUN apt-get update && apt-get install -y\
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
curl \
|
||||
gperf \
|
||||
git \
|
||||
libasound2 \
|
||||
libasound2-dev \
|
||||
libcap-dev \
|
||||
libcups2-dev \
|
||||
libdbus-1-dev \
|
||||
libgconf-2-4 \
|
||||
libgconf2-dev \
|
||||
libgnome-keyring-dev \
|
||||
libgtk2.0-0 \
|
||||
libgtk2.0-dev \
|
||||
libgtk-3-0 \
|
||||
libgtk-3-dev \
|
||||
libnotify-dev \
|
||||
libnss3 \
|
||||
libnss3-dev \
|
||||
libx11-xcb-dev \
|
||||
libxss1 \
|
||||
libxtst-dev \
|
||||
libxtst6 \
|
||||
lsb-release \
|
||||
locales \
|
||||
ninja \
|
||||
python-setuptools \
|
||||
python-pip \
|
||||
python-dbusmock \
|
||||
wget \
|
||||
xvfb
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN apt-get update && apt-get install -y nodejs
|
||||
|
||||
# Install crcmod
|
||||
RUN pip install -U crcmod
|
||||
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
# Install ninja in /usr/local
|
||||
RUN cd /usr/local && git clone https://github.com/martine/ninja.git -b v1.5.3
|
||||
RUN cd /usr/local/ninja && ./configure.py --bootstrap
|
||||
|
||||
USER builduser
|
||||
WORKDIR /home/builduser
|
||||
35
Jenkinsfile.arm64
Normal file
35
Jenkinsfile.arm64
Normal file
@@ -0,0 +1,35 @@
|
||||
pipeline {
|
||||
agent {
|
||||
docker {
|
||||
image 'electronbuilds/arm64v8:0.0.1'
|
||||
args '--privileged'
|
||||
}
|
||||
}
|
||||
environment {
|
||||
TARGET_ARCH='arm64'
|
||||
DISPLAY=':99.0'
|
||||
}
|
||||
stages {
|
||||
stage('Bootstrap') {
|
||||
steps {
|
||||
sh 'script/bootstrap.py -v --dev --target_arch=$TARGET_ARCH'
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'script/build.py -c D --ninja-path /usr/local/ninja/ninja'
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh '/etc/init.d/xvfb start'
|
||||
sh 'script/test.py --ci'
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
#if defined(OS_MACOSX)
|
||||
extern "C" {
|
||||
__attribute__((visibility("default")))
|
||||
int AtomMain(int argc, const char* argv[]);
|
||||
int AtomMain(int argc, char* argv[]);
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
int AtomInitializeICUandStartNode(int argc, char *argv[]);
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
int AtomMain(int argc, const char* argv[]) {
|
||||
int AtomMain(int argc, char* argv[]) {
|
||||
atom::AtomMainDelegate delegate;
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.argc = argc;
|
||||
params.argv = argv;
|
||||
params.argv = const_cast<const char**>(argv);
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
#include "atom/app/atom_main.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h> // windows.h must be included first
|
||||
@@ -15,9 +16,11 @@
|
||||
#include <tchar.h>
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "atom/app/command_line_args.h"
|
||||
#include "atom/common/crash_reporter/win/crash_service_main.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/process/launch.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/win/windows_version.h"
|
||||
#include "content/public/app/sandbox_helper_win.h"
|
||||
#include "sandbox/win/src/sandbox_types.h"
|
||||
@@ -52,18 +55,23 @@ bool IsEnvSet(const char* name) {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
int argc = 0;
|
||||
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
struct Arguments {
|
||||
int argc = 0;
|
||||
wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
|
||||
bool run_as_node = IsEnvSet(kRunAsNode);
|
||||
~Arguments() { LocalFree(argv); }
|
||||
} arguments;
|
||||
|
||||
if (!arguments.argv)
|
||||
return -1;
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Don't display assert dialog boxes in CI test runs
|
||||
static const auto kCI = "ELECTRON_CI";
|
||||
bool is_ci = IsEnvSet(kCI);
|
||||
if (!is_ci) {
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (!_wcsicmp(wargv[i], L"--ci")) {
|
||||
for (int i = 0; i < arguments.argc; ++i) {
|
||||
if (!_wcsicmp(arguments.argv[i], L"--ci")) {
|
||||
is_ci = true;
|
||||
_putenv_s(kCI, "1"); // set flag for child processes
|
||||
break;
|
||||
@@ -81,44 +89,12 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
}
|
||||
#endif
|
||||
|
||||
bool run_as_node = IsEnvSet(kRunAsNode);
|
||||
|
||||
// Make sure the output is printed to console.
|
||||
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
|
||||
base::RouteStdioToConsole(false);
|
||||
|
||||
// Convert argv to to UTF8
|
||||
char** argv = new char*[argc];
|
||||
for (int i = 0; i < argc; i++) {
|
||||
// Compute the size of the required buffer
|
||||
DWORD size = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wargv[i],
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (size == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
// Do the actual conversion
|
||||
argv[i] = new char[size];
|
||||
DWORD result = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wargv[i],
|
||||
-1,
|
||||
argv[i],
|
||||
size,
|
||||
NULL,
|
||||
NULL);
|
||||
if (result == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DEBUG
|
||||
// Chromium has its own TLS subsystem which supports automatic destruction
|
||||
// of thread-local data, and also depends on memory allocation routines
|
||||
@@ -139,14 +115,23 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
#endif
|
||||
|
||||
if (run_as_node) {
|
||||
// Now that argv conversion is done, we can finally start.
|
||||
std::vector<char*> argv(arguments.argc);
|
||||
std::transform(
|
||||
arguments.argv, arguments.argv + arguments.argc, argv.begin(),
|
||||
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
|
||||
|
||||
base::AtExitManager atexit_manager;
|
||||
base::i18n::InitializeICU();
|
||||
return atom::NodeMain(argc, argv);
|
||||
auto ret = atom::NodeMain(argv.size(), argv.data());
|
||||
std::for_each(argv.begin(), argv.end(), free);
|
||||
return ret;
|
||||
} else if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
|
||||
return crash_service::Main(cmd);
|
||||
}
|
||||
|
||||
if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
|
||||
return -1;
|
||||
|
||||
sandbox::SandboxInterfaceInfo sandbox_info = {0};
|
||||
content::InitializeSandboxInfo(&sandbox_info);
|
||||
atom::AtomMainDelegate delegate;
|
||||
@@ -154,33 +139,32 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.instance = instance;
|
||||
params.sandbox_info = &sandbox_info;
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
atom::AtomCommandLine::InitW(argc, wargv);
|
||||
atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, char* argv[]) {
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
base::i18n::InitializeICU();
|
||||
base::AtExitManager atexit_manager;
|
||||
return atom::NodeMain(argc, const_cast<char**>(argv));
|
||||
return atom::NodeMain(argc, argv);
|
||||
}
|
||||
|
||||
atom::AtomMainDelegate delegate;
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.argc = argc;
|
||||
params.argv = argv;
|
||||
params.argv = const_cast<const char**>(argv);
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
#else // defined(OS_LINUX)
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, char* argv[]) {
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
|
||||
return AtomInitializeICUandStartNode(argc, argv);
|
||||
}
|
||||
|
||||
return AtomMain(argc, argv);
|
||||
|
||||
1412
atom/app/command_line_args.cc
Normal file
1412
atom/app/command_line_args.cc
Normal file
File diff suppressed because it is too large
Load Diff
17
atom/app/command_line_args.h
Normal file
17
atom/app/command_line_args.h
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
#define ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
|
||||
#include "base/command_line.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
|
||||
@@ -861,11 +861,7 @@ bool App::Relaunch(mate::Arguments* js_args) {
|
||||
}
|
||||
|
||||
if (!override_argv) {
|
||||
#if defined(OS_WIN)
|
||||
const relauncher::StringVector& argv = atom::AtomCommandLine::wargv();
|
||||
#else
|
||||
const relauncher::StringVector& argv = atom::AtomCommandLine::argv();
|
||||
#endif
|
||||
return relauncher::RelaunchApp(argv);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
// implemetation. This is a known and wontFix issue in webrtc (see:
|
||||
// http://code.google.com/p/webrtc/issues/detail?id=3373)
|
||||
options.set_disable_effects(false);
|
||||
options.set_allow_directx_capturer(true);
|
||||
#endif
|
||||
|
||||
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
|
||||
|
||||
@@ -78,10 +78,6 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override {
|
||||
if (!request->initiator().has_value()) {
|
||||
// Don't intercept this request as it was created by `net.request`.
|
||||
return nullptr;
|
||||
}
|
||||
RequestJob* request_job = new RequestJob(request, network_delegate);
|
||||
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
|
||||
return request_job;
|
||||
|
||||
@@ -377,8 +377,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
||||
options.Get("transparent", &transparent);
|
||||
|
||||
content::WebContents::CreateParams params(session->browser_context());
|
||||
auto* view = new OffScreenWebContentsView(
|
||||
transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this)));
|
||||
auto* view = new OffScreenWebContentsView(transparent,
|
||||
base::Bind(&WebContents::OnPaint, base::Unretained(this)));
|
||||
params.view = view;
|
||||
params.delegate_view = view;
|
||||
|
||||
@@ -1644,10 +1644,10 @@ void WebContents::StartPainting() {
|
||||
return;
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
if (osr_rwhv)
|
||||
osr_rwhv->SetPainting(true);
|
||||
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||
if (osr_wcv)
|
||||
osr_wcv->SetPainting(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1656,10 +1656,10 @@ void WebContents::StopPainting() {
|
||||
return;
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
if (osr_rwhv)
|
||||
osr_rwhv->SetPainting(false);
|
||||
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||
if (osr_wcv)
|
||||
osr_wcv->SetPainting(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1668,9 +1668,10 @@ bool WebContents::IsPainting() const {
|
||||
return false;
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
return osr_rwhv && osr_rwhv->IsPainting();
|
||||
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||
|
||||
return osr_wcv && osr_wcv->IsPainting();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
@@ -1681,10 +1682,11 @@ void WebContents::SetFrameRate(int frame_rate) {
|
||||
return;
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
if (osr_rwhv)
|
||||
osr_rwhv->SetFrameRate(frame_rate);
|
||||
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||
|
||||
if (osr_wcv)
|
||||
osr_wcv->SetFrameRate(frame_rate);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1693,9 +1695,10 @@ int WebContents::GetFrameRate() const {
|
||||
return 0;
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
return osr_rwhv ? osr_rwhv->GetFrameRate() : 0;
|
||||
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||
|
||||
return osr_wcv ? osr_wcv->GetFrameRate() : 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "content/public/browser/resource_dispatcher_host.h"
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
@@ -243,6 +244,11 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
||||
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
base::CommandLine* command_line,
|
||||
int process_id) {
|
||||
// Make sure we're about to launch a known executable
|
||||
base::FilePath child_path;
|
||||
PathService::Get(content::CHILD_PROCESS_EXE, &child_path);
|
||||
CHECK(base::MakeAbsoluteFilePath(command_line->GetProgram()) == child_path);
|
||||
|
||||
std::string process_type =
|
||||
command_line->GetSwitchValueASCII(::switches::kProcessType);
|
||||
if (process_type != ::switches::kRendererProcess)
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "atom/browser/ui/views/win_frame_view.h"
|
||||
#include "atom/browser/ui/win/atom_desktop_native_widget_aura.h"
|
||||
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.h"
|
||||
#include "content/public/browser/gpu_data_manager.h"
|
||||
#include "skia/ext/skia_utils_win.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/display/display.h"
|
||||
@@ -297,9 +298,12 @@ NativeWindowViews::NativeWindowViews(
|
||||
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
|
||||
}
|
||||
|
||||
bool hardware_accelerated =
|
||||
content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled();
|
||||
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
|
||||
// Window without thick frame has to have WS_EX_COMPOSITED style.
|
||||
if (!thick_frame_)
|
||||
// Window without thick frame has to have WS_EX_COMPOSITED style when GPU
|
||||
// acceleration is enabled.
|
||||
if (!thick_frame_ && hardware_accelerated)
|
||||
ex_style |= WS_EX_COMPOSITED;
|
||||
if (window_type == "toolbar")
|
||||
ex_style |= WS_EX_TOOLWINDOW;
|
||||
@@ -1363,22 +1367,26 @@ void NativeWindowViews::ShowAutofillPopup(
|
||||
const gfx::RectF& bounds,
|
||||
const std::vector<base::string16>& values,
|
||||
const std::vector<base::string16>& labels) {
|
||||
const auto* web_preferences =
|
||||
WebContentsPreferences::FromWebContents(web_contents)->web_preferences();
|
||||
|
||||
bool is_offsceen = false;
|
||||
web_preferences->GetBoolean("offscreen", &is_offsceen);
|
||||
int guest_instance_id = 0;
|
||||
web_preferences->GetInteger(options::kGuestInstanceID, &guest_instance_id);
|
||||
|
||||
bool is_embedder_offscreen = false;
|
||||
if (guest_instance_id) {
|
||||
auto manager = WebViewManager::GetWebViewManager(web_contents);
|
||||
if (manager) {
|
||||
auto embedder = manager->GetEmbedder(guest_instance_id);
|
||||
if (embedder) {
|
||||
is_embedder_offscreen = WebContentsPreferences::IsPreferenceEnabled(
|
||||
"offscreen", embedder);
|
||||
|
||||
auto* web_contents_preferences =
|
||||
WebContentsPreferences::FromWebContents(web_contents);
|
||||
if (web_contents_preferences) {
|
||||
const auto* web_preferences = web_contents_preferences->web_preferences();
|
||||
|
||||
web_preferences->GetBoolean("offscreen", &is_offsceen);
|
||||
int guest_instance_id = 0;
|
||||
web_preferences->GetInteger(options::kGuestInstanceID, &guest_instance_id);
|
||||
|
||||
if (guest_instance_id) {
|
||||
auto manager = WebViewManager::GetWebViewManager(web_contents);
|
||||
if (manager) {
|
||||
auto embedder = manager->GetEmbedder(guest_instance_id);
|
||||
if (embedder) {
|
||||
is_embedder_offscreen = WebContentsPreferences::IsPreferenceEnabled(
|
||||
"offscreen", embedder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
#include "atom/browser/api/atom_api_url_request.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "base/callback.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/elements_upload_data_stream.h"
|
||||
@@ -120,6 +121,9 @@ void AtomURLRequest::DoInitialize(
|
||||
request_->set_method(method);
|
||||
// Do not send cookies from the cookie store.
|
||||
DoSetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES);
|
||||
// Set a flag to stop custom protocol from intercepting this request.
|
||||
request_->SetUserData(DisableProtocolInterceptFlagKey(),
|
||||
base::WrapUnique(new base::SupportsUserData::Data()));
|
||||
}
|
||||
|
||||
void AtomURLRequest::DoTerminate() {
|
||||
|
||||
@@ -15,8 +15,18 @@ using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
int disable_protocol_intercept_flag_key = 0;
|
||||
|
||||
} // namespace
|
||||
|
||||
typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
|
||||
|
||||
const void* DisableProtocolInterceptFlagKey() {
|
||||
return &disable_protocol_intercept_flag_key;
|
||||
}
|
||||
|
||||
AtomURLRequestJobFactory::AtomURLRequestJobFactory() {}
|
||||
|
||||
AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
|
||||
@@ -93,6 +103,8 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
|
||||
auto it = protocol_handler_map_.find(scheme);
|
||||
if (it == protocol_handler_map_.end())
|
||||
return nullptr;
|
||||
if (request->GetUserData(DisableProtocolInterceptFlagKey()))
|
||||
return nullptr;
|
||||
return it->second->MaybeCreateJob(request, network_delegate);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
namespace atom {
|
||||
|
||||
const void* DisableProtocolInterceptFlagKey();
|
||||
|
||||
class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
|
||||
public:
|
||||
AtomURLRequestJobFactory();
|
||||
|
||||
@@ -42,7 +42,7 @@ void NodeDebugger::Start() {
|
||||
// the debugger on the first line
|
||||
if (options.wait_for_connect()) {
|
||||
mate::Dictionary process(env_->isolate(), env_->process_object());
|
||||
process.Set("_debugWaitConnect", true);
|
||||
process.Set("_breakFirstLine", true);
|
||||
}
|
||||
|
||||
inspector->Start(platform_.get(), nullptr, options);
|
||||
|
||||
@@ -124,7 +124,7 @@ class AtomCopyFrameGenerator {
|
||||
}
|
||||
|
||||
void GenerateCopyFrame(const gfx::Rect& damage_rect) {
|
||||
if (!view_->render_widget_host())
|
||||
if (!view_->render_widget_host() || !view_->IsPainting())
|
||||
return;
|
||||
|
||||
std::unique_ptr<cc::CopyOutputRequest> request =
|
||||
@@ -255,6 +255,8 @@ class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient {
|
||||
|
||||
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
bool transparent,
|
||||
bool painting,
|
||||
int frame_rate,
|
||||
const OnPaintCallback& callback,
|
||||
content::RenderWidgetHost* host,
|
||||
OffScreenRenderWidgetHostView* parent_host_view,
|
||||
@@ -268,17 +270,18 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
transparent_(transparent),
|
||||
callback_(callback),
|
||||
parent_callback_(nullptr),
|
||||
frame_rate_(60),
|
||||
frame_rate_(frame_rate),
|
||||
frame_rate_threshold_us_(0),
|
||||
last_time_(base::Time::Now()),
|
||||
scale_factor_(kDefaultScaleFactor),
|
||||
size_(native_window->GetSize()),
|
||||
painting_(true),
|
||||
painting_(painting),
|
||||
is_showing_(!render_widget_host_->is_hidden()),
|
||||
is_destroyed_(false),
|
||||
popup_position_(gfx::Rect()),
|
||||
hold_resize_(false),
|
||||
pending_resize_(false),
|
||||
paint_callback_running_(false),
|
||||
renderer_compositor_frame_sink_(nullptr),
|
||||
background_color_(SkColor()),
|
||||
weak_ptr_factory_(this) {
|
||||
@@ -303,7 +306,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
|
||||
content::GetContextFactory(), context_factory_private,
|
||||
base::ThreadTaskRunnerHandle::Get()));
|
||||
compositor_->SetAcceleratedWidget(native_window_->GetAcceleratedWidget());
|
||||
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
|
||||
compositor_->SetRootLayer(root_layer_.get());
|
||||
#endif
|
||||
GetCompositor()->SetDelegate(this);
|
||||
@@ -738,6 +741,8 @@ content::RenderWidgetHostViewBase*
|
||||
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_,
|
||||
true,
|
||||
embedder_host_view->GetFrameRate(),
|
||||
callback_,
|
||||
render_widget_host,
|
||||
embedder_host_view,
|
||||
@@ -930,7 +935,7 @@ bool OffScreenRenderWidgetHostView::IsAutoResizeEnabled() const {
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
|
||||
bool needs_begin_frames) {
|
||||
SetupFrameRate(false);
|
||||
SetupFrameRate(true);
|
||||
|
||||
begin_frame_timer_->SetActive(needs_begin_frames);
|
||||
|
||||
@@ -1004,7 +1009,9 @@ void OffScreenRenderWidgetHostView::OnPaint(
|
||||
}
|
||||
|
||||
damage.Intersect(GetViewBounds());
|
||||
paint_callback_running_ = true;
|
||||
callback_.Run(damage, bitmap);
|
||||
paint_callback_running_ = false;
|
||||
|
||||
for (size_t i = 0; i < damages.size(); i++) {
|
||||
CopyBitmapTo(bitmap, originals[i], damages[i]);
|
||||
@@ -1151,7 +1158,7 @@ void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
|
||||
painting_ = painting;
|
||||
|
||||
if (software_output_device_) {
|
||||
software_output_device_->SetActive(painting_, true);
|
||||
software_output_device_->SetActive(painting_, !paint_callback_running_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1168,16 +1175,16 @@ void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) {
|
||||
} else {
|
||||
if (frame_rate <= 0)
|
||||
frame_rate = 1;
|
||||
if (frame_rate > 60)
|
||||
frame_rate = 60;
|
||||
if (frame_rate > 240)
|
||||
frame_rate = 240;
|
||||
|
||||
frame_rate_ = frame_rate;
|
||||
}
|
||||
|
||||
SetupFrameRate(true);
|
||||
|
||||
for (auto guest_host_view : guest_host_views_)
|
||||
guest_host_view->SetFrameRate(frame_rate);
|
||||
|
||||
SetupFrameRate(true);
|
||||
}
|
||||
|
||||
int OffScreenRenderWidgetHostView::GetFrameRate() const {
|
||||
@@ -1205,7 +1212,7 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||
|
||||
frame_rate_threshold_us_ = 1000000 / frame_rate_;
|
||||
|
||||
GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval(
|
||||
GetCompositor()->SetAuthoritativeVSyncInterval(
|
||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
|
||||
|
||||
if (copy_frame_generator_.get()) {
|
||||
|
||||
@@ -74,6 +74,8 @@ class OffScreenRenderWidgetHostView
|
||||
public OffscreenViewProxyObserver {
|
||||
public:
|
||||
OffScreenRenderWidgetHostView(bool transparent,
|
||||
bool painting,
|
||||
int frame_rate,
|
||||
const OnPaintCallback& callback,
|
||||
content::RenderWidgetHost* render_widget_host,
|
||||
OffScreenRenderWidgetHostView* parent_host_view,
|
||||
@@ -314,6 +316,8 @@ class OffScreenRenderWidgetHostView
|
||||
bool hold_resize_;
|
||||
bool pending_resize_;
|
||||
|
||||
bool paint_callback_running_;
|
||||
|
||||
std::unique_ptr<ui::Layer> root_layer_;
|
||||
std::unique_ptr<ui::Compositor> compositor_;
|
||||
std::unique_ptr<content::DelegatedFrameHost> delegated_frame_host_;
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace atom {
|
||||
OffScreenWebContentsView::OffScreenWebContentsView(
|
||||
bool transparent, const OnPaintCallback& callback)
|
||||
: transparent_(transparent),
|
||||
painting_(true),
|
||||
frame_rate_(60),
|
||||
callback_(callback),
|
||||
web_contents_(nullptr) {
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -103,6 +105,8 @@ content::RenderWidgetHostViewBase*
|
||||
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_,
|
||||
painting_,
|
||||
GetFrameRate(),
|
||||
callback_,
|
||||
render_widget_host,
|
||||
nullptr,
|
||||
@@ -125,6 +129,8 @@ content::RenderWidgetHostViewBase*
|
||||
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_,
|
||||
true,
|
||||
view->GetFrameRate(),
|
||||
callback_,
|
||||
render_widget_host,
|
||||
view,
|
||||
@@ -202,6 +208,42 @@ void OffScreenWebContentsView::UpdateDragCursor(
|
||||
blink::WebDragOperation operation) {
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::SetPainting(bool painting) {
|
||||
auto* view = GetView();
|
||||
if (view != nullptr) {
|
||||
view->SetPainting(painting);
|
||||
} else {
|
||||
painting_ = painting;
|
||||
}
|
||||
}
|
||||
|
||||
bool OffScreenWebContentsView::IsPainting() const {
|
||||
auto* view = GetView();
|
||||
if (view != nullptr) {
|
||||
return view->IsPainting();
|
||||
} else {
|
||||
return painting_;
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::SetFrameRate(int frame_rate) {
|
||||
auto* view = GetView();
|
||||
if (view != nullptr) {
|
||||
view->SetFrameRate(frame_rate);
|
||||
} else {
|
||||
frame_rate_ = frame_rate;
|
||||
}
|
||||
}
|
||||
|
||||
int OffScreenWebContentsView::GetFrameRate() const {
|
||||
auto* view = GetView();
|
||||
if (view != nullptr) {
|
||||
return view->GetFrameRate();
|
||||
} else {
|
||||
return frame_rate_;
|
||||
}
|
||||
}
|
||||
|
||||
OffScreenRenderWidgetHostView* OffScreenWebContentsView::GetView() const {
|
||||
if (web_contents_) {
|
||||
return static_cast<OffScreenRenderWidgetHostView*>(
|
||||
|
||||
@@ -69,6 +69,11 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
||||
content::RenderWidgetHostImpl* source_rwh) override;
|
||||
void UpdateDragCursor(blink::WebDragOperation operation) override;
|
||||
|
||||
void SetPainting(bool painting);
|
||||
bool IsPainting() const;
|
||||
void SetFrameRate(int frame_rate);
|
||||
int GetFrameRate() const;
|
||||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
void PlatformCreate();
|
||||
@@ -78,6 +83,8 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
||||
OffScreenRenderWidgetHostView* GetView() const;
|
||||
|
||||
const bool transparent_;
|
||||
bool painting_;
|
||||
int frame_rate_;
|
||||
OnPaintCallback callback_;
|
||||
|
||||
// Weak refs.
|
||||
|
||||
@@ -140,11 +140,7 @@ bool RelaunchAppWithHelper(const base::FilePath& helper,
|
||||
}
|
||||
|
||||
int RelauncherMain(const content::MainFunctionParams& main_parameters) {
|
||||
#if defined(OS_WIN)
|
||||
const StringVector& argv = atom::AtomCommandLine::wargv();
|
||||
#else
|
||||
const StringVector& argv = atom::AtomCommandLine::argv();
|
||||
#endif
|
||||
|
||||
if (argv.size() < 4 || argv[1] != internal::kRelauncherTypeArg) {
|
||||
LOG(ERROR) << "relauncher process invoked with unexpected arguments";
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.8.2</string>
|
||||
<string>1.8.3</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.8.2</string>
|
||||
<string>1.8.3</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -56,8 +56,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,8,2,2
|
||||
PRODUCTVERSION 1,8,2,2
|
||||
FILEVERSION 1,8,3,0
|
||||
PRODUCTVERSION 1,8,3,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -74,12 +74,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "1.8.2"
|
||||
VALUE "FileVersion", "1.8.3"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "1.8.2"
|
||||
VALUE "ProductVersion", "1.8.3"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -3,12 +3,16 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/ui/win/atom_desktop_native_widget_aura.h"
|
||||
#include "ui/views/corewm/tooltip_controller.h"
|
||||
#include "ui/wm/public/tooltip_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomDesktopNativeWidgetAura::AtomDesktopNativeWidgetAura(
|
||||
views::internal::NativeWidgetDelegate* delegate)
|
||||
: views::DesktopNativeWidgetAura(delegate) {
|
||||
// This is to enable the override of OnWindowActivated
|
||||
aura::client::SetActivationChangeObserver(GetNativeWindow(), this);
|
||||
}
|
||||
|
||||
void AtomDesktopNativeWidgetAura::Activate() {
|
||||
@@ -19,4 +23,23 @@ void AtomDesktopNativeWidgetAura::Activate() {
|
||||
views::DesktopNativeWidgetAura::Activate();
|
||||
}
|
||||
|
||||
void AtomDesktopNativeWidgetAura::OnWindowActivated(
|
||||
aura::client::ActivationChangeObserver::ActivationReason reason,
|
||||
aura::Window* gained_active,
|
||||
aura::Window* lost_active) {
|
||||
views::DesktopNativeWidgetAura::OnWindowActivated(
|
||||
reason, gained_active, lost_active);
|
||||
if (lost_active != nullptr) {
|
||||
auto* tooltip_controller = static_cast<views::corewm::TooltipController*>(
|
||||
aura::client::GetTooltipClient(lost_active->GetRootWindow()));
|
||||
|
||||
// This will cause the tooltip to be hidden when a window is deactivated,
|
||||
// as it should be.
|
||||
// TODO(brenca): Remove this fix when the chromium issue is fixed.
|
||||
// crbug.com/724538
|
||||
if (tooltip_controller != nullptr)
|
||||
tooltip_controller->OnCancelMode(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -19,6 +19,10 @@ class AtomDesktopNativeWidgetAura : public views::DesktopNativeWidgetAura {
|
||||
void Activate() override;
|
||||
|
||||
private:
|
||||
void OnWindowActivated(
|
||||
aura::client::ActivationChangeObserver::ActivationReason reason,
|
||||
aura::Window* gained_active,
|
||||
aura::Window* lost_active) override;
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomDesktopNativeWidgetAura);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,31 +10,22 @@
|
||||
namespace atom {
|
||||
|
||||
// static
|
||||
std::vector<std::string> AtomCommandLine::argv_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// static
|
||||
std::vector<std::wstring> AtomCommandLine::wargv_;
|
||||
#endif
|
||||
base::CommandLine::StringVector AtomCommandLine::argv_;
|
||||
|
||||
// static
|
||||
void AtomCommandLine::Init(int argc, const char* const* argv) {
|
||||
void AtomCommandLine::Init(int argc, base::CommandLine::CharType** argv) {
|
||||
DCHECK(argv_.empty());
|
||||
|
||||
// NOTE: uv_setup_args does nothing on Windows, so we don't need to call it.
|
||||
// Otherwise we'd have to convert the arguments from UTF16.
|
||||
#if !defined(OS_WIN)
|
||||
// Hack around with the argv pointer. Used for process.title = "blah"
|
||||
char** new_argv = uv_setup_args(argc, const_cast<char**>(argv));
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
argv_.push_back(new_argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// static
|
||||
void AtomCommandLine::InitW(int argc, const wchar_t* const* argv) {
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
wargv_.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
argv = uv_setup_args(argc, argv);
|
||||
#endif
|
||||
|
||||
argv_.assign(argv, argv + argc);
|
||||
}
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// static
|
||||
void AtomCommandLine::InitializeFromCommandLine() {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/macros.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
@@ -16,13 +17,9 @@ namespace atom {
|
||||
// Singleton to remember the original "argc" and "argv".
|
||||
class AtomCommandLine {
|
||||
public:
|
||||
static void Init(int argc, const char* const* argv);
|
||||
static std::vector<std::string> argv() { return argv_; }
|
||||
static const base::CommandLine::StringVector& argv() { return argv_; }
|
||||
|
||||
#if defined(OS_WIN)
|
||||
static void InitW(int argc, const wchar_t* const* argv);
|
||||
static std::vector<std::wstring> wargv() { return wargv_; }
|
||||
#endif
|
||||
static void Init(int argc, base::CommandLine::CharType** argv);
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// On Linux the command line has to be read from base::CommandLine since
|
||||
@@ -31,11 +28,7 @@ class AtomCommandLine {
|
||||
#endif
|
||||
|
||||
private:
|
||||
static std::vector<std::string> argv_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
static std::vector<std::wstring> wargv_;
|
||||
#endif
|
||||
static base::CommandLine::StringVector argv_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AtomCommandLine);
|
||||
};
|
||||
|
||||
@@ -7,22 +7,24 @@
|
||||
|
||||
#define ATOM_MAJOR_VERSION 1
|
||||
#define ATOM_MINOR_VERSION 8
|
||||
#define ATOM_PATCH_VERSION 2
|
||||
#define ATOM_PRE_RELEASE_VERSION -beta.2
|
||||
|
||||
#ifndef ATOM_PRE_RELEASE_VERSION
|
||||
# define ATOM_PRE_RELEASE_VERSION ""
|
||||
#endif
|
||||
#define ATOM_PATCH_VERSION 3
|
||||
// #define ATOM_PRE_RELEASE_VERSION
|
||||
|
||||
#ifndef ATOM_STRINGIFY
|
||||
#define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n)
|
||||
#define ATOM_STRINGIFY_HELPER(n) #n
|
||||
#endif
|
||||
|
||||
# define ATOM_VERSION_STRING ATOM_STRINGIFY(ATOM_MAJOR_VERSION) "." \
|
||||
#ifndef ATOM_PRE_RELEASE_VERSION
|
||||
#define ATOM_VERSION_STRING ATOM_STRINGIFY(ATOM_MAJOR_VERSION) "." \
|
||||
ATOM_STRINGIFY(ATOM_MINOR_VERSION) "." \
|
||||
ATOM_STRINGIFY(ATOM_PATCH_VERSION)
|
||||
#else
|
||||
#define ATOM_VERSION_STRING ATOM_STRINGIFY(ATOM_MAJOR_VERSION) "." \
|
||||
ATOM_STRINGIFY(ATOM_MINOR_VERSION) "." \
|
||||
ATOM_STRINGIFY(ATOM_PATCH_VERSION) \
|
||||
ATOM_STRINGIFY(ATOM_PRE_RELEASE_VERSION)
|
||||
#endif
|
||||
|
||||
#define ATOM_VERSION "v" ATOM_VERSION_STRING
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@ v8::Local<v8::Value> Converter<const net::AuthChallengeInfo*>::ToV8(
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<scoped_refptr<net::X509Certificate>>::ToV8(
|
||||
v8::Isolate* isolate, const scoped_refptr<net::X509Certificate>& val) {
|
||||
#if defined(ARCH_CPU_MIPS64EL)
|
||||
return v8::Undefined(isolate);
|
||||
#else
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
std::string encoded_data;
|
||||
net::X509Certificate::GetPEMEncoded(
|
||||
@@ -92,11 +95,15 @@ v8::Local<v8::Value> Converter<scoped_refptr<net::X509Certificate>>::ToV8(
|
||||
}
|
||||
|
||||
return dict.GetHandle();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Converter<scoped_refptr<net::X509Certificate>>::FromV8(
|
||||
v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
scoped_refptr<net::X509Certificate>* out) {
|
||||
#if defined(ARCH_CPU_MIPS64EL)
|
||||
return false;
|
||||
#else
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
@@ -123,6 +130,7 @@ bool Converter<scoped_refptr<net::X509Certificate>>::FromV8(
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "atom/common/node_bindings.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -17,6 +18,7 @@
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
@@ -150,7 +152,14 @@ void NodeBindings::Initialize() {
|
||||
|
||||
node::Environment* NodeBindings::CreateEnvironment(
|
||||
v8::Handle<v8::Context> context) {
|
||||
#if defined(OS_WIN)
|
||||
auto& atom_args = AtomCommandLine::argv();
|
||||
std::vector<std::string> args(atom_args.size());
|
||||
std::transform(atom_args.cbegin(), atom_args.cend(), args.begin(),
|
||||
[](auto& a) { return base::WideToUTF8(a); });
|
||||
#else
|
||||
auto args = AtomCommandLine::argv();
|
||||
#endif
|
||||
|
||||
// Feed node the path to initialization script.
|
||||
base::FilePath::StringType process_type;
|
||||
@@ -170,8 +179,7 @@ node::Environment* NodeBindings::CreateEnvironment(
|
||||
resources_path.Append(FILE_PATH_LITERAL("electron.asar"))
|
||||
.Append(process_type)
|
||||
.Append(FILE_PATH_LITERAL("init.js"));
|
||||
std::string script_path_str = script_path.AsUTF8Unsafe();
|
||||
args.insert(args.begin() + 1, script_path_str.c_str());
|
||||
args.insert(args.begin() + 1, script_path.AsUTF8Unsafe());
|
||||
|
||||
std::unique_ptr<const char*[]> c_argv = StringVectorToArgArray(args);
|
||||
node::Environment* env = node::CreateEnvironment(
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "atom/renderer/api/atom_api_spell_check_client.h"
|
||||
#include "base/memory/memory_pressure_listener.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "content/public/renderer/render_frame_visitor.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
@@ -58,6 +59,30 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback {
|
||||
DISALLOW_COPY_AND_ASSIGN(ScriptExecutionCallback);
|
||||
};
|
||||
|
||||
class FrameSpellChecker : public content::RenderFrameVisitor {
|
||||
public:
|
||||
explicit FrameSpellChecker(SpellCheckClient* spell_check_client,
|
||||
content::RenderFrame* main_frame)
|
||||
: spell_check_client_(spell_check_client), main_frame_(main_frame) {}
|
||||
~FrameSpellChecker() override {
|
||||
spell_check_client_ = nullptr;
|
||||
main_frame_ = nullptr;
|
||||
}
|
||||
bool Visit(content::RenderFrame* render_frame) override {
|
||||
auto view = render_frame->GetRenderView();
|
||||
if (view->GetMainRenderFrame() == main_frame_ ||
|
||||
(render_frame->IsMainFrame() && render_frame == main_frame_)) {
|
||||
render_frame->GetWebFrame()->SetTextCheckClient(spell_check_client_);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
SpellCheckClient* spell_check_client_;
|
||||
content::RenderFrame* main_frame_;
|
||||
DISALLOW_COPY_AND_ASSIGN(FrameSpellChecker);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
WebFrame::WebFrame(v8::Isolate* isolate)
|
||||
@@ -139,10 +164,15 @@ void WebFrame::SetSpellCheckProvider(mate::Arguments* args,
|
||||
return;
|
||||
}
|
||||
|
||||
spell_check_client_.reset(new SpellCheckClient(
|
||||
std::unique_ptr<SpellCheckClient> client(new SpellCheckClient(
|
||||
language, auto_spell_correct_turned_on, args->isolate(), provider));
|
||||
// Set spellchecker for all live frames in the same process or
|
||||
// in the sandbox mode for all live sub frames to this WebFrame.
|
||||
FrameSpellChecker spell_checker(
|
||||
client.get(), content::RenderFrame::FromWebFrame(web_frame_));
|
||||
content::RenderFrame::ForEach(&spell_checker);
|
||||
spell_check_client_.swap(client);
|
||||
web_frame_->View()->SetSpellCheckClient(spell_check_client_.get());
|
||||
web_frame_->SetTextCheckClient(spell_check_client_.get());
|
||||
}
|
||||
|
||||
void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
'variables': {
|
||||
# The libraries brightray will be compiled to.
|
||||
'linux_system_libraries': 'gtk+-2.0 dbus-1 x11 x11-xcb xcb xi xcursor xdamage xrandr xcomposite xext xfixes xrender xtst xscrnsaver gconf-2.0 gmodule-2.0 nss',
|
||||
'linux_system_libraries': 'gtk+-2.0 dbus-1 x11 x11-xcb xcb xi xcursor xdamage xrandr xcomposite xext xfixes xrender xtst xscrnsaver gconf-2.0 gmodule-2.0',
|
||||
'conditions': [
|
||||
['target_arch=="mips64el"', {
|
||||
'linux_system_libraries': '<(linux_system_libraries) libpulse',
|
||||
}, {
|
||||
'linux_system_libraries': '<(linux_system_libraries) nss',
|
||||
}],
|
||||
],
|
||||
},
|
||||
|
||||
@@ -118,16 +118,10 @@
|
||||
'defines': [
|
||||
'USE_OPENSSL',
|
||||
],
|
||||
}, {
|
||||
'defines': [
|
||||
'USE_X11',
|
||||
# "use_nss_certs" is set to 1 in libchromiumcontent.
|
||||
'USE_NSS_CERTS',
|
||||
'USE_NSS', # deprecated after Chrome 45.
|
||||
],
|
||||
}],
|
||||
['OS=="linux"', {
|
||||
'defines': [
|
||||
'USE_X11',
|
||||
'_LARGEFILE_SOURCE',
|
||||
'_LARGEFILE64_SOURCE',
|
||||
'_FILE_OFFSET_BITS=64',
|
||||
@@ -137,6 +131,11 @@
|
||||
'-fno-rtti',
|
||||
],
|
||||
}], # OS=="linux"
|
||||
['OS=="linux" and target_arch!="mips64el"', {
|
||||
'defines': [
|
||||
'USE_NSS_CERTS',
|
||||
],
|
||||
}], # OS=="linux" and target_arch!="mips64el"
|
||||
['OS=="mac"', {
|
||||
'defines': [
|
||||
# The usage of "webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||
@@ -228,10 +227,8 @@
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'RuntimeLibrary': '2', # /MD (nondebug DLL)
|
||||
# 1, optimizeMinSpace, Minimize Size (/O1)
|
||||
'Optimization': '1',
|
||||
# 2, favorSize - Favor small code (/Os)
|
||||
'FavorSizeOrSpeed': '2',
|
||||
'Optimization': '2', # /O2
|
||||
'WholeProgramOptimization': 'true', # /GL
|
||||
# See http://msdn.microsoft.com/en-us/library/47238hez(VS.71).aspx
|
||||
'InlineFunctionExpansion': '2', # 2 = max
|
||||
# See http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx
|
||||
@@ -241,11 +238,24 @@
|
||||
# perform FPO regardless, so we must explicitly disable.
|
||||
# We still want the false setting above to avoid having
|
||||
# "/Oy /Oy-" and warnings about overriding.
|
||||
'AdditionalOptions': ['/Oy-'],
|
||||
'AdditionalOptions': ['/Oy-', '/d2guard4'],
|
||||
},
|
||||
'VCLibrarianTool': {
|
||||
'LinkTimeCodeGeneration': 'true', # /LTCG
|
||||
},
|
||||
'VCLinkerTool': {
|
||||
# Control Flow Guard is a security feature in Windows
|
||||
# 8.1 and higher designed to prevent exploitation of
|
||||
# indirect calls in executables.
|
||||
# Control Flow Guard is enabled using the /d2guard4
|
||||
# compiler setting in combination with the /guard:cf
|
||||
# linker setting.
|
||||
'AdditionalOptions': ['/guard:cf'],
|
||||
# Turn off incremental linking to save binary size.
|
||||
'LinkIncremental': '1', # /INCREMENTAL:NO
|
||||
'LinkTimeCodeGeneration': '1', # /LTCG
|
||||
'OptimizeReferences': 2, # /OPT:REF
|
||||
'EnableCOMDATFolding': 2, # /OPT:ICF
|
||||
},
|
||||
},
|
||||
'conditions': [
|
||||
@@ -266,10 +276,26 @@
|
||||
# Specifically tell the linker to perform optimizations.
|
||||
# See http://lwn.net/Articles/192624/ .
|
||||
'-Wl,-O1',
|
||||
'-Wl,--as-needed',
|
||||
'-Wl,--gc-sections',
|
||||
],
|
||||
}], # OS=="linux"
|
||||
['OS=="linux" and target_arch!="mips64el"', {
|
||||
'ldflags': [
|
||||
'-Wl,--as-needed',
|
||||
],
|
||||
}],
|
||||
['OS=="linux" and target_arch in ["ia32", "x64", "arm64"]', {
|
||||
'cflags': [
|
||||
'-flto',
|
||||
],
|
||||
'ldflags': [
|
||||
'-flto',
|
||||
'-fuse-ld=gold',
|
||||
'-Wl,-plugin-opt,O1',
|
||||
'-Wl,-plugin-opt,-function-sections',
|
||||
'-Wl,--icf=all',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}, # Release_Base
|
||||
'conditions': [
|
||||
|
||||
@@ -174,7 +174,7 @@ void DesktopNotificationController::AnimateAll() {
|
||||
if (SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0)) {
|
||||
ScreenMetrics metrics;
|
||||
POINT origin = { work_area.right,
|
||||
work_area.bottom - metrics.Y(toast_margin_<int>) };
|
||||
work_area.bottom - metrics.Y(toast_margin_) };
|
||||
|
||||
auto hdwp =
|
||||
BeginDeferWindowPos(static_cast<int>(instances_.size()));
|
||||
@@ -231,7 +231,7 @@ void DesktopNotificationController::AnimateAll() {
|
||||
// Set new toast positions
|
||||
if (!instances_.empty()) {
|
||||
ScreenMetrics metrics;
|
||||
auto margin = metrics.Y(toast_margin_<int>);
|
||||
auto margin = metrics.Y(toast_margin_);
|
||||
|
||||
int target_pos = 0;
|
||||
for (auto&& inst : instances_) {
|
||||
@@ -305,7 +305,7 @@ void DesktopNotificationController::CreateToast(NotificationLink&& data) {
|
||||
auto toast = Toast::Get(item.hwnd);
|
||||
toast_pos = toast->GetVerticalPosition() +
|
||||
toast->GetHeight() +
|
||||
scr.Y(toast_margin_<int>);
|
||||
scr.Y(toast_margin_);
|
||||
}
|
||||
|
||||
instances_.push_back({ hwnd, move(data) });
|
||||
|
||||
@@ -36,8 +36,7 @@ class DesktopNotificationController {
|
||||
TimerID_Animate = 1
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static constexpr T toast_margin_ = 20;
|
||||
static constexpr int toast_margin_ = 20;
|
||||
|
||||
// Wrapper around `NotificationData` which makes sure that
|
||||
// the `controller` member is cleared when the controller object
|
||||
|
||||
@@ -140,6 +140,12 @@
|
||||
'<(libchromiumcontent_src_dir)/v8',
|
||||
'<(libchromiumcontent_src_dir)/v8/include',
|
||||
],
|
||||
'defines': [
|
||||
# Export V8 symbols from node.dll / libnode.so
|
||||
'BUILDING_V8_SHARED',
|
||||
'BUILDING_V8_PLATFORM_SHARED',
|
||||
'BUILDING_V8_BASE_SHARED',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac" and libchromiumcontent_component==0', {
|
||||
# -all_load is the "whole-archive" on macOS.
|
||||
|
||||
@@ -17,15 +17,27 @@ Please note, the `ARM` version of Windows is not supported for now.
|
||||
|
||||
### Linux
|
||||
|
||||
The prebuilt `ia32` (`i686`) and `x64` (`amd64`) binaries of Electron are built on
|
||||
Ubuntu 12.04, the `arm` binary is built against ARM v7 with hard-float ABI and
|
||||
NEON for Debian Wheezy.
|
||||
|
||||
Whether the prebuilt binary can run on a distribution depends on whether the
|
||||
distribution includes the libraries that Electron is linked to on the building
|
||||
platform, so only Ubuntu 12.04 is guaranteed to work, but following platforms
|
||||
are also verified to be able to run the prebuilt binaries of Electron:
|
||||
The prebuilt binaries of Electron are built for Debian Jessie, but whether the
|
||||
prebuilt binary can run on a distribution depends on whether the distribution
|
||||
includes the libraries that Electron is linked to on the building platform, so
|
||||
only Debian Jessie is guaranteed to work, but following platforms are also
|
||||
verified to be able to run the prebuilt binaries of Electron:
|
||||
|
||||
* Ubuntu 12.04 and later
|
||||
* Fedora 21
|
||||
* Debian 8
|
||||
* Debian 8 and later
|
||||
|
||||
Electorn provides prebuilt binaries for following CPU architectures:
|
||||
|
||||
* `ia32` (`i686`)
|
||||
* `x64` (`amd64`)
|
||||
* `armv7l`
|
||||
* `arm64`
|
||||
* `mips64el`
|
||||
|
||||
The `arm` binary is built against ARM v7 with hard-float ABI and NEON, and it is
|
||||
not guaranteed to run on all ARM platforms.
|
||||
|
||||
The `mips64el` binary is built with toolchains provided by Loongson, and it is
|
||||
not guaranteed to run on all MIPS64 platforms. And currently all certificate
|
||||
related APIs are not working on `mips64el` builds.
|
||||
|
||||
13
electron.gyp
13
electron.gyp
@@ -4,7 +4,7 @@
|
||||
'product_name%': 'Electron',
|
||||
'company_name%': 'GitHub, Inc',
|
||||
'company_abbr%': 'github',
|
||||
'version%': '1.8.2-beta.2',
|
||||
'version%': '1.8.3',
|
||||
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
|
||||
},
|
||||
'includes': [
|
||||
@@ -217,6 +217,11 @@
|
||||
],
|
||||
},
|
||||
],
|
||||
'link_settings': {
|
||||
'ldflags': [
|
||||
'-Wl,-z,noexecstack',
|
||||
],
|
||||
},
|
||||
}], # OS=="linux"
|
||||
],
|
||||
}, # target <(project_name)
|
||||
@@ -343,7 +348,6 @@
|
||||
['OS=="linux"', {
|
||||
'sources': [
|
||||
'<@(lib_sources_linux)',
|
||||
'<@(lib_sources_nss)',
|
||||
],
|
||||
'link_settings': {
|
||||
'ldflags': [
|
||||
@@ -366,6 +370,11 @@
|
||||
'vendor/breakpad/breakpad.gyp:breakpad_client',
|
||||
],
|
||||
}], # OS=="linux"
|
||||
['OS=="linux" and target_arch!="mips64el"', {
|
||||
'sources': [
|
||||
'<@(lib_sources_nss)',
|
||||
],
|
||||
}], # OS=="linux" and target_arch!="mips64el"
|
||||
['OS=="linux" and clang==1', {
|
||||
# Required settings of using breakpad.
|
||||
'cflags_cc': [
|
||||
|
||||
@@ -98,6 +98,8 @@
|
||||
'atom/app/atom_main_delegate.cc',
|
||||
'atom/app/atom_main_delegate.h',
|
||||
'atom/app/atom_main_delegate_mac.mm',
|
||||
'atom/app/command_line_args.cc',
|
||||
'atom/app/command_line_args.h',
|
||||
'atom/app/node_main.cc',
|
||||
'atom/app/node_main.h',
|
||||
'atom/app/uv_task_runner.cc',
|
||||
|
||||
@@ -44,20 +44,23 @@ Menu.prototype._init = function () {
|
||||
}
|
||||
|
||||
Menu.prototype.popup = function (window, x, y, positioningItem) {
|
||||
let asyncPopup
|
||||
let asyncPopup, opts
|
||||
let [newX, newY, newPosition, newWindow] = [x, y, positioningItem, window]
|
||||
|
||||
// menu.popup(x, y, positioningItem)
|
||||
if (!window) {
|
||||
// shift over values
|
||||
if (typeof window !== 'object' || window.constructor !== BrowserWindow) {
|
||||
[newPosition, newY, newX, newWindow] = [y, x, window, null]
|
||||
}
|
||||
if (window != null && !(window instanceof BrowserWindow)) {
|
||||
[newPosition, newY, newX, newWindow] = [y, x, window, null]
|
||||
}
|
||||
|
||||
// menu.popup({})
|
||||
if (window != null && window.constructor === Object) {
|
||||
opts = window
|
||||
// menu.popup(window, {})
|
||||
if (x && typeof x === 'object') {
|
||||
const opts = x
|
||||
} else if (x && typeof x === 'object') {
|
||||
opts = x
|
||||
}
|
||||
|
||||
if (opts) {
|
||||
newX = opts.x
|
||||
newY = opts.y
|
||||
newPosition = opts.positioningItem
|
||||
@@ -65,13 +68,28 @@ Menu.prototype.popup = function (window, x, y, positioningItem) {
|
||||
}
|
||||
|
||||
// set defaults
|
||||
if (typeof x !== 'number') newX = -1
|
||||
if (typeof y !== 'number') newY = -1
|
||||
if (typeof positioningItem !== 'number') newPosition = -1
|
||||
if (!window) newWindow = BrowserWindow.getFocusedWindow()
|
||||
if (typeof newX !== 'number') newX = -1
|
||||
if (typeof newY !== 'number') newY = -1
|
||||
if (typeof newPosition !== 'number') newPosition = -1
|
||||
if (typeof asyncPopup !== 'boolean') asyncPopup = false
|
||||
if (!newWindow || (newWindow && newWindow.constructor !== BrowserWindow)) {
|
||||
newWindow = BrowserWindow.getFocusedWindow()
|
||||
|
||||
// No window focused?
|
||||
if (!newWindow) {
|
||||
const browserWindows = BrowserWindow.getAllWindows()
|
||||
|
||||
if (browserWindows && browserWindows.length > 0) {
|
||||
newWindow = browserWindows[0]
|
||||
} else {
|
||||
throw new Error(`Cannot open Menu without a BrowserWindow present`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.popupAt(newWindow, newX, newY, newPosition, asyncPopup)
|
||||
|
||||
return { browserWindow: newWindow, x: newX, y: newY, position: newPosition, async: asyncPopup }
|
||||
}
|
||||
|
||||
Menu.prototype.closePopup = function (window) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "1.8.2-beta.2",
|
||||
"version": "1.8.3",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
@@ -12,7 +12,7 @@
|
||||
"dugite": "^1.45.0",
|
||||
"electabul": "~0.0.4",
|
||||
"electron-docs-linter": "^2.3.4",
|
||||
"electron-typescript-definitions": "^1.2.11",
|
||||
"electron-typescript-definitions": "~1.2.11",
|
||||
"github": "^9.2.0",
|
||||
"husky": "^0.14.3",
|
||||
"minimist": "^1.2.0",
|
||||
|
||||
@@ -28,6 +28,8 @@ def main():
|
||||
ninja += '.exe'
|
||||
|
||||
args = parse_args()
|
||||
if args.ninja_path:
|
||||
ninja = args.ninja_path
|
||||
if args.libcc:
|
||||
if ('D' not in args.configuration
|
||||
or not os.path.exists(GCLIENT_DONE)
|
||||
@@ -67,6 +69,9 @@ def parse_args():
|
||||
'-d --debug_libchromiumcontent.'
|
||||
),
|
||||
action='store_true', default=False)
|
||||
parser.add_argument('--ninja-path',
|
||||
help='Path of ninja command to use.',
|
||||
required=False)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ async function makeRequest (requestOptions, parseResponse) {
|
||||
} else {
|
||||
console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions)
|
||||
}
|
||||
reject()
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -199,7 +199,7 @@ function runRelease (targetBranch, options) {
|
||||
module.exports = runRelease
|
||||
|
||||
if (require.main === module) {
|
||||
const args = require('minimist')(process.argv.slice(2))
|
||||
const args = require('minimist')(process.argv.slice(2), { boolean: 'ghRelease' })
|
||||
const targetBranch = args._[0]
|
||||
if (args._.length < 1) {
|
||||
console.log(`Trigger CI to build release builds of electron.
|
||||
|
||||
@@ -215,7 +215,7 @@ def strip_binary(binary_path):
|
||||
elif get_target_arch() == 'arm64':
|
||||
strip = 'aarch64-linux-gnu-strip'
|
||||
elif get_target_arch() == 'mips64el':
|
||||
strip = 'mips64el-redhat-linux-strip'
|
||||
strip = 'mips64el-loongson-linux-strip'
|
||||
else:
|
||||
strip = 'strip'
|
||||
execute([strip, binary_path], env=build_env())
|
||||
|
||||
@@ -8,8 +8,8 @@ import sys
|
||||
# URL to the mips64el sysroot image.
|
||||
MIPS64EL_SYSROOT_URL = 'https://github.com/electron/debian-sysroot-image-creator/releases/download/v0.5.0/debian_jessie_mips64-sysroot.tar.bz2'
|
||||
# URL to the mips64el toolchain.
|
||||
MIPS64EL_GCC = 'gcc-4.8.3-d197-n64-loongson'
|
||||
MIPS64EL_GCC_URL = 'http://ftp.loongnix.org/toolchain/gcc/release/' + MIPS64EL_GCC + '.tar.gz'
|
||||
MIPS64EL_GCC = 'cross-gcc-4.9.3-n64-loongson-rc5.4'
|
||||
MIPS64EL_GCC_URL = 'https://github.com/electron/debian-sysroot-image-creator/releases/download/v0.5.0/' + MIPS64EL_GCC + '.tar.gz'
|
||||
|
||||
BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \
|
||||
'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent'
|
||||
@@ -93,11 +93,11 @@ def build_env():
|
||||
VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor')
|
||||
gcc_dir = os.path.join(VENDOR_DIR, MIPS64EL_GCC)
|
||||
ldlib_dirs = [
|
||||
gcc_dir + '/usr/x86_64-unknown-linux-gnu/mips64el-redhat-linux/lib',
|
||||
gcc_dir + '/usr/x86_64-unknown-linux-gnu/mips64el-loongson-linux/lib',
|
||||
gcc_dir + '/usr/lib64',
|
||||
gcc_dir + '/usr/mips64el-redhat-linux/lib64',
|
||||
gcc_dir + '/usr/mips64el-redhat-linux/sysroot/lib64',
|
||||
gcc_dir + '/usr/mips64el-redhat-linux/sysroot/usr/lib64',
|
||||
gcc_dir + '/usr/mips64el-loongson-linux/lib64',
|
||||
gcc_dir + '/usr/mips64el-loongson-linux/sysroot/lib64',
|
||||
gcc_dir + '/usr/mips64el-loongson-linux/sysroot/usr/lib64',
|
||||
]
|
||||
env['LD_LIBRARY_PATH'] = os.pathsep.join(ldlib_dirs)
|
||||
env['PATH'] = os.pathsep.join([gcc_dir + '/usr/bin', env['PATH']])
|
||||
|
||||
@@ -11,6 +11,7 @@ const GitHub = require('github')
|
||||
const pass = '\u2713'.green
|
||||
const path = require('path')
|
||||
const pkg = require('../package.json')
|
||||
const readline = require('readline')
|
||||
const versionType = args._[0]
|
||||
|
||||
// TODO (future) automatically determine version based on conventional commits
|
||||
@@ -45,18 +46,23 @@ async function createReleaseBranch () {
|
||||
}
|
||||
}
|
||||
|
||||
function getNewVersion () {
|
||||
function getNewVersion (dryRun) {
|
||||
console.log(`Bumping for new "${versionType}" version.`)
|
||||
let bumpScript = path.join(__dirname, 'bump-version.py')
|
||||
let scriptArgs = [bumpScript, `--bump ${versionType}`]
|
||||
if (args.stable) {
|
||||
scriptArgs.push('--stable')
|
||||
}
|
||||
if (dryRun) {
|
||||
scriptArgs.push('--dry-run')
|
||||
}
|
||||
try {
|
||||
let bumpVersion = execSync(scriptArgs.join(' '), {encoding: 'UTF-8'})
|
||||
bumpVersion = bumpVersion.substr(bumpVersion.indexOf(':') + 1).trim()
|
||||
let newVersion = `v${bumpVersion}`
|
||||
console.log(`${pass} Successfully bumped version to ${newVersion}`)
|
||||
if (!dryRun) {
|
||||
console.log(`${pass} Successfully bumped version to ${newVersion}`)
|
||||
}
|
||||
return newVersion
|
||||
} catch (err) {
|
||||
console.log(`${fail} Could not bump version, error was:`, err)
|
||||
@@ -119,23 +125,25 @@ async function createRelease (branchToTarget, isBeta) {
|
||||
.catch(err => {
|
||||
console.log('$fail} Could not get releases. Error was', err)
|
||||
})
|
||||
let drafts = releases.data.filter(release => release.draft)
|
||||
let drafts = releases.data.filter(release => release.draft &&
|
||||
release.tag_name === newVersion)
|
||||
if (drafts.length > 0) {
|
||||
console.log(`${fail} Aborting because draft release for
|
||||
${drafts[0].tag_name} already exists.`)
|
||||
process.exit(1)
|
||||
}
|
||||
console.log(`${pass} A draft release does not exist; creating one.`)
|
||||
githubOpts.body = releaseNotes
|
||||
githubOpts.draft = true
|
||||
githubOpts.name = `electron ${newVersion}`
|
||||
if (isBeta) {
|
||||
githubOpts.body = `Note: This is a beta release. Please file new issues ` +
|
||||
`for any bugs you find in it.\n \n This release is published to npm ` +
|
||||
`under the beta tag and can be installed via npm install electron@beta, ` +
|
||||
`or npm i electron@${newVersion.substr(1)}.`
|
||||
`or npm i electron@${newVersion.substr(1)}.\n \n ${releaseNotes}`
|
||||
githubOpts.name = `${githubOpts.name}`
|
||||
githubOpts.prerelease = true
|
||||
} else {
|
||||
githubOpts.body = releaseNotes
|
||||
}
|
||||
githubOpts.tag_name = newVersion
|
||||
githubOpts.target_commitish = branchToTarget
|
||||
@@ -165,12 +173,37 @@ async function runReleaseBuilds () {
|
||||
})
|
||||
}
|
||||
|
||||
async function verifyNewVersion () {
|
||||
let newVersion = await getNewVersion(true)
|
||||
let response = await promptForVersion(newVersion)
|
||||
if (response.match(/^y/i)) {
|
||||
console.log(`${pass} Starting release of ${newVersion}`)
|
||||
} else {
|
||||
console.log(`${fail} Aborting release of ${newVersion}`)
|
||||
process.exit()
|
||||
}
|
||||
}
|
||||
|
||||
async function promptForVersion (version) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
})
|
||||
rl.question(`Do you want to create the release ${version.green} (y/N)? `, (answer) => {
|
||||
rl.close()
|
||||
resolve(answer)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function prepareRelease (isBeta, notesOnly) {
|
||||
let currentBranch = await getCurrentBranch(gitDir)
|
||||
if (notesOnly) {
|
||||
let releaseNotes = await getReleaseNotes(currentBranch)
|
||||
console.log(`Draft release notes are: ${releaseNotes}`)
|
||||
} else {
|
||||
await verifyNewVersion()
|
||||
await createReleaseBranch()
|
||||
await createRelease(currentBranch, isBeta)
|
||||
await pushRelease()
|
||||
|
||||
@@ -21,7 +21,8 @@ const files = [
|
||||
'index.js',
|
||||
'install.js',
|
||||
'package.json',
|
||||
'README.md'
|
||||
'README.md',
|
||||
'LICENSE'
|
||||
]
|
||||
|
||||
const jsonFields = [
|
||||
@@ -49,9 +50,10 @@ new Promise((resolve, reject) => {
|
||||
tempDir = dirPath
|
||||
// copy files from `/npm` to temp directory
|
||||
files.forEach((name) => {
|
||||
const noThirdSegment = name === 'README.md' || name === 'LICENSE'
|
||||
fs.writeFileSync(
|
||||
path.join(tempDir, name),
|
||||
fs.readFileSync(path.join(__dirname, '..', name === 'README.md' ? '' : 'npm', name))
|
||||
fs.readFileSync(path.join(__dirname, '..', noThirdSegment ? '' : 'npm', name))
|
||||
)
|
||||
})
|
||||
// copy from root package.json to temp/package.json
|
||||
|
||||
@@ -31,21 +31,18 @@ async function getDraftRelease (version, skipValidation) {
|
||||
let drafts
|
||||
let versionToCheck
|
||||
if (version) {
|
||||
drafts = releaseInfo.data
|
||||
.filter(release => release.tag_name === version)
|
||||
versionToCheck = version
|
||||
} else {
|
||||
drafts = releaseInfo.data
|
||||
.filter(release => release.draft)
|
||||
versionToCheck = pkgVersion
|
||||
}
|
||||
|
||||
drafts = releaseInfo.data
|
||||
.filter(release => release.tag_name === versionToCheck &&
|
||||
release.draft === true)
|
||||
const draft = drafts[0]
|
||||
if (!skipValidation) {
|
||||
failureCount = 0
|
||||
check(drafts.length === 1, 'one draft exists', true)
|
||||
check(draft.tag_name === versionToCheck, `draft release version matches local package.json (${versionToCheck})`)
|
||||
if (versionToCheck.indexOf('beta')) {
|
||||
if (versionToCheck.indexOf('beta') > -1) {
|
||||
check(draft.prerelease, 'draft is a prerelease')
|
||||
}
|
||||
check(draft.body.length > 50 && !draft.body.includes('(placeholder)'), 'draft has release notes')
|
||||
@@ -54,8 +51,8 @@ async function getDraftRelease (version, skipValidation) {
|
||||
return draft
|
||||
}
|
||||
|
||||
async function validateReleaseAssets (release) {
|
||||
const requiredAssets = assetsForVersion(release.tag_name).sort()
|
||||
async function validateReleaseAssets (release, validatingRelease) {
|
||||
const requiredAssets = assetsForVersion(release.tag_name, validatingRelease).sort()
|
||||
const extantAssets = release.assets.map(asset => asset.name).sort()
|
||||
const downloadUrls = release.assets.map(asset => asset.browser_download_url).sort()
|
||||
|
||||
@@ -87,7 +84,7 @@ function check (condition, statement, exitIfFail = false) {
|
||||
}
|
||||
}
|
||||
|
||||
function assetsForVersion (version) {
|
||||
function assetsForVersion (version, validatingRelease) {
|
||||
const patterns = [
|
||||
`electron-${version}-darwin-x64-dsym.zip`,
|
||||
`electron-${version}-darwin-x64-symbols.zip`,
|
||||
@@ -123,9 +120,11 @@ function assetsForVersion (version) {
|
||||
`ffmpeg-${version}-linux-x64.zip`,
|
||||
`ffmpeg-${version}-mas-x64.zip`,
|
||||
`ffmpeg-${version}-win32-ia32.zip`,
|
||||
`ffmpeg-${version}-win32-x64.zip`,
|
||||
`SHASUMS256.txt`
|
||||
`ffmpeg-${version}-win32-x64.zip`
|
||||
]
|
||||
if (!validatingRelease) {
|
||||
patterns.push('SHASUMS256.txt')
|
||||
}
|
||||
return patterns
|
||||
}
|
||||
|
||||
@@ -215,7 +214,7 @@ async function uploadShasumFile (filePath, fileName, release) {
|
||||
filePath,
|
||||
name: fileName
|
||||
}
|
||||
return await github.repos.uploadAsset(githubOpts)
|
||||
return github.repos.uploadAsset(githubOpts)
|
||||
.catch(err => {
|
||||
console.log(`${fail} Error uploading ${filePath} to GitHub:`, err)
|
||||
process.exit(1)
|
||||
@@ -250,7 +249,7 @@ async function publishRelease (release) {
|
||||
tag_name: release.tag_name,
|
||||
draft: false
|
||||
}
|
||||
return await github.repos.editRelease(githubOpts)
|
||||
return github.repos.editRelease(githubOpts)
|
||||
.catch(err => {
|
||||
console.log(`${fail} Error publishing release:`, err)
|
||||
process.exit(1)
|
||||
@@ -259,9 +258,14 @@ async function publishRelease (release) {
|
||||
|
||||
async function makeRelease (releaseToValidate) {
|
||||
if (releaseToValidate) {
|
||||
console.log(`Validating release ${args.validateRelease}`)
|
||||
let release = await getDraftRelease(args.validateRelease)
|
||||
await validateReleaseAssets(release)
|
||||
if (releaseToValidate === true) {
|
||||
releaseToValidate = pkgVersion
|
||||
} else {
|
||||
console.log('Release to validate !=== true')
|
||||
}
|
||||
console.log(`Validating release ${releaseToValidate}`)
|
||||
let release = await getDraftRelease(releaseToValidate)
|
||||
await validateReleaseAssets(release, true)
|
||||
} else {
|
||||
checkVersion()
|
||||
let draftRelease = await getDraftRelease()
|
||||
@@ -447,7 +451,7 @@ async function cleanupReleaseBranch () {
|
||||
await callGit(['branch', '-D', 'release'], errorMessage, successMessage)
|
||||
errorMessage = `Could not delete remote release branch.`
|
||||
successMessage = `Successfully deleted remote release branch.`
|
||||
return await callGit(['push', 'origin', ':release'], errorMessage, successMessage)
|
||||
return callGit(['push', 'origin', ':release'], errorMessage, successMessage)
|
||||
}
|
||||
|
||||
async function callGit (args, errorMessage, successMessage) {
|
||||
|
||||
@@ -24,6 +24,7 @@ STAMP_FILE="${LLVM_DIR}/../llvm-build/cr_build_revision"
|
||||
LLVM_REPO_URL=${LLVM_URL:-https://llvm.org/svn/llvm-project}
|
||||
|
||||
CDS_URL=https://commondatastorage.googleapis.com/chromium-browser-clang
|
||||
S3_URL=https://s3.amazonaws.com/gh-contractor-zcbenz/clang
|
||||
|
||||
|
||||
# Die if any command dies, error on undefined variable expansions.
|
||||
@@ -45,32 +46,48 @@ rm -f "${STAMP_FILE}"
|
||||
|
||||
# Check if there's a prebuilt binary and if so just fetch that. That's faster,
|
||||
# and goma relies on having matching binary hashes on client and server too.
|
||||
CDS_FILE="clang-${PACKAGE_VERSION}.tgz"
|
||||
CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX)
|
||||
CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}"
|
||||
if [ "${OS}" = "Linux" ]; then
|
||||
CDS_FULL_URL="${CDS_URL}/Linux_x64/${CDS_FILE}"
|
||||
elif [ "${OS}" = "Darwin" ]; then
|
||||
CDS_FULL_URL="${CDS_URL}/Mac/${CDS_FILE}"
|
||||
fi
|
||||
echo Trying to download prebuilt clang
|
||||
if which curl > /dev/null; then
|
||||
curl -L --fail "${CDS_FULL_URL}" -o "${CDS_OUTPUT}" || \
|
||||
rm -rf "${CDS_OUT_DIR}"
|
||||
elif which wget > /dev/null; then
|
||||
wget "${CDS_FULL_URL}" -O "${CDS_OUTPUT}" || rm -rf "${CDS_OUT_DIR}"
|
||||
else
|
||||
echo "Neither curl nor wget found. Please install one of these."
|
||||
exit 1
|
||||
fi
|
||||
if [ -f "${CDS_OUTPUT}" ]; then
|
||||
rm -rf "${LLVM_BUILD_DIR}"
|
||||
mkdir -p "${LLVM_BUILD_DIR}"
|
||||
tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}"
|
||||
echo clang "${PACKAGE_VERSION}" unpacked
|
||||
echo "${PACKAGE_VERSION}" > "${STAMP_FILE}"
|
||||
rm -rf "${CDS_OUT_DIR}"
|
||||
exit 0
|
||||
else
|
||||
echo Did not find prebuilt clang "${PACKAGE_VERSION}", building
|
||||
rm -rf "${LLVM_BUILD_DIR}"
|
||||
mkdir -p "${LLVM_BUILD_DIR}"
|
||||
|
||||
CDS_FILES=("clang-${PACKAGE_VERSION}.tgz")
|
||||
CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX)
|
||||
if [ "${OS}" = "Linux" ]; then
|
||||
ARCH="$(uname -m)"
|
||||
if [ "${ARCH}" = "aarch64" ]; then
|
||||
CDS_URL="${S3_URL}"
|
||||
CDS_SUBDIR="arm64"
|
||||
else
|
||||
CDS_FILES+=("llvmgold-${PACKAGE_VERSION}.tgz")
|
||||
CDS_SUBDIR="Linux_x64"
|
||||
fi
|
||||
elif [ "${OS}" = "Darwin" ]; then
|
||||
CDS_SUBDIR="Mac"
|
||||
fi
|
||||
for CDS_FILE in "${CDS_FILES[@]}"
|
||||
do
|
||||
CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}"
|
||||
CDS_FULL_URL="${CDS_URL}/${CDS_SUBDIR}/${CDS_FILE}"
|
||||
|
||||
if which curl > /dev/null; then
|
||||
curl -L --fail "${CDS_FULL_URL}" -o "${CDS_OUTPUT}" || \
|
||||
rm -rf "${CDS_OUT_DIR}"
|
||||
elif which wget > /dev/null; then
|
||||
wget "${CDS_FULL_URL}" -O "${CDS_OUTPUT}" || rm -rf "${CDS_OUT_DIR}"
|
||||
else
|
||||
echo "Neither curl nor wget found. Please install one of these."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "${CDS_OUTPUT}" ]; then
|
||||
tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}"
|
||||
else
|
||||
echo Did not find prebuilt clang "${PACKAGE_VERSION}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo clang "${PACKAGE_VERSION}" unpacked
|
||||
echo "${PACKAGE_VERSION}" > "${STAMP_FILE}"
|
||||
rm -rf "${CDS_OUT_DIR}"
|
||||
exit 0
|
||||
|
||||
@@ -179,7 +179,7 @@ def get_text_with_editor(name):
|
||||
def create_or_get_release_draft(github, releases, tag, tag_exists):
|
||||
# Search for existing draft.
|
||||
for release in releases:
|
||||
if release['draft']:
|
||||
if release['draft'] and release['tag_name'] == tag:
|
||||
return release
|
||||
|
||||
if tag_exists:
|
||||
|
||||
@@ -531,6 +531,54 @@ describe('app module', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('app launch through uri', () => {
|
||||
before(function () {
|
||||
if (process.platform !== 'win32') {
|
||||
this.skip()
|
||||
}
|
||||
})
|
||||
|
||||
it('does not launch for blacklisted argument', function (done) {
|
||||
const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
|
||||
// App should exit with non 123 code.
|
||||
const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher=cmd.exe /c start calc'])
|
||||
first.once('exit', (code) => {
|
||||
assert.notEqual(code, 123)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('launches successfully for multiple uris in cmd args', function (done) {
|
||||
const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
|
||||
// App should exit with code 123.
|
||||
const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'http://electronjs.org', 'electron-test://testdata'])
|
||||
first.once('exit', (code) => {
|
||||
assert.equal(code, 123)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('does not launch for encoded space', function (done) {
|
||||
const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
|
||||
// App should exit with non 123 code.
|
||||
const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--no-sandbox', '--gpu-launcher%20"cmd.exe /c start calc'])
|
||||
first.once('exit', (code) => {
|
||||
assert.notEqual(code, 123)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('launches successfully for argnames similar to blacklisted ones', function (done) {
|
||||
const appPath = path.join(__dirname, 'fixtures', 'api', 'quit-app')
|
||||
// inspect is blacklisted, but inspector should work, and app launch should succeed
|
||||
const first = ChildProcess.spawn(remote.process.execPath, [appPath, 'electron-test://?', '--inspector'])
|
||||
first.once('exit', (code) => {
|
||||
assert.equal(code, 123)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getFileIcon() API', () => {
|
||||
const iconPath = path.join(__dirname, 'fixtures/assets/icon.ico')
|
||||
const sizes = {
|
||||
|
||||
@@ -279,14 +279,26 @@ describe('Menu module', () => {
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
menu.closePopup()
|
||||
menu.closePopup(w)
|
||||
return closeWindow(w).then(() => { w = null })
|
||||
})
|
||||
|
||||
describe('when called with async: true', () => {
|
||||
it('returns immediately', () => {
|
||||
menu.popup(w, {x: 100, y: 100, async: true})
|
||||
menu.closePopup(w)
|
||||
})
|
||||
it('returns immediately', () => {
|
||||
const { browserWindow, x, y, async } = menu.popup(w, {x: 100, y: 101, async: true})
|
||||
|
||||
assert.equal(browserWindow, w)
|
||||
assert.equal(x, 100)
|
||||
assert.equal(y, 101)
|
||||
assert.equal(async, true)
|
||||
})
|
||||
|
||||
it('works without a given BrowserWindow and options', () => {
|
||||
const { browserWindow, x, y } = menu.popup({x: 100, y: 101, async: true})
|
||||
|
||||
assert.equal(browserWindow.constructor.name, 'BrowserWindow')
|
||||
assert.equal(x, 100)
|
||||
assert.equal(y, 101)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -271,7 +271,8 @@ describe('session module', () => {
|
||||
})
|
||||
|
||||
describe('DownloadItem', () => {
|
||||
const mockPDF = new Buffer(1024 * 1024 * 5)
|
||||
const mockPDF = Buffer.alloc(1024 * 1024 * 5)
|
||||
const protocolName = 'custom-dl'
|
||||
let contentDisposition = 'inline; filename="mock.pdf"'
|
||||
const downloadFilePath = path.join(fixtures, 'mock.pdf')
|
||||
const downloadServer = http.createServer((req, res) => {
|
||||
@@ -286,11 +287,15 @@ describe('session module', () => {
|
||||
})
|
||||
const assertDownload = (event, state, url, mimeType,
|
||||
receivedBytes, totalBytes, disposition,
|
||||
filename, port, savePath) => {
|
||||
filename, port, savePath, isCustom) => {
|
||||
assert.equal(state, 'completed')
|
||||
assert.equal(filename, 'mock.pdf')
|
||||
assert.equal(savePath, path.join(__dirname, 'fixtures', 'mock.pdf'))
|
||||
assert.equal(url, `http://127.0.0.1:${port}/`)
|
||||
if (isCustom) {
|
||||
assert.equal(url, `${protocolName}://item`)
|
||||
} else {
|
||||
assert.equal(url, `http://127.0.0.1:${port}/`)
|
||||
}
|
||||
assert.equal(mimeType, 'application/pdf')
|
||||
assert.equal(receivedBytes, mockPDF.length)
|
||||
assert.equal(totalBytes, mockPDF.length)
|
||||
@@ -315,6 +320,30 @@ describe('session module', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('can download from custom protocols using WebContents.downloadURL', (done) => {
|
||||
const protocol = session.defaultSession.protocol
|
||||
downloadServer.listen(0, '127.0.0.1', () => {
|
||||
const port = downloadServer.address().port
|
||||
const handler = (ignoredError, callback) => {
|
||||
callback({url: `${url}:${port}`})
|
||||
}
|
||||
protocol.registerHttpProtocol(protocolName, handler, (error) => {
|
||||
if (error) return done(error)
|
||||
ipcRenderer.sendSync('set-download-option', false, false)
|
||||
w.webContents.downloadURL(`${protocolName}://item`)
|
||||
ipcRenderer.once('download-done', (event, state, url,
|
||||
mimeType, receivedBytes,
|
||||
totalBytes, disposition,
|
||||
filename, savePath) => {
|
||||
assertDownload(event, state, url, mimeType, receivedBytes,
|
||||
totalBytes, disposition, filename, port, savePath,
|
||||
true)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('can download using WebView.downloadURL', (done) => {
|
||||
downloadServer.listen(0, '127.0.0.1', () => {
|
||||
const port = downloadServer.address().port
|
||||
|
||||
@@ -30,7 +30,8 @@ describe('modules support', () => {
|
||||
|
||||
describe('ffi', () => {
|
||||
before(function () {
|
||||
if (!nativeModulesEnabled || process.platform === 'win32') {
|
||||
if (!nativeModulesEnabled || process.platform === 'win32' ||
|
||||
process.arch === 'arm64') {
|
||||
this.skip()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -293,6 +293,20 @@ describe('node feature', () => {
|
||||
buffer = new Buffer(new Array(4097).join(' '))
|
||||
assert.equal(buffer.length, 4096)
|
||||
})
|
||||
|
||||
it('does not crash for crypto operations', () => {
|
||||
const crypto = require('crypto')
|
||||
const data = 'lG9E+/g4JmRmedDAnihtBD4Dfaha/GFOjd+xUOQI05UtfVX3DjUXvrS98p7kZQwY3LNhdiFo7MY5rGft8yBuDhKuNNag9vRx/44IuClDhdQ='
|
||||
const key = 'q90K9yBqhWZnAMCMTOJfPQ=='
|
||||
const cipherText = '{"error_code":114,"error_message":"Tham số không hợp lệ","data":null}'
|
||||
for (let i = 0; i < 10000; ++i) {
|
||||
let iv = Buffer.from('0'.repeat(32), 'hex')
|
||||
let input = Buffer.from(data, 'base64')
|
||||
let decipher = crypto.createDecipheriv('aes-128-cbc', Buffer.from(key, 'base64'), iv)
|
||||
let result = Buffer.concat([decipher.update(input), decipher.final()])
|
||||
assert.equal(cipherText, result)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('process.stdout', () => {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
'clang%': 1,
|
||||
|
||||
# Path to mips64el toolchain.
|
||||
'make_mips64_dir%': 'vendor/gcc-4.8.3-d197-n64-loongson/usr',
|
||||
'make_mips64_dir%': 'vendor/cross-gcc-4.9.3-n64-loongson-rc5.4/usr',
|
||||
|
||||
'variables': {
|
||||
# The minimum macOS SDK version to use.
|
||||
@@ -104,8 +104,10 @@
|
||||
# Setup building with clang.
|
||||
['clang==1', {
|
||||
'make_global_settings': [
|
||||
['AR', '<(make_clang_dir)/bin/llvm-ar'],
|
||||
['CC', '<(make_clang_dir)/bin/clang'],
|
||||
['CXX', '<(make_clang_dir)/bin/clang++'],
|
||||
['AR.host', '<(make_clang_dir)/bin/llvm-ar'],
|
||||
['CC.host', '$(CC)'],
|
||||
['CXX.host', '$(CXX)'],
|
||||
],
|
||||
@@ -138,8 +140,8 @@
|
||||
|
||||
['target_arch=="mips64el"', {
|
||||
'make_global_settings': [
|
||||
['CC', '<(make_mips64_dir)/bin/mips64el-redhat-linux-gcc'],
|
||||
['CXX', '<(make_mips64_dir)/bin/mips64el-redhat-linux-g++'],
|
||||
['CC', '<(make_mips64_dir)/bin/mips64el-loongson-linux-gcc'],
|
||||
['CXX', '<(make_mips64_dir)/bin/mips64el-loongson-linux-g++'],
|
||||
['CC.host', '$(CC)'],
|
||||
['CXX.host', '$(CXX)'],
|
||||
],
|
||||
|
||||
2
vendor/libchromiumcontent
vendored
2
vendor/libchromiumcontent
vendored
Submodule vendor/libchromiumcontent updated: eb1db5393c...3f171a50cd
2
vendor/node
vendored
2
vendor/node
vendored
Submodule vendor/node updated: dc8fe9d390...2586ef1eb5
Reference in New Issue
Block a user