mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
139 Commits
v28.0.0-al
...
v1.8.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0602ca8e9c | ||
|
|
519a02d8d4 | ||
|
|
8ebd0ce1b1 | ||
|
|
61d9470b7a | ||
|
|
16e1b2340f | ||
|
|
f91aa3f37d | ||
|
|
a1a921325d | ||
|
|
65533961e2 | ||
|
|
77093d540f | ||
|
|
86438632d7 | ||
|
|
df69c6de2c | ||
|
|
e68bdbff65 | ||
|
|
caa889e270 | ||
|
|
700ea8731f | ||
|
|
e15e152177 | ||
|
|
8e9bdfc59d | ||
|
|
c96916ef94 | ||
|
|
959ffff316 | ||
|
|
66bd8c669d | ||
|
|
2bb22f776a | ||
|
|
baa12df67b | ||
|
|
d8b41482a2 | ||
|
|
43650d4053 | ||
|
|
8c50e14eee | ||
|
|
41eda591c2 | ||
|
|
2a90b5cbfa | ||
|
|
9bb3547809 | ||
|
|
9827185d60 | ||
|
|
ed3206a0f5 | ||
|
|
7189fb5bd8 | ||
|
|
44d9720629 | ||
|
|
1607708c33 | ||
|
|
cc7aa41303 | ||
|
|
acb9a47d50 | ||
|
|
8d7b348a70 | ||
|
|
adcddb8b32 | ||
|
|
c94eb28451 | ||
|
|
dccc98677b | ||
|
|
295a4f81dd | ||
|
|
6993ee352d | ||
|
|
9dfb85dd21 | ||
|
|
cf5e77c39f | ||
|
|
9a9b4910e8 | ||
|
|
8200d6cdbf | ||
|
|
c26372c0f3 | ||
|
|
ac75e00aee | ||
|
|
f95e5c71c0 | ||
|
|
ffe47c3f50 | ||
|
|
73c2652935 | ||
|
|
6c7e64cceb | ||
|
|
e2c7b43f25 | ||
|
|
8144e53bfd | ||
|
|
891ab8e256 | ||
|
|
fe2dfdc24d | ||
|
|
8efd31ab4d | ||
|
|
d2adedadd3 | ||
|
|
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 |
@@ -3,10 +3,10 @@ version: 2
|
|||||||
jobs:
|
jobs:
|
||||||
electron-linux-arm:
|
electron-linux-arm:
|
||||||
docker:
|
docker:
|
||||||
- image: electronbuilds/electron:0.0.3
|
- image: electronbuilds/electron:0.0.7
|
||||||
environment:
|
environment:
|
||||||
TARGET_ARCH: arm
|
TARGET_ARCH: arm
|
||||||
resource_class: xlarge
|
resource_class: 2xlarge
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
@@ -60,10 +60,10 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
electron-linux-arm64:
|
electron-linux-arm64:
|
||||||
docker:
|
docker:
|
||||||
- image: electronbuilds/electron:0.0.3
|
- image: electronbuilds/electron:0.0.7
|
||||||
environment:
|
environment:
|
||||||
TARGET_ARCH: arm64
|
TARGET_ARCH: arm64
|
||||||
resource_class: xlarge
|
resource_class: 2xlarge
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
@@ -117,7 +117,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
electron-linux-ia32:
|
electron-linux-ia32:
|
||||||
docker:
|
docker:
|
||||||
- image: electronbuilds/electron:0.0.3
|
- image: electronbuilds/electron:0.0.7
|
||||||
environment:
|
environment:
|
||||||
TARGET_ARCH: ia32
|
TARGET_ARCH: ia32
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
@@ -174,7 +174,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
electron-linux-mips64el:
|
electron-linux-mips64el:
|
||||||
docker:
|
docker:
|
||||||
- image: electronbuilds/electron:0.0.3
|
- image: electronbuilds/electron:0.0.7
|
||||||
environment:
|
environment:
|
||||||
TARGET_ARCH: mips64el
|
TARGET_ARCH: mips64el
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
@@ -232,11 +232,11 @@ jobs:
|
|||||||
|
|
||||||
electron-linux-x64:
|
electron-linux-x64:
|
||||||
docker:
|
docker:
|
||||||
- image: electronbuilds/electron:0.0.3
|
- image: electronbuilds/electron:0.0.7
|
||||||
environment:
|
environment:
|
||||||
TARGET_ARCH: x64
|
TARGET_ARCH: x64
|
||||||
DISPLAY: ':99.0'
|
DISPLAY: ':99.0'
|
||||||
resource_class: xlarge
|
resource_class: 2xlarge
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
@@ -262,6 +262,206 @@ jobs:
|
|||||||
- run: npm run lint
|
- run: npm run lint
|
||||||
- run:
|
- run:
|
||||||
name: Build
|
name: Build
|
||||||
|
no_output_timeout: 30m
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||||
|
echo 'Building Electron for release'
|
||||||
|
script/build.py -c R
|
||||||
|
else
|
||||||
|
echo 'Building Electron for debug'
|
||||||
|
script/build.py -c D
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Create distribution
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||||
|
echo 'Creating Electron release distribution'
|
||||||
|
script/create-dist.py
|
||||||
|
else
|
||||||
|
echo 'Skipping create distribution because build is not for release'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Upload distribution
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
||||||
|
echo 'Uploading Electron release distribution to github releases'
|
||||||
|
script/upload.py
|
||||||
|
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
||||||
|
echo 'Uploading Electron release distribution to s3'
|
||||||
|
script/upload.py --upload_to_s3
|
||||||
|
else
|
||||||
|
echo 'Skipping upload distribution because build is not for release'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Test
|
||||||
|
environment:
|
||||||
|
MOCHA_FILE: junit/test-results.xml
|
||||||
|
MOCHA_REPORTER: mocha-junit-reporter
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||||
|
echo 'Testing Electron debug build'
|
||||||
|
mkdir junit
|
||||||
|
script/test.py --ci --rebuild_native_modules
|
||||||
|
else
|
||||||
|
echo 'Skipping testing on release build'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Verify FFmpeg
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||||
|
echo 'Verifying ffmpeg on debug build'
|
||||||
|
script/verify-ffmpeg.py
|
||||||
|
else
|
||||||
|
echo 'Skipping verify ffmpeg on release build'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Generate Typescript Definitions
|
||||||
|
command: npm run create-typescript-definitions
|
||||||
|
- store_test_results:
|
||||||
|
path: junit
|
||||||
|
- store_artifacts:
|
||||||
|
path: junit
|
||||||
|
- store_artifacts:
|
||||||
|
path: out/electron.d.ts
|
||||||
|
- store_artifacts:
|
||||||
|
path: out/electron-api.json
|
||||||
|
|
||||||
|
electron-osx-x64:
|
||||||
|
environment:
|
||||||
|
TARGET_ARCH: x64
|
||||||
|
macos:
|
||||||
|
xcode: "9.0"
|
||||||
|
resource_class: 2xlarge
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: Reclaim disk space
|
||||||
|
command: |
|
||||||
|
df -h
|
||||||
|
sudo rm -rf /Library/Developer/CoreSimulator
|
||||||
|
df -h
|
||||||
|
sysctl -n hw.ncpu
|
||||||
|
- run:
|
||||||
|
name: Check for release
|
||||||
|
command: |
|
||||||
|
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||||
|
echo 'release build triggered from api'
|
||||||
|
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Bootstrap
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||||
|
echo 'Bootstrapping Electron for release build'
|
||||||
|
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||||
|
else
|
||||||
|
echo 'Bootstrapping Electron for debug build'
|
||||||
|
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||||
|
fi
|
||||||
|
- run: npm run lint
|
||||||
|
- run:
|
||||||
|
name: Build
|
||||||
|
no_output_timeout: 30m
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||||
|
echo 'Building Electron for release'
|
||||||
|
script/build.py -c R
|
||||||
|
else
|
||||||
|
echo 'Building Electron for debug'
|
||||||
|
script/build.py -c D
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Create distribution
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||||
|
echo 'Creating Electron release distribution'
|
||||||
|
script/create-dist.py
|
||||||
|
else
|
||||||
|
echo 'Skipping create distribution because build is not for release'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Upload distribution
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
||||||
|
echo 'Uploading Electron release distribution to github releases'
|
||||||
|
script/upload.py
|
||||||
|
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
||||||
|
echo 'Uploading Electron release distribution to s3'
|
||||||
|
script/upload.py --upload_to_s3
|
||||||
|
else
|
||||||
|
echo 'Skipping upload distribution because build is not for release'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Test
|
||||||
|
environment:
|
||||||
|
MOCHA_FILE: junit/test-results.xml
|
||||||
|
MOCHA_REPORTER: mocha-junit-reporter
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||||
|
echo 'Testing Electron debug build'
|
||||||
|
mkdir junit
|
||||||
|
script/test.py --ci --rebuild_native_modules
|
||||||
|
else
|
||||||
|
echo 'Skipping testing on release build'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Verify FFmpeg
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||||
|
echo 'Verifying ffmpeg on debug build'
|
||||||
|
script/verify-ffmpeg.py
|
||||||
|
else
|
||||||
|
echo 'Skipping verify ffmpeg on release build'
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Generate Typescript Definitions
|
||||||
|
command: npm run create-typescript-definitions
|
||||||
|
- store_test_results:
|
||||||
|
path: junit
|
||||||
|
- store_artifacts:
|
||||||
|
path: junit
|
||||||
|
- store_artifacts:
|
||||||
|
path: out/electron.d.ts
|
||||||
|
- store_artifacts:
|
||||||
|
path: out/electron-api.json
|
||||||
|
|
||||||
|
electron-mas-x64:
|
||||||
|
environment:
|
||||||
|
TARGET_ARCH: x64
|
||||||
|
MAS_BUILD: 1
|
||||||
|
macos:
|
||||||
|
xcode: "9.0"
|
||||||
|
resource_class: 2xlarge
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: Reclaim disk space
|
||||||
|
command: |
|
||||||
|
df -h
|
||||||
|
sudo rm -rf /Library/Developer/CoreSimulator
|
||||||
|
df -h
|
||||||
|
sysctl -n hw.ncpu
|
||||||
|
- run:
|
||||||
|
name: Check for release
|
||||||
|
command: |
|
||||||
|
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||||
|
echo 'release build triggered from api'
|
||||||
|
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Bootstrap
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||||
|
echo 'Bootstrapping Electron for release build'
|
||||||
|
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||||
|
else
|
||||||
|
echo 'Bootstrapping Electron for debug build'
|
||||||
|
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||||
|
fi
|
||||||
|
- run: npm run lint
|
||||||
|
- run:
|
||||||
|
name: Build
|
||||||
|
no_output_timeout: 30m
|
||||||
command: |
|
command: |
|
||||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||||
echo 'Building Electron for release'
|
echo 'Building Electron for release'
|
||||||
@@ -339,3 +539,12 @@ workflows:
|
|||||||
build-x64:
|
build-x64:
|
||||||
jobs:
|
jobs:
|
||||||
- electron-linux-x64
|
- electron-linux-x64
|
||||||
|
build-mips64el:
|
||||||
|
jobs:
|
||||||
|
- electron-linux-mips64el
|
||||||
|
build-osx-x64:
|
||||||
|
jobs:
|
||||||
|
- electron-osx-x64
|
||||||
|
build-mas-x64:
|
||||||
|
jobs:
|
||||||
|
- electron-mas-x64
|
||||||
|
|||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -28,6 +28,7 @@
|
|||||||
/external_binaries/
|
/external_binaries/
|
||||||
/out/
|
/out/
|
||||||
/vendor/.gclient
|
/vendor/.gclient
|
||||||
|
/vendor/cross-gcc-4.9.3-n64-loongson-rc5.4
|
||||||
/vendor/debian_jessie_amd64-sysroot/
|
/vendor/debian_jessie_amd64-sysroot/
|
||||||
/vendor/debian_jessie_arm-sysroot/
|
/vendor/debian_jessie_arm-sysroot/
|
||||||
/vendor/debian_jessie_arm64-sysroot/
|
/vendor/debian_jessie_arm64-sysroot/
|
||||||
@@ -36,13 +37,13 @@
|
|||||||
/vendor/debian_wheezy_amd64-sysroot/
|
/vendor/debian_wheezy_amd64-sysroot/
|
||||||
/vendor/debian_wheezy_arm-sysroot/
|
/vendor/debian_wheezy_arm-sysroot/
|
||||||
/vendor/debian_wheezy_i386-sysroot/
|
/vendor/debian_wheezy_i386-sysroot/
|
||||||
/vendor/gcc-4.8.3-d197-n64-loongson/
|
|
||||||
/vendor/readme-gcc483-loongson.txt
|
|
||||||
/vendor/download/
|
/vendor/download/
|
||||||
/vendor/llvm-build/
|
/vendor/llvm-build/
|
||||||
/vendor/llvm/
|
/vendor/llvm/
|
||||||
/vendor/node/deps/node-inspect/.npmrc
|
/vendor/node/deps/node-inspect/.npmrc
|
||||||
/vendor/npm/
|
/vendor/npm/
|
||||||
/vendor/python_26/
|
/vendor/python_26/
|
||||||
|
/vendor/native_mksnapshot
|
||||||
|
/vendor/LICENSES.chromium.html
|
||||||
node_modules/
|
node_modules/
|
||||||
SHASUMS256.txt
|
SHASUMS256.txt
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
|
|||||||
|
|
||||||
## Enforcement
|
## Enforcement
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [electron@github.com](mailto:electron@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [coc@electronjs.org](mailto:coc@electronjs.org). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
|
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
|
||||||
By participating, you are expected to uphold this code. Please report unacceptable
|
By participating, you are expected to uphold this code. Please report unacceptable
|
||||||
behavior to electron@github.com.
|
behavior to coc@electronjs.org.
|
||||||
|
|
||||||
The following is a set of guidelines for contributing to Electron.
|
The following is a set of guidelines for contributing to Electron.
|
||||||
These are just guidelines, not rules, use your best judgment and feel free to
|
These are just guidelines, not rules, use your best judgment and feel free to
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ ENV HOME=/home
|
|||||||
RUN chmod a+rwx /home
|
RUN chmod a+rwx /home
|
||||||
|
|
||||||
# Install node.js
|
# Install node.js
|
||||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
|
||||||
RUN apt-get update && apt-get install -y --force-yes nodejs
|
RUN apt-get update && apt-get install -y --force-yes nodejs
|
||||||
|
|
||||||
# Install wget used by crash reporter
|
# Install wget used by crash reporter
|
||||||
|
|||||||
64
Dockerfile.arm64v8
Normal file
64
Dockerfile.arm64v8
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
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 \
|
||||||
|
unzip \
|
||||||
|
wget \
|
||||||
|
xvfb
|
||||||
|
|
||||||
|
# Install node.js
|
||||||
|
RUN curl -sL https://deb.nodesource.com/setup_8.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
|
||||||
@@ -3,7 +3,7 @@ FROM electronbuilds/libchromiumcontent:0.0.4
|
|||||||
USER root
|
USER root
|
||||||
|
|
||||||
# Install node.js
|
# Install node.js
|
||||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
|
||||||
RUN apt-get update && apt-get install -y --force-yes nodejs
|
RUN apt-get update && apt-get install -y --force-yes nodejs
|
||||||
|
|
||||||
# Install wget used by crash reporter
|
# Install wget used by crash reporter
|
||||||
|
|||||||
36
Jenkinsfile.arm64
Normal file
36
Jenkinsfile.arm64
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
pipeline {
|
||||||
|
agent {
|
||||||
|
docker {
|
||||||
|
image 'electronbuilds/arm64v8:0.0.3'
|
||||||
|
args '--privileged'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
environment {
|
||||||
|
TARGET_ARCH='arm64'
|
||||||
|
DISPLAY=':99.0'
|
||||||
|
MOCHA_TIMEOUT='60000'
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ announcements.
|
|||||||
This project adheres to the Contributor Covenant
|
This project adheres to the Contributor Covenant
|
||||||
[code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md).
|
[code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md).
|
||||||
By participating, you are expected to uphold this code. Please report unacceptable
|
By participating, you are expected to uphold this code. Please report unacceptable
|
||||||
behavior to [electron@github.com](mailto:electron@github.com).
|
behavior to [coc@electronjs.org](mailto:coc@electronjs.org).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
The Electron team and community take security bugs in Electron seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
|
The Electron team and community take security bugs in Electron seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
|
||||||
|
|
||||||
To report a security issue, email [electron@github.com](mailto:electron@github.com) and include the word "SECURITY" in the subject line.
|
To report a security issue, email [security@electronjs.org](mailto:security@electronjs.org) and include the word "SECURITY" in the subject line.
|
||||||
|
|
||||||
The Electron team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
The Electron team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
||||||
|
|
||||||
|
|||||||
83
appveyor.yml
83
appveyor.yml
@@ -1,25 +1,58 @@
|
|||||||
# appveyor file
|
build_cloud: electron-16
|
||||||
# http://www.appveyor.com/docs/appveyor-yml
|
image: electron-16-vs2015
|
||||||
version: "{build}"
|
build_script:
|
||||||
|
- ps: >-
|
||||||
os: Visual Studio 2015
|
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||||
|
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||||
init:
|
} else {
|
||||||
- git config --global core.autocrlf input
|
Add-Path "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64"
|
||||||
|
$env:path = "$env:ProgramFiles (x86)\Windows Kits\10\Debuggers\x64;$env:path"
|
||||||
platform:
|
if($env:APPVEYOR_SCHEDULED_BUILD -eq 'True') {
|
||||||
- x86
|
$env:RUN_RELEASE_BUILD = "1"
|
||||||
- x64
|
}
|
||||||
|
$Message = (git log --format=%B -n 1 HEAD) | Out-String
|
||||||
install:
|
if ((Test-Path Env:\RUN_RELEASE_BUILD)) {
|
||||||
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\14.0\bin\;%PATH%
|
$env:ELECTRON_RELEASE = '1'
|
||||||
- cmd: SET PATH=C:\python27;%PATH%
|
Write-Output "release build triggered from api"
|
||||||
- cmd: python script/cibuild
|
}
|
||||||
|
if ((Test-Path Env:\ELECTRON_RELEASE)) {
|
||||||
branches:
|
Write-Output "Running release build"
|
||||||
only:
|
python script\bootstrap.py --target_arch=$env:TARGET_ARCH
|
||||||
- master
|
python script\build.py -c R
|
||||||
|
python script\create-dist.py
|
||||||
# disable build and test phases
|
} else {
|
||||||
build: off
|
Write-Output "Running debug build"
|
||||||
test: off
|
python script\bootstrap.py --target_arch=$env:TARGET_ARCH --dev
|
||||||
|
python script\build.py -c D
|
||||||
|
}
|
||||||
|
if ($? -ne 'True') {
|
||||||
|
throw "Build failed with exit code $?"
|
||||||
|
} else {
|
||||||
|
"Build succeeded."
|
||||||
|
}
|
||||||
|
Push-AppveyorArtifact out
|
||||||
|
}
|
||||||
|
test_script:
|
||||||
|
- ps: >-
|
||||||
|
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||||
|
Write-Output "Skipping tests for release build"
|
||||||
|
} else {
|
||||||
|
Write-Output "Running tests for debug build"
|
||||||
|
python script\test.py --ci --rebuild_native_modules
|
||||||
|
if ($LASTEXITCODE -ne '0') {
|
||||||
|
throw "Tests failed with exit code $LASTEXITCODE"
|
||||||
|
} else {
|
||||||
|
Write-Output "Tests succeeded."
|
||||||
|
}
|
||||||
|
python script\verify-ffmpeg.py
|
||||||
|
if ($LASTEXITCODE -ne '0') {
|
||||||
|
throw "Verify ffmpeg failed with exit code $LASTEXITCODE"
|
||||||
|
} else {
|
||||||
|
"Verify ffmpeg succeeded."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
artifacts:
|
||||||
|
- path: test-results.xml
|
||||||
|
name: test-results.xml
|
||||||
|
deploy_script:
|
||||||
|
- ps: "if (Test-Path Env:\\ELECTRON_RELEASE) {\n if (Test-Path Env:\\RUN_RELEASE_BUILD) {\n Write-Output \"Uploading Electron release distribution to s3\"\n & python script\\upload.py --upload_to_s3\n } else {\n Write-Output \"Uploading Electron release distribution to github releases\"\n & python script\\upload.py\n }\n} else {\n Write-Output \"Skipping upload distribution because build is not for release\"\n}"
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default")))
|
||||||
int AtomMain(int argc, const char* argv[]);
|
int AtomMain(int argc, char* argv[]);
|
||||||
|
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default")))
|
||||||
int AtomInitializeICUandStartNode(int argc, char *argv[]);
|
int AtomInitializeICUandStartNode(int argc, char *argv[]);
|
||||||
|
|||||||
@@ -15,11 +15,11 @@
|
|||||||
#include "content/public/app/content_main.h"
|
#include "content/public/app/content_main.h"
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
int AtomMain(int argc, const char* argv[]) {
|
int AtomMain(int argc, char* argv[]) {
|
||||||
atom::AtomMainDelegate delegate;
|
atom::AtomMainDelegate delegate;
|
||||||
content::ContentMainParams params(&delegate);
|
content::ContentMainParams params(&delegate);
|
||||||
params.argc = argc;
|
params.argc = argc;
|
||||||
params.argv = argv;
|
params.argv = const_cast<const char**>(argv);
|
||||||
atom::AtomCommandLine::Init(argc, argv);
|
atom::AtomCommandLine::Init(argc, argv);
|
||||||
return content::ContentMain(params);
|
return content::ContentMain(params);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
#include "atom/app/atom_main.h"
|
#include "atom/app/atom_main.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
#include <windows.h> // windows.h must be included first
|
#include <windows.h> // windows.h must be included first
|
||||||
@@ -15,9 +16,11 @@
|
|||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
#include "atom/app/atom_main_delegate.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 "atom/common/crash_reporter/win/crash_service_main.h"
|
||||||
#include "base/environment.h"
|
#include "base/environment.h"
|
||||||
#include "base/process/launch.h"
|
#include "base/process/launch.h"
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "base/win/windows_version.h"
|
#include "base/win/windows_version.h"
|
||||||
#include "content/public/app/sandbox_helper_win.h"
|
#include "content/public/app/sandbox_helper_win.h"
|
||||||
#include "sandbox/win/src/sandbox_types.h"
|
#include "sandbox/win/src/sandbox_types.h"
|
||||||
@@ -52,18 +55,23 @@ bool IsEnvSet(const char* name) {
|
|||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||||
int argc = 0;
|
struct Arguments {
|
||||||
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
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
|
#ifdef _DEBUG
|
||||||
// Don't display assert dialog boxes in CI test runs
|
// Don't display assert dialog boxes in CI test runs
|
||||||
static const auto kCI = "ELECTRON_CI";
|
static const auto kCI = "ELECTRON_CI";
|
||||||
bool is_ci = IsEnvSet(kCI);
|
bool is_ci = IsEnvSet(kCI);
|
||||||
if (!is_ci) {
|
if (!is_ci) {
|
||||||
for (int i = 0; i < argc; ++i) {
|
for (int i = 0; i < arguments.argc; ++i) {
|
||||||
if (!_wcsicmp(wargv[i], L"--ci")) {
|
if (!_wcsicmp(arguments.argv[i], L"--ci")) {
|
||||||
is_ci = true;
|
is_ci = true;
|
||||||
_putenv_s(kCI, "1"); // set flag for child processes
|
_putenv_s(kCI, "1"); // set flag for child processes
|
||||||
break;
|
break;
|
||||||
@@ -81,44 +89,12 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool run_as_node = IsEnvSet(kRunAsNode);
|
||||||
|
|
||||||
// Make sure the output is printed to console.
|
// Make sure the output is printed to console.
|
||||||
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
|
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
|
||||||
base::RouteStdioToConsole(false);
|
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
|
#ifndef DEBUG
|
||||||
// Chromium has its own TLS subsystem which supports automatic destruction
|
// Chromium has its own TLS subsystem which supports automatic destruction
|
||||||
// of thread-local data, and also depends on memory allocation routines
|
// 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
|
#endif
|
||||||
|
|
||||||
if (run_as_node) {
|
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::AtExitManager atexit_manager;
|
||||||
base::i18n::InitializeICU();
|
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")) {
|
} else if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
|
||||||
return crash_service::Main(cmd);
|
return crash_service::Main(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
|
||||||
|
return -1;
|
||||||
|
|
||||||
sandbox::SandboxInterfaceInfo sandbox_info = {0};
|
sandbox::SandboxInterfaceInfo sandbox_info = {0};
|
||||||
content::InitializeSandboxInfo(&sandbox_info);
|
content::InitializeSandboxInfo(&sandbox_info);
|
||||||
atom::AtomMainDelegate delegate;
|
atom::AtomMainDelegate delegate;
|
||||||
@@ -154,33 +139,32 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
|||||||
content::ContentMainParams params(&delegate);
|
content::ContentMainParams params(&delegate);
|
||||||
params.instance = instance;
|
params.instance = instance;
|
||||||
params.sandbox_info = &sandbox_info;
|
params.sandbox_info = &sandbox_info;
|
||||||
atom::AtomCommandLine::Init(argc, argv);
|
atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
|
||||||
atom::AtomCommandLine::InitW(argc, wargv);
|
|
||||||
return content::ContentMain(params);
|
return content::ContentMain(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (IsEnvSet(kRunAsNode)) {
|
if (IsEnvSet(kRunAsNode)) {
|
||||||
base::i18n::InitializeICU();
|
base::i18n::InitializeICU();
|
||||||
base::AtExitManager atexit_manager;
|
base::AtExitManager atexit_manager;
|
||||||
return atom::NodeMain(argc, const_cast<char**>(argv));
|
return atom::NodeMain(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
atom::AtomMainDelegate delegate;
|
atom::AtomMainDelegate delegate;
|
||||||
content::ContentMainParams params(&delegate);
|
content::ContentMainParams params(&delegate);
|
||||||
params.argc = argc;
|
params.argc = argc;
|
||||||
params.argv = argv;
|
params.argv = const_cast<const char**>(argv);
|
||||||
atom::AtomCommandLine::Init(argc, argv);
|
atom::AtomCommandLine::Init(argc, argv);
|
||||||
return content::ContentMain(params);
|
return content::ContentMain(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // defined(OS_LINUX)
|
#else // defined(OS_LINUX)
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (IsEnvSet(kRunAsNode)) {
|
if (IsEnvSet(kRunAsNode)) {
|
||||||
return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
|
return AtomInitializeICUandStartNode(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
return AtomMain(argc, argv);
|
return AtomMain(argc, argv);
|
||||||
|
|||||||
1389
atom/app/command_line_args.cc
Normal file
1389
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 (!override_argv) {
|
||||||
#if defined(OS_WIN)
|
|
||||||
const relauncher::StringVector& argv = atom::AtomCommandLine::wargv();
|
|
||||||
#else
|
|
||||||
const relauncher::StringVector& argv = atom::AtomCommandLine::argv();
|
const relauncher::StringVector& argv = atom::AtomCommandLine::argv();
|
||||||
#endif
|
|
||||||
return relauncher::RelaunchApp(argv);
|
return relauncher::RelaunchApp(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ void BrowserView::Init(v8::Isolate* isolate,
|
|||||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||||
api_web_contents_ = web_contents.get();
|
api_web_contents_ = web_contents.get();
|
||||||
|
|
||||||
view_.reset(NativeBrowserView::Create(
|
view_.reset(
|
||||||
api_web_contents_->managed_web_contents()->GetView()));
|
NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
|
||||||
|
|
||||||
InitWith(isolate, wrapper);
|
InitWith(isolate, wrapper);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
|||||||
// implemetation. This is a known and wontFix issue in webrtc (see:
|
// implemetation. This is a known and wontFix issue in webrtc (see:
|
||||||
// http://code.google.com/p/webrtc/issues/detail?id=3373)
|
// http://code.google.com/p/webrtc/issues/detail?id=3373)
|
||||||
options.set_disable_effects(false);
|
options.set_disable_effects(false);
|
||||||
|
options.set_allow_directx_capturer(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
|
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
|
||||||
|
|||||||
@@ -22,22 +22,16 @@ MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
|||||||
|
|
||||||
void MenuViews::PopupAt(
|
void MenuViews::PopupAt(
|
||||||
Window* window, int x, int y, int positioning_item, bool async) {
|
Window* window, int x, int y, int positioning_item, bool async) {
|
||||||
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
|
auto* native_window = static_cast<NativeWindowViews*>(window->window());
|
||||||
if (!native_window)
|
if (!native_window)
|
||||||
return;
|
return;
|
||||||
content::WebContents* web_contents = native_window->web_contents();
|
|
||||||
if (!web_contents)
|
|
||||||
return;
|
|
||||||
content::RenderWidgetHostView* view = web_contents->GetRenderWidgetHostView();
|
|
||||||
if (!view)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// (-1, -1) means showing on mouse location.
|
// (-1, -1) means showing on mouse location.
|
||||||
gfx::Point location;
|
gfx::Point location;
|
||||||
if (x == -1 || y == -1) {
|
if (x == -1 || y == -1) {
|
||||||
location = display::Screen::GetScreen()->GetCursorScreenPoint();
|
location = display::Screen::GetScreen()->GetCursorScreenPoint();
|
||||||
} else {
|
} else {
|
||||||
gfx::Point origin = view->GetViewBounds().origin();
|
gfx::Point origin = native_window->GetContentBounds().origin();
|
||||||
location = gfx::Point(origin.x() + x, origin.y() + y);
|
location = gfx::Point(origin.x() + x, origin.y() + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +49,7 @@ void MenuViews::PopupAt(
|
|||||||
menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner(
|
menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner(
|
||||||
model(), flags, close_callback));
|
model(), flags, close_callback));
|
||||||
ignore_result(menu_runners_[window_id]->RunMenuAt(
|
ignore_result(menu_runners_[window_id]->RunMenuAt(
|
||||||
static_cast<NativeWindowViews*>(window->window())->widget(),
|
native_window->widget(),
|
||||||
NULL,
|
NULL,
|
||||||
gfx::Rect(location, gfx::Size()),
|
gfx::Rect(location, gfx::Size()),
|
||||||
views::MENU_ANCHOR_TOPLEFT,
|
views::MENU_ANCHOR_TOPLEFT,
|
||||||
|
|||||||
@@ -78,10 +78,6 @@ class Protocol : public mate::TrackableObject<Protocol> {
|
|||||||
net::URLRequestJob* MaybeCreateJob(
|
net::URLRequestJob* MaybeCreateJob(
|
||||||
net::URLRequest* request,
|
net::URLRequest* request,
|
||||||
net::NetworkDelegate* network_delegate) const override {
|
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);
|
RequestJob* request_job = new RequestJob(request, network_delegate);
|
||||||
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
|
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
|
||||||
return request_job;
|
return request_job;
|
||||||
|
|||||||
@@ -271,6 +271,9 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
|
|||||||
void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
|
void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
|
||||||
const SkBitmap& bitmap,
|
const SkBitmap& bitmap,
|
||||||
content::ReadbackResponse response) {
|
content::ReadbackResponse response) {
|
||||||
|
// Hack to enable transparency in captured image
|
||||||
|
// TODO(nitsakh) Remove hack once fixed in chromium
|
||||||
|
const_cast<SkBitmap&>(bitmap).setAlphaType(kPremul_SkAlphaType);
|
||||||
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
|
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,8 +380,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
|
|||||||
options.Get("transparent", &transparent);
|
options.Get("transparent", &transparent);
|
||||||
|
|
||||||
content::WebContents::CreateParams params(session->browser_context());
|
content::WebContents::CreateParams params(session->browser_context());
|
||||||
auto* view = new OffScreenWebContentsView(
|
auto* view = new OffScreenWebContentsView(transparent,
|
||||||
transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this)));
|
base::Bind(&WebContents::OnPaint, base::Unretained(this)));
|
||||||
params.view = view;
|
params.view = view;
|
||||||
params.delegate_view = view;
|
params.delegate_view = view;
|
||||||
|
|
||||||
@@ -1644,10 +1647,10 @@ void WebContents::StartPainting() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
#if defined(ENABLE_OSR)
|
#if defined(ENABLE_OSR)
|
||||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||||
web_contents()->GetRenderWidgetHostView());
|
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||||
if (osr_rwhv)
|
if (osr_wcv)
|
||||||
osr_rwhv->SetPainting(true);
|
osr_wcv->SetPainting(true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1656,10 +1659,10 @@ void WebContents::StopPainting() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
#if defined(ENABLE_OSR)
|
#if defined(ENABLE_OSR)
|
||||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||||
web_contents()->GetRenderWidgetHostView());
|
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||||
if (osr_rwhv)
|
if (osr_wcv)
|
||||||
osr_rwhv->SetPainting(false);
|
osr_wcv->SetPainting(false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1668,9 +1671,10 @@ bool WebContents::IsPainting() const {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
#if defined(ENABLE_OSR)
|
#if defined(ENABLE_OSR)
|
||||||
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||||
web_contents()->GetRenderWidgetHostView());
|
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||||
return osr_rwhv && osr_rwhv->IsPainting();
|
|
||||||
|
return osr_wcv && osr_wcv->IsPainting();
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
@@ -1681,10 +1685,11 @@ void WebContents::SetFrameRate(int frame_rate) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
#if defined(ENABLE_OSR)
|
#if defined(ENABLE_OSR)
|
||||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||||
web_contents()->GetRenderWidgetHostView());
|
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||||
if (osr_rwhv)
|
|
||||||
osr_rwhv->SetFrameRate(frame_rate);
|
if (osr_wcv)
|
||||||
|
osr_wcv->SetFrameRate(frame_rate);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1693,9 +1698,10 @@ int WebContents::GetFrameRate() const {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#if defined(ENABLE_OSR)
|
#if defined(ENABLE_OSR)
|
||||||
const auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
const auto* wc_impl = static_cast<content::WebContentsImpl*>(web_contents());
|
||||||
web_contents()->GetRenderWidgetHostView());
|
auto* osr_wcv = static_cast<OffScreenWebContentsView*>(wc_impl->GetView());
|
||||||
return osr_rwhv ? osr_rwhv->GetFrameRate() : 0;
|
|
||||||
|
return osr_wcv ? osr_wcv->GetFrameRate() : 0;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
@@ -1765,6 +1771,14 @@ v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
|
|||||||
return mate::ConvertToV8(isolate, *web_preferences->web_preferences());
|
return mate::ConvertToV8(isolate, *web_preferences->web_preferences());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) {
|
||||||
|
WebContentsPreferences* web_preferences =
|
||||||
|
WebContentsPreferences::FromWebContents(web_contents());
|
||||||
|
if (!web_preferences)
|
||||||
|
return v8::Null(isolate);
|
||||||
|
return mate::ConvertToV8(isolate, *web_preferences->last_web_preferences());
|
||||||
|
}
|
||||||
|
|
||||||
v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() {
|
v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() {
|
||||||
if (owner_window())
|
if (owner_window())
|
||||||
return Window::From(isolate(), owner_window());
|
return Window::From(isolate(), owner_window());
|
||||||
@@ -1911,6 +1925,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
|||||||
.SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
|
.SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
|
||||||
.SetMethod("getType", &WebContents::GetType)
|
.SetMethod("getType", &WebContents::GetType)
|
||||||
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
|
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
|
||||||
|
.SetMethod("getLastWebPreferences", &WebContents::GetLastWebPreferences)
|
||||||
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
|
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
|
||||||
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
|
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
|
||||||
.SetMethod("unregisterServiceWorker",
|
.SetMethod("unregisterServiceWorker",
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
|||||||
|
|
||||||
// Returns the web preferences of current WebContents.
|
// Returns the web preferences of current WebContents.
|
||||||
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
|
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
|
||||||
|
v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate);
|
||||||
|
|
||||||
// Returns the owner window.
|
// Returns the owner window.
|
||||||
v8::Local<v8::Value> GetOwnerBrowserWindow();
|
v8::Local<v8::Value> GetOwnerBrowserWindow();
|
||||||
|
|||||||
@@ -889,6 +889,8 @@ void Window::SetBrowserView(v8::Local<v8::Value> value) {
|
|||||||
window_->SetBrowserView(browser_view->view());
|
window_->SetBrowserView(browser_view->view());
|
||||||
browser_view->web_contents()->SetOwnerWindow(window_.get());
|
browser_view->web_contents()->SetOwnerWindow(window_.get());
|
||||||
browser_view_.Reset(isolate(), value);
|
browser_view_.Reset(isolate(), value);
|
||||||
|
|
||||||
|
window_->UpdateDraggableRegionViews();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "content/public/browser/resource_dispatcher_host.h"
|
#include "content/public/browser/resource_dispatcher_host.h"
|
||||||
#include "content/public/browser/site_instance.h"
|
#include "content/public/browser/site_instance.h"
|
||||||
#include "content/public/browser/web_contents.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/content_switches.h"
|
||||||
#include "content/public/common/url_constants.h"
|
#include "content/public/common/url_constants.h"
|
||||||
#include "content/public/common/web_preferences.h"
|
#include "content/public/common/web_preferences.h"
|
||||||
@@ -243,6 +244,11 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
|||||||
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||||
base::CommandLine* command_line,
|
base::CommandLine* command_line,
|
||||||
int process_id) {
|
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 =
|
std::string process_type =
|
||||||
command_line->GetSwitchValueASCII(::switches::kProcessType);
|
command_line->GetSwitchValueASCII(::switches::kProcessType);
|
||||||
if (process_type != ::switches::kRendererProcess)
|
if (process_type != ::switches::kRendererProcess)
|
||||||
|
|||||||
@@ -7,14 +7,23 @@
|
|||||||
#include "atom/browser/native_browser_view.h"
|
#include "atom/browser/native_browser_view.h"
|
||||||
|
|
||||||
#include "atom/browser/api/atom_api_web_contents.h"
|
#include "atom/browser/api/atom_api_web_contents.h"
|
||||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
#include "brightray/browser/inspectable_web_contents.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
NativeBrowserView::NativeBrowserView(
|
NativeBrowserView::NativeBrowserView(
|
||||||
brightray::InspectableWebContentsView* web_contents_view)
|
brightray::InspectableWebContents* inspectable_web_contents)
|
||||||
: web_contents_view_(web_contents_view) {}
|
: inspectable_web_contents_(inspectable_web_contents) {}
|
||||||
|
|
||||||
NativeBrowserView::~NativeBrowserView() {}
|
NativeBrowserView::~NativeBrowserView() {}
|
||||||
|
|
||||||
|
brightray::InspectableWebContentsView*
|
||||||
|
NativeBrowserView::GetInspectableWebContentsView() {
|
||||||
|
return inspectable_web_contents_->GetView();
|
||||||
|
}
|
||||||
|
|
||||||
|
content::WebContents* NativeBrowserView::GetWebContents() {
|
||||||
|
return inspectable_web_contents_->GetWebContents();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|||||||
@@ -9,9 +9,11 @@
|
|||||||
|
|
||||||
#include "atom/common/draggable_region.h"
|
#include "atom/common/draggable_region.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
|
#include "content/public/browser/web_contents.h"
|
||||||
#include "third_party/skia/include/core/SkColor.h"
|
#include "third_party/skia/include/core/SkColor.h"
|
||||||
|
|
||||||
namespace brightray {
|
namespace brightray {
|
||||||
|
class InspectableWebContents;
|
||||||
class InspectableWebContentsView;
|
class InspectableWebContentsView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,12 +33,15 @@ class NativeBrowserView {
|
|||||||
virtual ~NativeBrowserView();
|
virtual ~NativeBrowserView();
|
||||||
|
|
||||||
static NativeBrowserView* Create(
|
static NativeBrowserView* Create(
|
||||||
brightray::InspectableWebContentsView* web_contents_view);
|
brightray::InspectableWebContents* inspectable_web_contents);
|
||||||
|
|
||||||
brightray::InspectableWebContentsView* GetInspectableWebContentsView() {
|
brightray::InspectableWebContents* GetInspectableWebContents() {
|
||||||
return web_contents_view_;
|
return inspectable_web_contents_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
brightray::InspectableWebContentsView* GetInspectableWebContentsView();
|
||||||
|
content::WebContents* GetWebContents();
|
||||||
|
|
||||||
virtual void SetAutoResizeFlags(uint8_t flags) = 0;
|
virtual void SetAutoResizeFlags(uint8_t flags) = 0;
|
||||||
virtual void SetBounds(const gfx::Rect& bounds) = 0;
|
virtual void SetBounds(const gfx::Rect& bounds) = 0;
|
||||||
virtual void SetBackgroundColor(SkColor color) = 0;
|
virtual void SetBackgroundColor(SkColor color) = 0;
|
||||||
@@ -47,9 +52,9 @@ class NativeBrowserView {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit NativeBrowserView(
|
explicit NativeBrowserView(
|
||||||
brightray::InspectableWebContentsView* web_contents_view);
|
brightray::InspectableWebContents* inspectable_web_contents);
|
||||||
|
|
||||||
brightray::InspectableWebContentsView* web_contents_view_;
|
brightray::InspectableWebContents* inspectable_web_contents_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(NativeBrowserView);
|
DISALLOW_COPY_AND_ASSIGN(NativeBrowserView);
|
||||||
|
|||||||
@@ -17,12 +17,13 @@ namespace atom {
|
|||||||
class NativeBrowserViewMac : public NativeBrowserView {
|
class NativeBrowserViewMac : public NativeBrowserView {
|
||||||
public:
|
public:
|
||||||
explicit NativeBrowserViewMac(
|
explicit NativeBrowserViewMac(
|
||||||
brightray::InspectableWebContentsView* web_contents_view);
|
brightray::InspectableWebContents* inspectable_web_contents);
|
||||||
~NativeBrowserViewMac() override;
|
~NativeBrowserViewMac() override;
|
||||||
|
|
||||||
void SetAutoResizeFlags(uint8_t flags) override;
|
void SetAutoResizeFlags(uint8_t flags) override;
|
||||||
void SetBounds(const gfx::Rect& bounds) override;
|
void SetBounds(const gfx::Rect& bounds) override;
|
||||||
void SetBackgroundColor(SkColor color) override;
|
void SetBackgroundColor(SkColor color) override;
|
||||||
|
|
||||||
void UpdateDraggableRegions(
|
void UpdateDraggableRegions(
|
||||||
const std::vector<gfx::Rect>& system_drag_exclude_areas) override;
|
const std::vector<gfx::Rect>& system_drag_exclude_areas) override;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "atom/browser/native_browser_view_mac.h"
|
#include "atom/browser/native_browser_view_mac.h"
|
||||||
|
|
||||||
|
#include "brightray/browser/inspectable_web_contents.h"
|
||||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||||
#include "skia/ext/skia_utils_mac.h"
|
#include "skia/ext/skia_utils_mac.h"
|
||||||
#include "ui/gfx/geometry/rect.h"
|
#include "ui/gfx/geometry/rect.h"
|
||||||
@@ -156,8 +157,8 @@ const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
|
|||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
NativeBrowserViewMac::NativeBrowserViewMac(
|
NativeBrowserViewMac::NativeBrowserViewMac(
|
||||||
brightray::InspectableWebContentsView* web_contents_view)
|
brightray::InspectableWebContents* inspectable_web_contents)
|
||||||
: NativeBrowserView(web_contents_view) {
|
: NativeBrowserView(inspectable_web_contents) {
|
||||||
auto* view = GetInspectableWebContentsView()->GetNativeView();
|
auto* view = GetInspectableWebContentsView()->GetNativeView();
|
||||||
view.autoresizingMask = kDefaultAutoResizingMask;
|
view.autoresizingMask = kDefaultAutoResizingMask;
|
||||||
}
|
}
|
||||||
@@ -193,62 +194,46 @@ void NativeBrowserViewMac::SetBackgroundColor(SkColor color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NativeBrowserViewMac::UpdateDraggableRegions(
|
void NativeBrowserViewMac::UpdateDraggableRegions(
|
||||||
const std::vector<gfx::Rect>& system_drag_exclude_areas) {
|
const std::vector<gfx::Rect>& drag_exclude_rects) {
|
||||||
NSView* webView = GetInspectableWebContentsView()->GetNativeView();
|
NSView* web_view = GetWebContents()->GetNativeView();
|
||||||
|
NSView* inspectable_view = GetInspectableWebContentsView()->GetNativeView();
|
||||||
|
NSView* window_content_view = inspectable_view.superview;
|
||||||
|
const auto window_content_view_height = NSHeight(window_content_view.bounds);
|
||||||
|
|
||||||
NSInteger superViewHeight = NSHeight([webView.superview bounds]);
|
// Remove all DragRegionViews that were added last time. Note that we need
|
||||||
NSInteger webViewHeight = NSHeight([webView bounds]);
|
// to copy the `subviews` array to avoid mutation during iteration.
|
||||||
NSInteger webViewWidth = NSWidth([webView bounds]);
|
base::scoped_nsobject<NSArray> subviews([[web_view subviews] copy]);
|
||||||
NSInteger webViewX = NSMinX([webView frame]);
|
for (NSView* subview in subviews.get()) {
|
||||||
NSInteger webViewY = 0;
|
if ([subview isKindOfClass:[DragRegionView class]]) {
|
||||||
|
|
||||||
// Apple's NSViews have their coordinate system originate at the bottom left,
|
|
||||||
// meaning that we need to be a bit smarter when it comes to calculating our
|
|
||||||
// current top offset
|
|
||||||
if (webViewHeight > superViewHeight) {
|
|
||||||
webViewY = std::abs(webViewHeight - superViewHeight - (std::abs(NSMinY([webView frame]))));
|
|
||||||
} else {
|
|
||||||
webViewY = superViewHeight - NSMaxY([webView frame]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove all DraggableRegionViews that are added last time.
|
|
||||||
// Note that [webView subviews] returns the view's mutable internal array and
|
|
||||||
// it should be copied to avoid mutating the original array while enumerating
|
|
||||||
// it.
|
|
||||||
base::scoped_nsobject<NSArray> subviews([[webView subviews] copy]);
|
|
||||||
for (NSView* subview in subviews.get())
|
|
||||||
if ([subview isKindOfClass:[DragRegionView class]])
|
|
||||||
[subview removeFromSuperview];
|
[subview removeFromSuperview];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create one giant NSView that is draggable.
|
// Create one giant NSView that is draggable.
|
||||||
base::scoped_nsobject<NSView> dragRegion(
|
base::scoped_nsobject<NSView> drag_region_view(
|
||||||
[[DragRegionView alloc] initWithFrame:NSZeroRect]);
|
[[DragRegionView alloc] initWithFrame:web_view.bounds]);
|
||||||
[dragRegion setFrame:NSMakeRect(0,
|
[web_view addSubview:drag_region_view];
|
||||||
0,
|
|
||||||
webViewWidth,
|
|
||||||
webViewHeight)];
|
|
||||||
|
|
||||||
// Then, on top of that, add "exclusion zones"
|
// Then, on top of that, add "exclusion zones"
|
||||||
for (auto iter = system_drag_exclude_areas.begin();
|
for (const auto& rect : drag_exclude_rects) {
|
||||||
iter != system_drag_exclude_areas.end();
|
const auto window_content_view_exclude_rect =
|
||||||
++iter) {
|
NSMakeRect(rect.x(), window_content_view_height - rect.bottom(),
|
||||||
base::scoped_nsobject<NSView> controlRegion(
|
rect.width(), rect.height());
|
||||||
[[ExcludeDragRegionView alloc] initWithFrame:NSZeroRect]);
|
const auto drag_region_view_exclude_rect =
|
||||||
[controlRegion setFrame:NSMakeRect(iter->x() - webViewX,
|
[window_content_view convertRect:window_content_view_exclude_rect
|
||||||
webViewHeight - iter->bottom() + webViewY,
|
toView:drag_region_view];
|
||||||
iter->width(),
|
|
||||||
iter->height())];
|
|
||||||
[dragRegion addSubview:controlRegion];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the DragRegion to the WebView
|
base::scoped_nsobject<NSView> exclude_drag_region_view(
|
||||||
[webView addSubview:dragRegion];
|
[[ExcludeDragRegionView alloc]
|
||||||
|
initWithFrame:drag_region_view_exclude_rect]);
|
||||||
|
[drag_region_view addSubview:exclude_drag_region_view];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
NativeBrowserView* NativeBrowserView::Create(
|
NativeBrowserView* NativeBrowserView::Create(
|
||||||
brightray::InspectableWebContentsView* web_contents_view) {
|
brightray::InspectableWebContents* inspectable_web_contents) {
|
||||||
return new NativeBrowserViewMac(web_contents_view);
|
return new NativeBrowserViewMac(inspectable_web_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
NativeBrowserViewViews::NativeBrowserViewViews(
|
NativeBrowserViewViews::NativeBrowserViewViews(
|
||||||
brightray::InspectableWebContentsView* web_contents_view)
|
brightray::InspectableWebContents* inspectable_web_contents)
|
||||||
: NativeBrowserView(web_contents_view) {}
|
: NativeBrowserView(inspectable_web_contents) {}
|
||||||
|
|
||||||
NativeBrowserViewViews::~NativeBrowserViewViews() {}
|
NativeBrowserViewViews::~NativeBrowserViewViews() {}
|
||||||
|
|
||||||
@@ -29,8 +29,8 @@ void NativeBrowserViewViews::SetBackgroundColor(SkColor color) {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
NativeBrowserView* NativeBrowserView::Create(
|
NativeBrowserView* NativeBrowserView::Create(
|
||||||
brightray::InspectableWebContentsView* web_contents_view) {
|
brightray::InspectableWebContents* inspectable_web_contents) {
|
||||||
return new NativeBrowserViewViews(web_contents_view);
|
return new NativeBrowserViewViews(inspectable_web_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace atom {
|
|||||||
class NativeBrowserViewViews : public NativeBrowserView {
|
class NativeBrowserViewViews : public NativeBrowserView {
|
||||||
public:
|
public:
|
||||||
explicit NativeBrowserViewViews(
|
explicit NativeBrowserViewViews(
|
||||||
brightray::InspectableWebContentsView* web_contents_view);
|
brightray::InspectableWebContents* inspectable_web_contents);
|
||||||
~NativeBrowserViewViews() override;
|
~NativeBrowserViewViews() override;
|
||||||
|
|
||||||
uint8_t GetAutoResizeFlags() { return auto_resize_flags_; }
|
uint8_t GetAutoResizeFlags() { return auto_resize_flags_; }
|
||||||
|
|||||||
@@ -237,6 +237,8 @@ class NativeWindow : public base::SupportsUserData,
|
|||||||
const std::vector<base::string16>& labels) {}
|
const std::vector<base::string16>& labels) {}
|
||||||
virtual void HideAutofillPopup(content::RenderFrameHost* frame_host) {}
|
virtual void HideAutofillPopup(content::RenderFrameHost* frame_host) {}
|
||||||
|
|
||||||
|
virtual void UpdateDraggableRegionViews() {}
|
||||||
|
|
||||||
// Public API used by platform-dependent delegates and observers to send UI
|
// Public API used by platform-dependent delegates and observers to send UI
|
||||||
// related notifications.
|
// related notifications.
|
||||||
void NotifyWindowClosed();
|
void NotifyWindowClosed();
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ class NativeWindowMac : public NativeWindow,
|
|||||||
content::RenderViewHost* new_host) override;
|
content::RenderViewHost* new_host) override;
|
||||||
|
|
||||||
// Refresh the DraggableRegion views.
|
// Refresh the DraggableRegion views.
|
||||||
void UpdateDraggableRegionViews() {
|
void UpdateDraggableRegionViews() override {
|
||||||
UpdateDraggableRegionViews(draggable_regions_);
|
UpdateDraggableRegionViews(draggable_regions_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1932,25 +1932,20 @@ void NativeWindowMac::UpdateDraggableRegionViews(
|
|||||||
|
|
||||||
// Draggable regions is implemented by having the whole web view draggable
|
// Draggable regions is implemented by having the whole web view draggable
|
||||||
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
|
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
|
||||||
std::vector<gfx::Rect> system_drag_exclude_areas =
|
std::vector<gfx::Rect> drag_exclude_rects =
|
||||||
CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight);
|
CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight);
|
||||||
|
|
||||||
if (browser_view_) {
|
if (browser_view_) {
|
||||||
browser_view_->UpdateDraggableRegions(system_drag_exclude_areas);
|
browser_view_->UpdateDraggableRegions(drag_exclude_rects);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and add a ControlRegionView for each region that needs to be
|
// Create and add a ControlRegionView for each region that needs to be
|
||||||
// excluded from the dragging.
|
// excluded from the dragging.
|
||||||
for (std::vector<gfx::Rect>::const_iterator iter =
|
for (const auto& rect : drag_exclude_rects) {
|
||||||
system_drag_exclude_areas.begin();
|
|
||||||
iter != system_drag_exclude_areas.end();
|
|
||||||
++iter) {
|
|
||||||
base::scoped_nsobject<NSView> controlRegion(
|
base::scoped_nsobject<NSView> controlRegion(
|
||||||
[[ControlRegionView alloc] initWithFrame:NSZeroRect]);
|
[[ControlRegionView alloc] initWithFrame:NSZeroRect]);
|
||||||
[controlRegion setFrame:NSMakeRect(iter->x(),
|
[controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(),
|
||||||
webViewHeight - iter->bottom(),
|
rect.width(), rect.height())];
|
||||||
iter->width(),
|
|
||||||
iter->height())];
|
|
||||||
[webView addSubview:controlRegion];
|
[webView addSubview:controlRegion];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
#include "atom/browser/ui/views/win_frame_view.h"
|
#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_native_widget_aura.h"
|
||||||
#include "atom/browser/ui/win/atom_desktop_window_tree_host_win.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 "skia/ext/skia_utils_win.h"
|
||||||
#include "ui/base/win/shell.h"
|
#include "ui/base/win/shell.h"
|
||||||
#include "ui/display/display.h"
|
#include "ui/display/display.h"
|
||||||
@@ -297,9 +298,12 @@ NativeWindowViews::NativeWindowViews(
|
|||||||
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
|
::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hardware_accelerated =
|
||||||
|
content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled();
|
||||||
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
|
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
|
||||||
// Window without thick frame has to have WS_EX_COMPOSITED style.
|
// Window without thick frame has to have WS_EX_COMPOSITED style when GPU
|
||||||
if (!thick_frame_)
|
// acceleration is enabled.
|
||||||
|
if (!thick_frame_ && hardware_accelerated)
|
||||||
ex_style |= WS_EX_COMPOSITED;
|
ex_style |= WS_EX_COMPOSITED;
|
||||||
if (window_type == "toolbar")
|
if (window_type == "toolbar")
|
||||||
ex_style |= WS_EX_TOOLWINDOW;
|
ex_style |= WS_EX_TOOLWINDOW;
|
||||||
@@ -1363,22 +1367,26 @@ void NativeWindowViews::ShowAutofillPopup(
|
|||||||
const gfx::RectF& bounds,
|
const gfx::RectF& bounds,
|
||||||
const std::vector<base::string16>& values,
|
const std::vector<base::string16>& values,
|
||||||
const std::vector<base::string16>& labels) {
|
const std::vector<base::string16>& labels) {
|
||||||
const auto* web_preferences =
|
|
||||||
WebContentsPreferences::FromWebContents(web_contents)->web_preferences();
|
|
||||||
|
|
||||||
bool is_offsceen = false;
|
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;
|
bool is_embedder_offscreen = false;
|
||||||
if (guest_instance_id) {
|
|
||||||
auto manager = WebViewManager::GetWebViewManager(web_contents);
|
auto* web_contents_preferences =
|
||||||
if (manager) {
|
WebContentsPreferences::FromWebContents(web_contents);
|
||||||
auto embedder = manager->GetEmbedder(guest_instance_id);
|
if (web_contents_preferences) {
|
||||||
if (embedder) {
|
const auto* web_preferences = web_contents_preferences->web_preferences();
|
||||||
is_embedder_offscreen = WebContentsPreferences::IsPreferenceEnabled(
|
|
||||||
"offscreen", embedder);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -245,10 +245,21 @@ void URLRequestAsarJob::FetchMetaInfo(const base::FilePath& file_path,
|
|||||||
meta_info->file_size = file_info.size;
|
meta_info->file_size = file_info.size;
|
||||||
meta_info->is_directory = file_info.is_directory;
|
meta_info->is_directory = file_info.is_directory;
|
||||||
}
|
}
|
||||||
// On Windows GetMimeTypeFromFile() goes to the registry. Thus it should be
|
|
||||||
// done in WorkerPool.
|
// We use GetWellKnownMimeTypeFromExtension() to ensure that configurations
|
||||||
meta_info->mime_type_result =
|
// that may have been set by other programs on a user's machine don't affect
|
||||||
net::GetMimeTypeFromFile(file_path, &meta_info->mime_type);
|
// the mime type returned (in particular, JS should always be
|
||||||
|
// (application/javascript). See https://crbug.com/797712. Using an accurate
|
||||||
|
// mime type is necessary at least for modules and sw, which enforce strict
|
||||||
|
// mime type requirements.
|
||||||
|
// TODO(deepak1556): Revert this when sw support is removed for file scheme.
|
||||||
|
base::FilePath::StringType file_extension = file_path.Extension();
|
||||||
|
if (file_extension.empty()) {
|
||||||
|
meta_info->mime_type_result = false;
|
||||||
|
} else {
|
||||||
|
meta_info->mime_type_result = net::GetWellKnownMimeTypeFromExtension(
|
||||||
|
file_extension.substr(1), &meta_info->mime_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void URLRequestAsarJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) {
|
void URLRequestAsarJob::DidFetchMetaInfo(const FileMetaInfo* meta_info) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "atom/browser/api/atom_api_url_request.h"
|
#include "atom/browser/api/atom_api_url_request.h"
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
|
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||||
#include "base/callback.h"
|
#include "base/callback.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "net/base/elements_upload_data_stream.h"
|
#include "net/base/elements_upload_data_stream.h"
|
||||||
@@ -120,6 +121,9 @@ void AtomURLRequest::DoInitialize(
|
|||||||
request_->set_method(method);
|
request_->set_method(method);
|
||||||
// Do not send cookies from the cookie store.
|
// Do not send cookies from the cookie store.
|
||||||
DoSetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES);
|
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() {
|
void AtomURLRequest::DoTerminate() {
|
||||||
|
|||||||
@@ -15,8 +15,18 @@ using content::BrowserThread;
|
|||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
int disable_protocol_intercept_flag_key = 0;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
|
typedef net::URLRequestJobFactory::ProtocolHandler ProtocolHandler;
|
||||||
|
|
||||||
|
const void* DisableProtocolInterceptFlagKey() {
|
||||||
|
return &disable_protocol_intercept_flag_key;
|
||||||
|
}
|
||||||
|
|
||||||
AtomURLRequestJobFactory::AtomURLRequestJobFactory() {}
|
AtomURLRequestJobFactory::AtomURLRequestJobFactory() {}
|
||||||
|
|
||||||
AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
|
AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
|
||||||
@@ -93,6 +103,8 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
|
|||||||
auto it = protocol_handler_map_.find(scheme);
|
auto it = protocol_handler_map_.find(scheme);
|
||||||
if (it == protocol_handler_map_.end())
|
if (it == protocol_handler_map_.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
if (request->GetUserData(DisableProtocolInterceptFlagKey()))
|
||||||
|
return nullptr;
|
||||||
return it->second->MaybeCreateJob(request, network_delegate);
|
return it->second->MaybeCreateJob(request, network_delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
const void* DisableProtocolInterceptFlagKey();
|
||||||
|
|
||||||
class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
|
class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
|
||||||
public:
|
public:
|
||||||
AtomURLRequestJobFactory();
|
AtomURLRequestJobFactory();
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ void NodeDebugger::Start() {
|
|||||||
// the debugger on the first line
|
// the debugger on the first line
|
||||||
if (options.wait_for_connect()) {
|
if (options.wait_for_connect()) {
|
||||||
mate::Dictionary process(env_->isolate(), env_->process_object());
|
mate::Dictionary process(env_->isolate(), env_->process_object());
|
||||||
process.Set("_debugWaitConnect", true);
|
process.Set("_breakFirstLine", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inspector->Start(platform_.get(), nullptr, options);
|
inspector->Start(platform_.get(), nullptr, options);
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ class AtomCopyFrameGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GenerateCopyFrame(const gfx::Rect& damage_rect) {
|
void GenerateCopyFrame(const gfx::Rect& damage_rect) {
|
||||||
if (!view_->render_widget_host())
|
if (!view_->render_widget_host() || !view_->IsPainting())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::unique_ptr<cc::CopyOutputRequest> request =
|
std::unique_ptr<cc::CopyOutputRequest> request =
|
||||||
@@ -255,6 +255,8 @@ class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient {
|
|||||||
|
|
||||||
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||||
bool transparent,
|
bool transparent,
|
||||||
|
bool painting,
|
||||||
|
int frame_rate,
|
||||||
const OnPaintCallback& callback,
|
const OnPaintCallback& callback,
|
||||||
content::RenderWidgetHost* host,
|
content::RenderWidgetHost* host,
|
||||||
OffScreenRenderWidgetHostView* parent_host_view,
|
OffScreenRenderWidgetHostView* parent_host_view,
|
||||||
@@ -268,17 +270,18 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
|||||||
transparent_(transparent),
|
transparent_(transparent),
|
||||||
callback_(callback),
|
callback_(callback),
|
||||||
parent_callback_(nullptr),
|
parent_callback_(nullptr),
|
||||||
frame_rate_(60),
|
frame_rate_(frame_rate),
|
||||||
frame_rate_threshold_us_(0),
|
frame_rate_threshold_us_(0),
|
||||||
last_time_(base::Time::Now()),
|
last_time_(base::Time::Now()),
|
||||||
scale_factor_(kDefaultScaleFactor),
|
scale_factor_(kDefaultScaleFactor),
|
||||||
size_(native_window->GetSize()),
|
size_(native_window->GetSize()),
|
||||||
painting_(true),
|
painting_(painting),
|
||||||
is_showing_(!render_widget_host_->is_hidden()),
|
is_showing_(!render_widget_host_->is_hidden()),
|
||||||
is_destroyed_(false),
|
is_destroyed_(false),
|
||||||
popup_position_(gfx::Rect()),
|
popup_position_(gfx::Rect()),
|
||||||
hold_resize_(false),
|
hold_resize_(false),
|
||||||
pending_resize_(false),
|
pending_resize_(false),
|
||||||
|
paint_callback_running_(false),
|
||||||
renderer_compositor_frame_sink_(nullptr),
|
renderer_compositor_frame_sink_(nullptr),
|
||||||
background_color_(SkColor()),
|
background_color_(SkColor()),
|
||||||
weak_ptr_factory_(this) {
|
weak_ptr_factory_(this) {
|
||||||
@@ -303,7 +306,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
|||||||
new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
|
new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
|
||||||
content::GetContextFactory(), context_factory_private,
|
content::GetContextFactory(), context_factory_private,
|
||||||
base::ThreadTaskRunnerHandle::Get()));
|
base::ThreadTaskRunnerHandle::Get()));
|
||||||
compositor_->SetAcceleratedWidget(native_window_->GetAcceleratedWidget());
|
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
|
||||||
compositor_->SetRootLayer(root_layer_.get());
|
compositor_->SetRootLayer(root_layer_.get());
|
||||||
#endif
|
#endif
|
||||||
GetCompositor()->SetDelegate(this);
|
GetCompositor()->SetDelegate(this);
|
||||||
@@ -738,6 +741,8 @@ content::RenderWidgetHostViewBase*
|
|||||||
|
|
||||||
return new OffScreenRenderWidgetHostView(
|
return new OffScreenRenderWidgetHostView(
|
||||||
transparent_,
|
transparent_,
|
||||||
|
true,
|
||||||
|
embedder_host_view->GetFrameRate(),
|
||||||
callback_,
|
callback_,
|
||||||
render_widget_host,
|
render_widget_host,
|
||||||
embedder_host_view,
|
embedder_host_view,
|
||||||
@@ -930,7 +935,7 @@ bool OffScreenRenderWidgetHostView::IsAutoResizeEnabled() const {
|
|||||||
|
|
||||||
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
|
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
|
||||||
bool needs_begin_frames) {
|
bool needs_begin_frames) {
|
||||||
SetupFrameRate(false);
|
SetupFrameRate(true);
|
||||||
|
|
||||||
begin_frame_timer_->SetActive(needs_begin_frames);
|
begin_frame_timer_->SetActive(needs_begin_frames);
|
||||||
|
|
||||||
@@ -1004,7 +1009,9 @@ void OffScreenRenderWidgetHostView::OnPaint(
|
|||||||
}
|
}
|
||||||
|
|
||||||
damage.Intersect(GetViewBounds());
|
damage.Intersect(GetViewBounds());
|
||||||
|
paint_callback_running_ = true;
|
||||||
callback_.Run(damage, bitmap);
|
callback_.Run(damage, bitmap);
|
||||||
|
paint_callback_running_ = false;
|
||||||
|
|
||||||
for (size_t i = 0; i < damages.size(); i++) {
|
for (size_t i = 0; i < damages.size(); i++) {
|
||||||
CopyBitmapTo(bitmap, originals[i], damages[i]);
|
CopyBitmapTo(bitmap, originals[i], damages[i]);
|
||||||
@@ -1151,7 +1158,7 @@ void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
|
|||||||
painting_ = painting;
|
painting_ = painting;
|
||||||
|
|
||||||
if (software_output_device_) {
|
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 {
|
} else {
|
||||||
if (frame_rate <= 0)
|
if (frame_rate <= 0)
|
||||||
frame_rate = 1;
|
frame_rate = 1;
|
||||||
if (frame_rate > 60)
|
if (frame_rate > 240)
|
||||||
frame_rate = 60;
|
frame_rate = 240;
|
||||||
|
|
||||||
frame_rate_ = frame_rate;
|
frame_rate_ = frame_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetupFrameRate(true);
|
||||||
|
|
||||||
for (auto guest_host_view : guest_host_views_)
|
for (auto guest_host_view : guest_host_views_)
|
||||||
guest_host_view->SetFrameRate(frame_rate);
|
guest_host_view->SetFrameRate(frame_rate);
|
||||||
|
|
||||||
SetupFrameRate(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int OffScreenRenderWidgetHostView::GetFrameRate() const {
|
int OffScreenRenderWidgetHostView::GetFrameRate() const {
|
||||||
@@ -1205,7 +1212,7 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
|||||||
|
|
||||||
frame_rate_threshold_us_ = 1000000 / frame_rate_;
|
frame_rate_threshold_us_ = 1000000 / frame_rate_;
|
||||||
|
|
||||||
GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval(
|
GetCompositor()->SetAuthoritativeVSyncInterval(
|
||||||
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
|
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
|
||||||
|
|
||||||
if (copy_frame_generator_.get()) {
|
if (copy_frame_generator_.get()) {
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ class OffScreenRenderWidgetHostView
|
|||||||
public OffscreenViewProxyObserver {
|
public OffscreenViewProxyObserver {
|
||||||
public:
|
public:
|
||||||
OffScreenRenderWidgetHostView(bool transparent,
|
OffScreenRenderWidgetHostView(bool transparent,
|
||||||
|
bool painting,
|
||||||
|
int frame_rate,
|
||||||
const OnPaintCallback& callback,
|
const OnPaintCallback& callback,
|
||||||
content::RenderWidgetHost* render_widget_host,
|
content::RenderWidgetHost* render_widget_host,
|
||||||
OffScreenRenderWidgetHostView* parent_host_view,
|
OffScreenRenderWidgetHostView* parent_host_view,
|
||||||
@@ -314,6 +316,8 @@ class OffScreenRenderWidgetHostView
|
|||||||
bool hold_resize_;
|
bool hold_resize_;
|
||||||
bool pending_resize_;
|
bool pending_resize_;
|
||||||
|
|
||||||
|
bool paint_callback_running_;
|
||||||
|
|
||||||
std::unique_ptr<ui::Layer> root_layer_;
|
std::unique_ptr<ui::Layer> root_layer_;
|
||||||
std::unique_ptr<ui::Compositor> compositor_;
|
std::unique_ptr<ui::Compositor> compositor_;
|
||||||
std::unique_ptr<content::DelegatedFrameHost> delegated_frame_host_;
|
std::unique_ptr<content::DelegatedFrameHost> delegated_frame_host_;
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ namespace atom {
|
|||||||
OffScreenWebContentsView::OffScreenWebContentsView(
|
OffScreenWebContentsView::OffScreenWebContentsView(
|
||||||
bool transparent, const OnPaintCallback& callback)
|
bool transparent, const OnPaintCallback& callback)
|
||||||
: transparent_(transparent),
|
: transparent_(transparent),
|
||||||
|
painting_(true),
|
||||||
|
frame_rate_(60),
|
||||||
callback_(callback),
|
callback_(callback),
|
||||||
web_contents_(nullptr) {
|
web_contents_(nullptr) {
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
@@ -103,6 +105,8 @@ content::RenderWidgetHostViewBase*
|
|||||||
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
|
auto relay = NativeWindowRelay::FromWebContents(web_contents_);
|
||||||
return new OffScreenRenderWidgetHostView(
|
return new OffScreenRenderWidgetHostView(
|
||||||
transparent_,
|
transparent_,
|
||||||
|
painting_,
|
||||||
|
GetFrameRate(),
|
||||||
callback_,
|
callback_,
|
||||||
render_widget_host,
|
render_widget_host,
|
||||||
nullptr,
|
nullptr,
|
||||||
@@ -125,6 +129,8 @@ content::RenderWidgetHostViewBase*
|
|||||||
|
|
||||||
return new OffScreenRenderWidgetHostView(
|
return new OffScreenRenderWidgetHostView(
|
||||||
transparent_,
|
transparent_,
|
||||||
|
true,
|
||||||
|
view->GetFrameRate(),
|
||||||
callback_,
|
callback_,
|
||||||
render_widget_host,
|
render_widget_host,
|
||||||
view,
|
view,
|
||||||
@@ -202,6 +208,42 @@ void OffScreenWebContentsView::UpdateDragCursor(
|
|||||||
blink::WebDragOperation operation) {
|
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 {
|
OffScreenRenderWidgetHostView* OffScreenWebContentsView::GetView() const {
|
||||||
if (web_contents_) {
|
if (web_contents_) {
|
||||||
return static_cast<OffScreenRenderWidgetHostView*>(
|
return static_cast<OffScreenRenderWidgetHostView*>(
|
||||||
|
|||||||
@@ -69,6 +69,11 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
|||||||
content::RenderWidgetHostImpl* source_rwh) override;
|
content::RenderWidgetHostImpl* source_rwh) override;
|
||||||
void UpdateDragCursor(blink::WebDragOperation operation) override;
|
void UpdateDragCursor(blink::WebDragOperation operation) override;
|
||||||
|
|
||||||
|
void SetPainting(bool painting);
|
||||||
|
bool IsPainting() const;
|
||||||
|
void SetFrameRate(int frame_rate);
|
||||||
|
int GetFrameRate() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
void PlatformCreate();
|
void PlatformCreate();
|
||||||
@@ -78,6 +83,8 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
|||||||
OffScreenRenderWidgetHostView* GetView() const;
|
OffScreenRenderWidgetHostView* GetView() const;
|
||||||
|
|
||||||
const bool transparent_;
|
const bool transparent_;
|
||||||
|
bool painting_;
|
||||||
|
int frame_rate_;
|
||||||
OnPaintCallback callback_;
|
OnPaintCallback callback_;
|
||||||
|
|
||||||
// Weak refs.
|
// Weak refs.
|
||||||
|
|||||||
@@ -140,11 +140,7 @@ bool RelaunchAppWithHelper(const base::FilePath& helper,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int RelauncherMain(const content::MainFunctionParams& main_parameters) {
|
int RelauncherMain(const content::MainFunctionParams& main_parameters) {
|
||||||
#if defined(OS_WIN)
|
|
||||||
const StringVector& argv = atom::AtomCommandLine::wargv();
|
|
||||||
#else
|
|
||||||
const StringVector& argv = atom::AtomCommandLine::argv();
|
const StringVector& argv = atom::AtomCommandLine::argv();
|
||||||
#endif
|
|
||||||
|
|
||||||
if (argv.size() < 4 || argv[1] != internal::kRelauncherTypeArg) {
|
if (argv.size() < 4 || argv[1] != internal::kRelauncherTypeArg) {
|
||||||
LOG(ERROR) << "relauncher process invoked with unexpected arguments";
|
LOG(ERROR) << "relauncher process invoked with unexpected arguments";
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>electron.icns</string>
|
<string>electron.icns</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.8.2</string>
|
<string>1.8.8</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.8.2</string>
|
<string>1.8.8</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.developer-tools</string>
|
<string>public.app-category.developer-tools</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ END
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,8,2,2
|
FILEVERSION 1,8,8,0
|
||||||
PRODUCTVERSION 1,8,2,2
|
PRODUCTVERSION 1,8,8,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@@ -74,12 +74,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "GitHub, Inc."
|
VALUE "CompanyName", "GitHub, Inc."
|
||||||
VALUE "FileDescription", "Electron"
|
VALUE "FileDescription", "Electron"
|
||||||
VALUE "FileVersion", "1.8.2"
|
VALUE "FileVersion", "1.8.8"
|
||||||
VALUE "InternalName", "electron.exe"
|
VALUE "InternalName", "electron.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||||
VALUE "OriginalFilename", "electron.exe"
|
VALUE "OriginalFilename", "electron.exe"
|
||||||
VALUE "ProductName", "Electron"
|
VALUE "ProductName", "Electron"
|
||||||
VALUE "ProductVersion", "1.8.2"
|
VALUE "ProductVersion", "1.8.8"
|
||||||
VALUE "SquirrelAwareVersion", "1"
|
VALUE "SquirrelAwareVersion", "1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|||||||
@@ -154,6 +154,18 @@ bool ShowOpenDialog(const DialogSettings& settings,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenDialogCompletion(int chosen, NSOpenPanel* dialog,
|
||||||
|
const DialogSettings& settings,
|
||||||
|
const OpenDialogCallback& callback) {
|
||||||
|
if (chosen == NSFileHandlingPanelCancelButton) {
|
||||||
|
callback.Run(false, std::vector<base::FilePath>());
|
||||||
|
} else {
|
||||||
|
std::vector<base::FilePath> paths;
|
||||||
|
ReadDialogPaths(dialog, &paths);
|
||||||
|
callback.Run(true, paths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShowOpenDialog(const DialogSettings& settings,
|
void ShowOpenDialog(const DialogSettings& settings,
|
||||||
const OpenDialogCallback& c) {
|
const OpenDialogCallback& c) {
|
||||||
NSOpenPanel* dialog = [NSOpenPanel openPanel];
|
NSOpenPanel* dialog = [NSOpenPanel openPanel];
|
||||||
@@ -167,25 +179,14 @@ void ShowOpenDialog(const DialogSettings& settings,
|
|||||||
|
|
||||||
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
|
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
|
||||||
settings.force_detached) {
|
settings.force_detached) {
|
||||||
int chosen = [dialog runModal];
|
[dialog beginWithCompletionHandler:^(NSInteger chosen) {
|
||||||
if (chosen == NSFileHandlingPanelCancelButton) {
|
OpenDialogCompletion(chosen, dialog, settings, callback);
|
||||||
callback.Run(false, std::vector<base::FilePath>());
|
}];
|
||||||
} else {
|
|
||||||
std::vector<base::FilePath> paths;
|
|
||||||
ReadDialogPaths(dialog, &paths);
|
|
||||||
callback.Run(true, paths);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
NSWindow* window = settings.parent_window->GetNativeWindow();
|
NSWindow* window = settings.parent_window->GetNativeWindow();
|
||||||
[dialog beginSheetModalForWindow:window
|
[dialog beginSheetModalForWindow:window
|
||||||
completionHandler:^(NSInteger chosen) {
|
completionHandler:^(NSInteger chosen) {
|
||||||
if (chosen == NSFileHandlingPanelCancelButton) {
|
OpenDialogCompletion(chosen, dialog, settings, callback);
|
||||||
callback.Run(false, std::vector<base::FilePath>());
|
|
||||||
} else {
|
|
||||||
std::vector<base::FilePath> paths;
|
|
||||||
ReadDialogPaths(dialog, &paths);
|
|
||||||
callback.Run(true, paths);
|
|
||||||
}
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,6 +206,17 @@ bool ShowSaveDialog(const DialogSettings& settings,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SaveDialogCompletion(int chosen, NSSavePanel* dialog,
|
||||||
|
const DialogSettings& settings,
|
||||||
|
const SaveDialogCallback& callback) {
|
||||||
|
if (chosen == NSFileHandlingPanelCancelButton) {
|
||||||
|
callback.Run(false, base::FilePath());
|
||||||
|
} else {
|
||||||
|
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
|
||||||
|
callback.Run(true, base::FilePath(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShowSaveDialog(const DialogSettings& settings,
|
void ShowSaveDialog(const DialogSettings& settings,
|
||||||
const SaveDialogCallback& c) {
|
const SaveDialogCallback& c) {
|
||||||
NSSavePanel* dialog = [NSSavePanel savePanel];
|
NSSavePanel* dialog = [NSSavePanel savePanel];
|
||||||
@@ -216,23 +228,14 @@ void ShowSaveDialog(const DialogSettings& settings,
|
|||||||
|
|
||||||
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
|
if (!settings.parent_window || !settings.parent_window->GetNativeWindow() ||
|
||||||
settings.force_detached) {
|
settings.force_detached) {
|
||||||
int chosen = [dialog runModal];
|
[dialog beginWithCompletionHandler:^(NSInteger chosen) {
|
||||||
if (chosen == NSFileHandlingPanelCancelButton) {
|
SaveDialogCompletion(chosen, dialog, settings, callback);
|
||||||
callback.Run(false, base::FilePath());
|
}];
|
||||||
} else {
|
|
||||||
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
|
|
||||||
callback.Run(true, base::FilePath(path));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
NSWindow* window = settings.parent_window->GetNativeWindow();
|
NSWindow* window = settings.parent_window->GetNativeWindow();
|
||||||
[dialog beginSheetModalForWindow:window
|
[dialog beginSheetModalForWindow:window
|
||||||
completionHandler:^(NSInteger chosen) {
|
completionHandler:^(NSInteger chosen) {
|
||||||
if (chosen == NSFileHandlingPanelCancelButton) {
|
SaveDialogCompletion(chosen, dialog, settings, callback);
|
||||||
callback.Run(false, base::FilePath());
|
|
||||||
} else {
|
|
||||||
std::string path = base::SysNSStringToUTF8([[dialog URL] path]);
|
|
||||||
callback.Run(true, base::FilePath(path));
|
|
||||||
}
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ void ShowMessageBox(NativeWindow* parent_window,
|
|||||||
if (!parent_window || !parent_window->GetNativeWindow() ||
|
if (!parent_window || !parent_window->GetNativeWindow() ||
|
||||||
parent_window->is_offscreen_dummy()) {
|
parent_window->is_offscreen_dummy()) {
|
||||||
int ret = [[alert autorelease] runModal];
|
int ret = [[alert autorelease] runModal];
|
||||||
callback.Run(ret, false);
|
callback.Run(ret, alert.suppressionButton.state == NSOnState);
|
||||||
} else {
|
} else {
|
||||||
ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback
|
ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback
|
||||||
andAlert:alert
|
andAlert:alert
|
||||||
|
|||||||
@@ -3,12 +3,16 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include "atom/browser/ui/win/atom_desktop_native_widget_aura.h"
|
#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 {
|
namespace atom {
|
||||||
|
|
||||||
AtomDesktopNativeWidgetAura::AtomDesktopNativeWidgetAura(
|
AtomDesktopNativeWidgetAura::AtomDesktopNativeWidgetAura(
|
||||||
views::internal::NativeWidgetDelegate* delegate)
|
views::internal::NativeWidgetDelegate* delegate)
|
||||||
: views::DesktopNativeWidgetAura(delegate) {
|
: views::DesktopNativeWidgetAura(delegate) {
|
||||||
|
// This is to enable the override of OnWindowActivated
|
||||||
|
aura::client::SetActivationChangeObserver(GetNativeWindow(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomDesktopNativeWidgetAura::Activate() {
|
void AtomDesktopNativeWidgetAura::Activate() {
|
||||||
@@ -19,4 +23,23 @@ void AtomDesktopNativeWidgetAura::Activate() {
|
|||||||
views::DesktopNativeWidgetAura::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
|
} // namespace atom
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ class AtomDesktopNativeWidgetAura : public views::DesktopNativeWidgetAura {
|
|||||||
void Activate() override;
|
void Activate() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void OnWindowActivated(
|
||||||
|
aura::client::ActivationChangeObserver::ActivationReason reason,
|
||||||
|
aura::Window* gained_active,
|
||||||
|
aura::Window* lost_active) override;
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomDesktopNativeWidgetAura);
|
DISALLOW_COPY_AND_ASSIGN(AtomDesktopNativeWidgetAura);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,35 @@ WebContentsPreferences::WebContentsPreferences(
|
|||||||
web_contents->SetUserData(UserDataKey(), this);
|
web_contents->SetUserData(UserDataKey(), this);
|
||||||
|
|
||||||
instances_.push_back(this);
|
instances_.push_back(this);
|
||||||
|
|
||||||
|
// Set WebPreferences defaults onto the JS object
|
||||||
|
SetDefaultBoolIfUndefined("plugins", false);
|
||||||
|
SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false);
|
||||||
|
SetDefaultBoolIfUndefined(options::kExperimentalCanvasFeatures, false);
|
||||||
|
bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true);
|
||||||
|
SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false);
|
||||||
|
SetDefaultBoolIfUndefined(options::kWebviewTag, node);
|
||||||
|
SetDefaultBoolIfUndefined("sandbox", false);
|
||||||
|
SetDefaultBoolIfUndefined("nativeWindowOpen", false);
|
||||||
|
SetDefaultBoolIfUndefined(options::kContextIsolation, false);
|
||||||
|
SetDefaultBoolIfUndefined("javascript", true);
|
||||||
|
SetDefaultBoolIfUndefined("images", true);
|
||||||
|
SetDefaultBoolIfUndefined("textAreasAreResizable", true);
|
||||||
|
SetDefaultBoolIfUndefined("webgl", true);
|
||||||
|
bool webSecurity = true;
|
||||||
|
SetDefaultBoolIfUndefined("webSecurity", webSecurity);
|
||||||
|
// If webSecurity was explicity set to false, let's inherit that into
|
||||||
|
// insecureContent
|
||||||
|
if (web_preferences.Get("webSecurity", &webSecurity) && !webSecurity) {
|
||||||
|
SetDefaultBoolIfUndefined("allowRunningInsecureContent", true);
|
||||||
|
} else {
|
||||||
|
SetDefaultBoolIfUndefined("allowRunningInsecureContent", false);
|
||||||
|
}
|
||||||
|
#if defined(OS_MACOSX)
|
||||||
|
SetDefaultBoolIfUndefined(options::kScrollBounce, false);
|
||||||
|
#endif
|
||||||
|
SetDefaultBoolIfUndefined("offscreen", false);
|
||||||
|
last_web_preferences_.MergeDictionary(&web_preferences_);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebContentsPreferences::~WebContentsPreferences() {
|
WebContentsPreferences::~WebContentsPreferences() {
|
||||||
@@ -55,6 +84,16 @@ WebContentsPreferences::~WebContentsPreferences() {
|
|||||||
instances_.end());
|
instances_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WebContentsPreferences::SetDefaultBoolIfUndefined(const std::string key,
|
||||||
|
bool val) {
|
||||||
|
bool existing;
|
||||||
|
if (!web_preferences_.GetBoolean(key, &existing)) {
|
||||||
|
web_preferences_.SetBoolean(key, val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
|
void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
|
||||||
web_preferences_.MergeDictionary(&extend);
|
web_preferences_.MergeDictionary(&extend);
|
||||||
}
|
}
|
||||||
@@ -79,6 +118,12 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
|
|||||||
|
|
||||||
base::DictionaryValue& web_preferences = self->web_preferences_;
|
base::DictionaryValue& web_preferences = self->web_preferences_;
|
||||||
|
|
||||||
|
// We are appending args to a webContents so let's save the current state
|
||||||
|
// of our preferences object so that during the lifetime of the WebContents
|
||||||
|
// we can fetch the options used to initally configure the WebContents
|
||||||
|
self->last_web_preferences_.Clear();
|
||||||
|
self->last_web_preferences_.MergeDictionary(&web_preferences);
|
||||||
|
|
||||||
bool b;
|
bool b;
|
||||||
// Check if plugins are enabled.
|
// Check if plugins are enabled.
|
||||||
if (web_preferences.GetBoolean("plugins", &b) && b)
|
if (web_preferences.GetBoolean("plugins", &b) && b)
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ class WebContentsPreferences
|
|||||||
|
|
||||||
// Returns the web preferences.
|
// Returns the web preferences.
|
||||||
base::DictionaryValue* web_preferences() { return &web_preferences_; }
|
base::DictionaryValue* web_preferences() { return &web_preferences_; }
|
||||||
|
base::DictionaryValue* last_web_preferences() {
|
||||||
|
return &last_web_preferences_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class content::WebContentsUserData<WebContentsPreferences>;
|
friend class content::WebContentsUserData<WebContentsPreferences>;
|
||||||
@@ -65,6 +68,10 @@ class WebContentsPreferences
|
|||||||
|
|
||||||
content::WebContents* web_contents_;
|
content::WebContents* web_contents_;
|
||||||
base::DictionaryValue web_preferences_;
|
base::DictionaryValue web_preferences_;
|
||||||
|
base::DictionaryValue last_web_preferences_;
|
||||||
|
|
||||||
|
// Set preference value to given bool if user did not provide value
|
||||||
|
bool SetDefaultBoolIfUndefined(const std::string key, bool val);
|
||||||
|
|
||||||
// Get preferences value as integer possibly coercing it from a string
|
// Get preferences value as integer possibly coercing it from a string
|
||||||
bool GetInteger(const std::string& attributeName, int* intValue);
|
bool GetInteger(const std::string& attributeName, int* intValue);
|
||||||
|
|||||||
@@ -156,10 +156,10 @@ file_dialog::Filters GetFileTypesFromAcceptType(
|
|||||||
|
|
||||||
filters.push_back(file_dialog::Filter());
|
filters.push_back(file_dialog::Filter());
|
||||||
|
|
||||||
if (valid_type_count > 1 ||
|
if (valid_type_count > 1 || (valid_type_count == 1 && description.empty()))
|
||||||
(valid_type_count == 1 && description.empty() && extensions.size() > 1))
|
|
||||||
description = "Custom Files";
|
description = "Custom Files";
|
||||||
|
|
||||||
|
DCHECK(!description.empty());
|
||||||
filters[0].first = description;
|
filters[0].first = description;
|
||||||
|
|
||||||
for (const auto& extension : extensions) {
|
for (const auto& extension : extensions) {
|
||||||
@@ -215,6 +215,7 @@ void WebDialogHelper::RunFileChooser(
|
|||||||
flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS;
|
flags |= file_dialog::FILE_DIALOG_MULTI_SELECTIONS;
|
||||||
case content::FileChooserParams::Open:
|
case content::FileChooserParams::Open:
|
||||||
flags |= file_dialog::FILE_DIALOG_OPEN_FILE;
|
flags |= file_dialog::FILE_DIALOG_OPEN_FILE;
|
||||||
|
flags |= file_dialog::FILE_DIALOG_TREAT_PACKAGE_APP_AS_DIRECTORY;
|
||||||
break;
|
break;
|
||||||
case content::FileChooserParams::UploadFolder:
|
case content::FileChooserParams::UploadFolder:
|
||||||
flags |= file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
|
flags |= file_dialog::FILE_DIALOG_OPEN_DIRECTORY;
|
||||||
|
|||||||
@@ -10,31 +10,22 @@
|
|||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
std::vector<std::string> AtomCommandLine::argv_;
|
base::CommandLine::StringVector AtomCommandLine::argv_;
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
// static
|
|
||||||
std::vector<std::wstring> AtomCommandLine::wargv_;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// static
|
// 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"
|
// Hack around with the argv pointer. Used for process.title = "blah"
|
||||||
char** new_argv = uv_setup_args(argc, const_cast<char**>(argv));
|
argv = uv_setup_args(argc, 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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
argv_.assign(argv, argv + argc);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
// static
|
// static
|
||||||
void AtomCommandLine::InitializeFromCommandLine() {
|
void AtomCommandLine::InitializeFromCommandLine() {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/command_line.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
|
|
||||||
@@ -16,13 +17,9 @@ namespace atom {
|
|||||||
// Singleton to remember the original "argc" and "argv".
|
// Singleton to remember the original "argc" and "argv".
|
||||||
class AtomCommandLine {
|
class AtomCommandLine {
|
||||||
public:
|
public:
|
||||||
static void Init(int argc, const char* const* argv);
|
static const base::CommandLine::StringVector& argv() { return argv_; }
|
||||||
static std::vector<std::string> argv() { return argv_; }
|
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
static void Init(int argc, base::CommandLine::CharType** argv);
|
||||||
static void InitW(int argc, const wchar_t* const* argv);
|
|
||||||
static std::vector<std::wstring> wargv() { return wargv_; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
// On Linux the command line has to be read from base::CommandLine since
|
// On Linux the command line has to be read from base::CommandLine since
|
||||||
@@ -31,11 +28,7 @@ class AtomCommandLine {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::vector<std::string> argv_;
|
static base::CommandLine::StringVector argv_;
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
static std::vector<std::wstring> wargv_;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AtomCommandLine);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(AtomCommandLine);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,22 +7,24 @@
|
|||||||
|
|
||||||
#define ATOM_MAJOR_VERSION 1
|
#define ATOM_MAJOR_VERSION 1
|
||||||
#define ATOM_MINOR_VERSION 8
|
#define ATOM_MINOR_VERSION 8
|
||||||
#define ATOM_PATCH_VERSION 2
|
#define ATOM_PATCH_VERSION 8
|
||||||
#define ATOM_PRE_RELEASE_VERSION -beta.2
|
// #define ATOM_PRE_RELEASE_VERSION
|
||||||
|
|
||||||
#ifndef ATOM_PRE_RELEASE_VERSION
|
|
||||||
# define ATOM_PRE_RELEASE_VERSION ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ATOM_STRINGIFY
|
#ifndef ATOM_STRINGIFY
|
||||||
#define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n)
|
#define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n)
|
||||||
#define ATOM_STRINGIFY_HELPER(n) #n
|
#define ATOM_STRINGIFY_HELPER(n) #n
|
||||||
#endif
|
#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_MINOR_VERSION) "." \
|
||||||
ATOM_STRINGIFY(ATOM_PATCH_VERSION) \
|
ATOM_STRINGIFY(ATOM_PATCH_VERSION) \
|
||||||
ATOM_STRINGIFY(ATOM_PRE_RELEASE_VERSION)
|
ATOM_STRINGIFY(ATOM_PRE_RELEASE_VERSION)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ATOM_VERSION "v" ATOM_VERSION_STRING
|
#define ATOM_VERSION "v" ATOM_VERSION_STRING
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,10 @@ void CrashReporterWin::SetUploadParameters() {
|
|||||||
int CrashReporterWin::CrashForException(EXCEPTION_POINTERS* info) {
|
int CrashReporterWin::CrashForException(EXCEPTION_POINTERS* info) {
|
||||||
if (breakpad_) {
|
if (breakpad_) {
|
||||||
breakpad_->WriteMinidumpForException(info);
|
breakpad_->WriteMinidumpForException(info);
|
||||||
TerminateProcessWithoutDump();
|
if (skip_system_crash_handler_)
|
||||||
|
TerminateProcessWithoutDump();
|
||||||
|
else
|
||||||
|
RaiseFailFastException(info->ExceptionRecord, info->ContextRecord, 0);
|
||||||
}
|
}
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
@@ -229,7 +232,7 @@ bool CrashReporterWin::MinidumpCallback(const wchar_t* dump_path,
|
|||||||
MDRawAssertionInfo* assertion,
|
MDRawAssertionInfo* assertion,
|
||||||
bool succeeded) {
|
bool succeeded) {
|
||||||
CrashReporterWin* self = static_cast<CrashReporterWin*>(context);
|
CrashReporterWin* self = static_cast<CrashReporterWin*>(context);
|
||||||
if (succeeded && !self->skip_system_crash_handler_)
|
if (succeeded && self->skip_system_crash_handler_)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "atom/common/node_bindings.h"
|
#include "atom/common/node_bindings.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "base/run_loop.h"
|
#include "base/run_loop.h"
|
||||||
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "base/threading/thread_task_runner_handle.h"
|
#include "base/threading/thread_task_runner_handle.h"
|
||||||
#include "base/trace_event/trace_event.h"
|
#include "base/trace_event/trace_event.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
@@ -150,7 +152,14 @@ void NodeBindings::Initialize() {
|
|||||||
|
|
||||||
node::Environment* NodeBindings::CreateEnvironment(
|
node::Environment* NodeBindings::CreateEnvironment(
|
||||||
v8::Handle<v8::Context> context) {
|
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();
|
auto args = AtomCommandLine::argv();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Feed node the path to initialization script.
|
// Feed node the path to initialization script.
|
||||||
base::FilePath::StringType process_type;
|
base::FilePath::StringType process_type;
|
||||||
@@ -170,8 +179,7 @@ node::Environment* NodeBindings::CreateEnvironment(
|
|||||||
resources_path.Append(FILE_PATH_LITERAL("electron.asar"))
|
resources_path.Append(FILE_PATH_LITERAL("electron.asar"))
|
||||||
.Append(process_type)
|
.Append(process_type)
|
||||||
.Append(FILE_PATH_LITERAL("init.js"));
|
.Append(FILE_PATH_LITERAL("init.js"));
|
||||||
std::string script_path_str = script_path.AsUTF8Unsafe();
|
args.insert(args.begin() + 1, script_path.AsUTF8Unsafe());
|
||||||
args.insert(args.begin() + 1, script_path_str.c_str());
|
|
||||||
|
|
||||||
std::unique_ptr<const char*[]> c_argv = StringVectorToArgArray(args);
|
std::unique_ptr<const char*[]> c_argv = StringVectorToArgArray(args);
|
||||||
node::Environment* env = node::CreateEnvironment(
|
node::Environment* env = node::CreateEnvironment(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "atom/renderer/api/atom_api_spell_check_client.h"
|
#include "atom/renderer/api/atom_api_spell_check_client.h"
|
||||||
#include "base/memory/memory_pressure_listener.h"
|
#include "base/memory/memory_pressure_listener.h"
|
||||||
#include "content/public/renderer/render_frame.h"
|
#include "content/public/renderer/render_frame.h"
|
||||||
|
#include "content/public/renderer/render_frame_visitor.h"
|
||||||
#include "content/public/renderer/render_view.h"
|
#include "content/public/renderer/render_view.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
@@ -58,6 +59,30 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback {
|
|||||||
DISALLOW_COPY_AND_ASSIGN(ScriptExecutionCallback);
|
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
|
} // namespace
|
||||||
|
|
||||||
WebFrame::WebFrame(v8::Isolate* isolate)
|
WebFrame::WebFrame(v8::Isolate* isolate)
|
||||||
@@ -101,6 +126,7 @@ double WebFrame::GetZoomFactor() const {
|
|||||||
|
|
||||||
void WebFrame::SetVisualZoomLevelLimits(double min_level, double max_level) {
|
void WebFrame::SetVisualZoomLevelLimits(double min_level, double max_level) {
|
||||||
web_frame_->View()->SetDefaultPageScaleLimits(min_level, max_level);
|
web_frame_->View()->SetDefaultPageScaleLimits(min_level, max_level);
|
||||||
|
web_frame_->View()->SetIgnoreViewportTagScaleLimits(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) {
|
void WebFrame::SetLayoutZoomLevelLimits(double min_level, double max_level) {
|
||||||
@@ -139,10 +165,15 @@ void WebFrame::SetSpellCheckProvider(mate::Arguments* args,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spell_check_client_.reset(new SpellCheckClient(
|
std::unique_ptr<SpellCheckClient> client(new SpellCheckClient(
|
||||||
language, auto_spell_correct_turned_on, args->isolate(), provider));
|
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_->View()->SetSpellCheckClient(spell_check_client_.get());
|
||||||
web_frame_->SetTextCheckClient(spell_check_client_.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) {
|
void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) {
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ namespace {
|
|||||||
const std::string kIpcKey = "ipcNative";
|
const std::string kIpcKey = "ipcNative";
|
||||||
const std::string kModuleCacheKey = "native-module-cache";
|
const std::string kModuleCacheKey = "native-module-cache";
|
||||||
|
|
||||||
|
|
||||||
v8::Local<v8::Object> GetModuleCache(v8::Isolate* isolate) {
|
v8::Local<v8::Object> GetModuleCache(v8::Isolate* isolate) {
|
||||||
mate::Dictionary global(isolate, isolate->GetCurrentContext()->Global());
|
mate::Dictionary global(isolate, isolate->GetCurrentContext()->Global());
|
||||||
v8::Local<v8::Value> cache;
|
v8::Local<v8::Value> cache;
|
||||||
@@ -158,8 +157,6 @@ void AtomSandboxedRendererClient::DidCreateScriptContext(
|
|||||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
std::string preload_script = command_line->GetSwitchValueASCII(
|
std::string preload_script = command_line->GetSwitchValueASCII(
|
||||||
switches::kPreloadScript);
|
switches::kPreloadScript);
|
||||||
if (preload_script.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto isolate = context->GetIsolate();
|
auto isolate = context->GetIsolate();
|
||||||
v8::HandleScope handle_scope(isolate);
|
v8::HandleScope handle_scope(isolate);
|
||||||
|
|||||||
@@ -228,10 +228,8 @@
|
|||||||
'msvs_settings': {
|
'msvs_settings': {
|
||||||
'VCCLCompilerTool': {
|
'VCCLCompilerTool': {
|
||||||
'RuntimeLibrary': '2', # /MD (nondebug DLL)
|
'RuntimeLibrary': '2', # /MD (nondebug DLL)
|
||||||
# 1, optimizeMinSpace, Minimize Size (/O1)
|
'Optimization': '2', # /O2
|
||||||
'Optimization': '1',
|
'WholeProgramOptimization': 'true', # /GL
|
||||||
# 2, favorSize - Favor small code (/Os)
|
|
||||||
'FavorSizeOrSpeed': '2',
|
|
||||||
# See http://msdn.microsoft.com/en-us/library/47238hez(VS.71).aspx
|
# See http://msdn.microsoft.com/en-us/library/47238hez(VS.71).aspx
|
||||||
'InlineFunctionExpansion': '2', # 2 = max
|
'InlineFunctionExpansion': '2', # 2 = max
|
||||||
# See http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx
|
# See http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx
|
||||||
@@ -241,11 +239,24 @@
|
|||||||
# perform FPO regardless, so we must explicitly disable.
|
# perform FPO regardless, so we must explicitly disable.
|
||||||
# We still want the false setting above to avoid having
|
# We still want the false setting above to avoid having
|
||||||
# "/Oy /Oy-" and warnings about overriding.
|
# "/Oy /Oy-" and warnings about overriding.
|
||||||
'AdditionalOptions': ['/Oy-'],
|
'AdditionalOptions': ['/Oy-', '/d2guard4'],
|
||||||
|
},
|
||||||
|
'VCLibrarianTool': {
|
||||||
|
'LinkTimeCodeGeneration': 'true', # /LTCG
|
||||||
},
|
},
|
||||||
'VCLinkerTool': {
|
'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.
|
# Turn off incremental linking to save binary size.
|
||||||
'LinkIncremental': '1', # /INCREMENTAL:NO
|
'LinkIncremental': '1', # /INCREMENTAL:NO
|
||||||
|
'LinkTimeCodeGeneration': '1', # /LTCG
|
||||||
|
'OptimizeReferences': 2, # /OPT:REF
|
||||||
|
'EnableCOMDATFolding': 2, # /OPT:ICF
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'conditions': [
|
'conditions': [
|
||||||
@@ -270,6 +281,18 @@
|
|||||||
'-Wl,--gc-sections',
|
'-Wl,--gc-sections',
|
||||||
],
|
],
|
||||||
}], # OS=="linux"
|
}], # OS=="linux"
|
||||||
|
['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
|
}, # Release_Base
|
||||||
'conditions': [
|
'conditions': [
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ void DesktopNotificationController::AnimateAll() {
|
|||||||
if (SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0)) {
|
if (SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0)) {
|
||||||
ScreenMetrics metrics;
|
ScreenMetrics metrics;
|
||||||
POINT origin = { work_area.right,
|
POINT origin = { work_area.right,
|
||||||
work_area.bottom - metrics.Y(toast_margin_<int>) };
|
work_area.bottom - metrics.Y(toast_margin_) };
|
||||||
|
|
||||||
auto hdwp =
|
auto hdwp =
|
||||||
BeginDeferWindowPos(static_cast<int>(instances_.size()));
|
BeginDeferWindowPos(static_cast<int>(instances_.size()));
|
||||||
@@ -231,7 +231,7 @@ void DesktopNotificationController::AnimateAll() {
|
|||||||
// Set new toast positions
|
// Set new toast positions
|
||||||
if (!instances_.empty()) {
|
if (!instances_.empty()) {
|
||||||
ScreenMetrics metrics;
|
ScreenMetrics metrics;
|
||||||
auto margin = metrics.Y(toast_margin_<int>);
|
auto margin = metrics.Y(toast_margin_);
|
||||||
|
|
||||||
int target_pos = 0;
|
int target_pos = 0;
|
||||||
for (auto&& inst : instances_) {
|
for (auto&& inst : instances_) {
|
||||||
@@ -305,7 +305,7 @@ void DesktopNotificationController::CreateToast(NotificationLink&& data) {
|
|||||||
auto toast = Toast::Get(item.hwnd);
|
auto toast = Toast::Get(item.hwnd);
|
||||||
toast_pos = toast->GetVerticalPosition() +
|
toast_pos = toast->GetVerticalPosition() +
|
||||||
toast->GetHeight() +
|
toast->GetHeight() +
|
||||||
scr.Y(toast_margin_<int>);
|
scr.Y(toast_margin_);
|
||||||
}
|
}
|
||||||
|
|
||||||
instances_.push_back({ hwnd, move(data) });
|
instances_.push_back({ hwnd, move(data) });
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ class DesktopNotificationController {
|
|||||||
TimerID_Animate = 1
|
TimerID_Animate = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
static constexpr int toast_margin_ = 20;
|
||||||
static constexpr T toast_margin_ = 20;
|
|
||||||
|
|
||||||
// Wrapper around `NotificationData` which makes sure that
|
// Wrapper around `NotificationData` which makes sure that
|
||||||
// the `controller` member is cleared when the controller object
|
// the `controller` member is cleared when the controller object
|
||||||
|
|||||||
@@ -140,6 +140,12 @@
|
|||||||
'<(libchromiumcontent_src_dir)/v8',
|
'<(libchromiumcontent_src_dir)/v8',
|
||||||
'<(libchromiumcontent_src_dir)/v8/include',
|
'<(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': [
|
'conditions': [
|
||||||
['OS=="mac" and libchromiumcontent_component==0', {
|
['OS=="mac" and libchromiumcontent_component==0', {
|
||||||
# -all_load is the "whole-archive" on macOS.
|
# -all_load is the "whole-archive" on macOS.
|
||||||
|
|||||||
@@ -73,6 +73,16 @@ A `Integer` representing the unique ID of the view.
|
|||||||
|
|
||||||
Objects created with `new BrowserView` have the following instance methods:
|
Objects created with `new BrowserView` have the following instance methods:
|
||||||
|
|
||||||
|
#### `view.destroy()`
|
||||||
|
|
||||||
|
Force closing the view, the `unload` and `beforeunload` events won't be emitted
|
||||||
|
for the web page. After you're done with a view, call this function in order to
|
||||||
|
free memory and other resources as soon as possible.
|
||||||
|
|
||||||
|
#### `view.isDestroyed()`
|
||||||
|
|
||||||
|
Returns `Boolean` - Whether the view is destroyed.
|
||||||
|
|
||||||
#### `view.setAutoResize(options)` _Experimental_
|
#### `view.setAutoResize(options)` _Experimental_
|
||||||
|
|
||||||
* `options` Object
|
* `options` Object
|
||||||
|
|||||||
@@ -1174,7 +1174,7 @@ menu bar.
|
|||||||
|
|
||||||
* `progress` Double
|
* `progress` Double
|
||||||
* `options` Object (optional)
|
* `options` Object (optional)
|
||||||
* `mode` String _Windows_ - Mode for the progress bar. Can be `none`, `normal`, `indeterminate`, `error`, or `paused`.
|
* `mode` String _Windows_ - Mode for the progress bar. Can be `none`, `normal`, `indeterminate`, `error` or `paused`.
|
||||||
|
|
||||||
Sets progress value in progress bar. Valid range is [0, 1.0].
|
Sets progress value in progress bar. Valid range is [0, 1.0].
|
||||||
|
|
||||||
@@ -1191,7 +1191,7 @@ mode set (but with a value within the valid range), `normal` will be assumed.
|
|||||||
|
|
||||||
#### `win.setOverlayIcon(overlay, description)` _Windows_
|
#### `win.setOverlayIcon(overlay, description)` _Windows_
|
||||||
|
|
||||||
* `overlay` [NativeImage](native-image.md) - the icon to display on the bottom
|
* `overlay` [NativeImage](native-image.md) | null - the icon to display on the bottom
|
||||||
right corner of the taskbar icon. If this parameter is `null`, the overlay is
|
right corner of the taskbar icon. If this parameter is `null`, the overlay is
|
||||||
cleared
|
cleared
|
||||||
* `description` String - a description that will be provided to Accessibility
|
* `description` String - a description that will be provided to Accessibility
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ Sets the `image` associated with this tray icon.
|
|||||||
|
|
||||||
#### `tray.setPressedImage(image)` _macOS_
|
#### `tray.setPressedImage(image)` _macOS_
|
||||||
|
|
||||||
* `image` [NativeImage](native-image.md)
|
* `image` ([NativeImage](native-image.md) | String)
|
||||||
|
|
||||||
Sets the `image` associated with this tray icon when pressed on macOS.
|
Sets the `image` associated with this tray icon when pressed on macOS.
|
||||||
|
|
||||||
|
|||||||
@@ -1291,11 +1291,17 @@ Shows pop-up dictionary that searches the selected word on the page.
|
|||||||
Set the size of the page. This is only supported for `<webview>` guest contents.
|
Set the size of the page. This is only supported for `<webview>` guest contents.
|
||||||
|
|
||||||
* `options` Object
|
* `options` Object
|
||||||
* `normal` Object (optional) - Normal size of the page. This can be used in
|
* `enableAutoSize` Boolean (optional) - true to make the webview container automatically
|
||||||
combination with the [`disableguestresize`](web-view-tag.md#disableguestresize)
|
resize within the bounds specified by the attributes normal, min and max.
|
||||||
|
* `normal` [Size](structures/size.md) (optional) - Normal size of the page. This can be used in
|
||||||
|
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
|
||||||
|
attribute to manually resize the webview guest contents.
|
||||||
|
* `min` [Size](structures/size.md) (optional) - Minimum size of the page. This can be used in
|
||||||
|
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
|
||||||
|
attribute to manually resize the webview guest contents.
|
||||||
|
* `max` [Size](structures/size.md) (optional) - Maximium size of the page. This can be used in
|
||||||
|
combination with the [`disableguestresize`](webview-tag.md#disableguestresize)
|
||||||
attribute to manually resize the webview guest contents.
|
attribute to manually resize the webview guest contents.
|
||||||
* `width` Integer
|
|
||||||
* `height` Integer
|
|
||||||
|
|
||||||
#### `contents.isOffscreen()`
|
#### `contents.isOffscreen()`
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ this limitation.
|
|||||||
Returns `Object`:
|
Returns `Object`:
|
||||||
|
|
||||||
* `images` [MemoryUsageDetails](structures/memory-usage-details.md)
|
* `images` [MemoryUsageDetails](structures/memory-usage-details.md)
|
||||||
|
* `scripts` [MemoryUsageDetails](structures/memory-usage-details.md)
|
||||||
* `cssStyleSheets` [MemoryUsageDetails](structures/memory-usage-details.md)
|
* `cssStyleSheets` [MemoryUsageDetails](structures/memory-usage-details.md)
|
||||||
* `xslStyleSheets` [MemoryUsageDetails](structures/memory-usage-details.md)
|
* `xslStyleSheets` [MemoryUsageDetails](structures/memory-usage-details.md)
|
||||||
* `fonts` [MemoryUsageDetails](structures/memory-usage-details.md)
|
* `fonts` [MemoryUsageDetails](structures/memory-usage-details.md)
|
||||||
|
|||||||
@@ -17,15 +17,27 @@ Please note, the `ARM` version of Windows is not supported for now.
|
|||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
The prebuilt `ia32` (`i686`) and `x64` (`amd64`) binaries of Electron are built on
|
The prebuilt binaries of Electron are built for Debian Jessie, but whether the
|
||||||
Ubuntu 12.04, the `arm` binary is built against ARM v7 with hard-float ABI and
|
prebuilt binary can run on a distribution depends on whether the distribution
|
||||||
NEON for Debian Wheezy.
|
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
|
||||||
Whether the prebuilt binary can run on a distribution depends on whether the
|
verified to be able to run the prebuilt binaries of Electron:
|
||||||
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:
|
|
||||||
|
|
||||||
* Ubuntu 12.04 and later
|
* Ubuntu 12.04 and later
|
||||||
* Fedora 21
|
* 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.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
'product_name%': 'Electron',
|
'product_name%': 'Electron',
|
||||||
'company_name%': 'GitHub, Inc',
|
'company_name%': 'GitHub, Inc',
|
||||||
'company_abbr%': 'github',
|
'company_abbr%': 'github',
|
||||||
'version%': '1.8.2-beta.2',
|
'version%': '1.8.8',
|
||||||
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
|
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
|
||||||
},
|
},
|
||||||
'includes': [
|
'includes': [
|
||||||
@@ -217,6 +217,11 @@
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
'link_settings': {
|
||||||
|
'ldflags': [
|
||||||
|
'-Wl,-z,noexecstack',
|
||||||
|
],
|
||||||
|
},
|
||||||
}], # OS=="linux"
|
}], # OS=="linux"
|
||||||
],
|
],
|
||||||
}, # target <(project_name)
|
}, # target <(project_name)
|
||||||
|
|||||||
@@ -98,6 +98,8 @@
|
|||||||
'atom/app/atom_main_delegate.cc',
|
'atom/app/atom_main_delegate.cc',
|
||||||
'atom/app/atom_main_delegate.h',
|
'atom/app/atom_main_delegate.h',
|
||||||
'atom/app/atom_main_delegate_mac.mm',
|
'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.cc',
|
||||||
'atom/app/node_main.h',
|
'atom/app/node_main.h',
|
||||||
'atom/app/uv_task_runner.cc',
|
'atom/app/uv_task_runner.cc',
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ Menu.prototype._init = function () {
|
|||||||
getAcceleratorForCommandId: (id, useDefaultAccelerator) => {
|
getAcceleratorForCommandId: (id, useDefaultAccelerator) => {
|
||||||
const command = this.commandsMap[id]
|
const command = this.commandsMap[id]
|
||||||
if (!command) return
|
if (!command) return
|
||||||
if (command.accelerator) return command.accelerator
|
if (command.accelerator != null) return command.accelerator
|
||||||
if (useDefaultAccelerator) return command.getDefaultRoleAccelerator()
|
if (useDefaultAccelerator) return command.getDefaultRoleAccelerator()
|
||||||
},
|
},
|
||||||
getIconForCommandId: id => this.commandsMap[id] ? this.commandsMap[id].icon : undefined,
|
getIconForCommandId: id => this.commandsMap[id] ? this.commandsMap[id].icon : undefined,
|
||||||
@@ -44,20 +44,23 @@ Menu.prototype._init = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Menu.prototype.popup = function (window, x, y, positioningItem) {
|
Menu.prototype.popup = function (window, x, y, positioningItem) {
|
||||||
let asyncPopup
|
let asyncPopup, opts
|
||||||
let [newX, newY, newPosition, newWindow] = [x, y, positioningItem, window]
|
let [newX, newY, newPosition, newWindow] = [x, y, positioningItem, window]
|
||||||
|
|
||||||
// menu.popup(x, y, positioningItem)
|
// menu.popup(x, y, positioningItem)
|
||||||
if (!window) {
|
if (window != null && !(window instanceof BrowserWindow)) {
|
||||||
// shift over values
|
[newPosition, newY, newX, newWindow] = [y, x, window, null]
|
||||||
if (typeof window !== 'object' || window.constructor !== BrowserWindow) {
|
|
||||||
[newPosition, newY, newX, newWindow] = [y, x, window, null]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// menu.popup({})
|
||||||
|
if (window != null && window.constructor === Object) {
|
||||||
|
opts = window
|
||||||
// menu.popup(window, {})
|
// menu.popup(window, {})
|
||||||
if (x && typeof x === 'object') {
|
} else if (x && typeof x === 'object') {
|
||||||
const opts = x
|
opts = x
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts) {
|
||||||
newX = opts.x
|
newX = opts.x
|
||||||
newY = opts.y
|
newY = opts.y
|
||||||
newPosition = opts.positioningItem
|
newPosition = opts.positioningItem
|
||||||
@@ -65,13 +68,28 @@ Menu.prototype.popup = function (window, x, y, positioningItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
if (typeof x !== 'number') newX = -1
|
if (typeof newX !== 'number') newX = -1
|
||||||
if (typeof y !== 'number') newY = -1
|
if (typeof newY !== 'number') newY = -1
|
||||||
if (typeof positioningItem !== 'number') newPosition = -1
|
if (typeof newPosition !== 'number') newPosition = -1
|
||||||
if (!window) newWindow = BrowserWindow.getFocusedWindow()
|
|
||||||
if (typeof asyncPopup !== 'boolean') asyncPopup = false
|
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)
|
this.popupAt(newWindow, newX, newY, newPosition, asyncPopup)
|
||||||
|
|
||||||
|
return { browserWindow: newWindow, x: newX, y: newY, position: newPosition, async: asyncPopup }
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu.prototype.closePopup = function (window) {
|
Menu.prototype.closePopup = function (window) {
|
||||||
@@ -149,7 +167,7 @@ Menu.setApplicationMenu = function (menu) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Menu.buildFromTemplate = function (template) {
|
Menu.buildFromTemplate = function (template) {
|
||||||
if (!(template instanceof Array)) {
|
if (!Array.isArray(template)) {
|
||||||
throw new TypeError('Invalid template for Menu')
|
throw new TypeError('Invalid template for Menu')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,18 @@ class TouchBar extends EventEmitter {
|
|||||||
window.removeListener('closed', removeListeners)
|
window.removeListener('closed', removeListeners)
|
||||||
window._touchBar = null
|
window._touchBar = null
|
||||||
delete this.windowListeners[id]
|
delete this.windowListeners[id]
|
||||||
|
const unregisterItems = (items) => {
|
||||||
|
for (const item of items) {
|
||||||
|
item.removeListener('change', this.changeListener)
|
||||||
|
if (item.child instanceof TouchBar) {
|
||||||
|
unregisterItems(item.child.ordereredItems)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unregisterItems(this.ordereredItems)
|
||||||
|
if (this.escapeItem) {
|
||||||
|
this.escapeItem.removeListener('change', this.changeListener)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
window.once('closed', removeListeners)
|
window.once('closed', removeListeners)
|
||||||
this.windowListeners[id] = removeListeners
|
this.windowListeners[id] = removeListeners
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ const createGuest = function (embedder, params) {
|
|||||||
// Forward internal web contents event to embedder to handle
|
// Forward internal web contents event to embedder to handle
|
||||||
// native window.open setup
|
// native window.open setup
|
||||||
guest.on('-add-new-contents', (...args) => {
|
guest.on('-add-new-contents', (...args) => {
|
||||||
if (guest.getWebPreferences().nativeWindowOpen === true) {
|
if (guest.getLastWebPreferences().nativeWindowOpen === true) {
|
||||||
const embedder = getEmbedder(guestInstanceId)
|
const embedder = getEmbedder(guestInstanceId)
|
||||||
if (embedder != null) {
|
if (embedder != null) {
|
||||||
embedder.emit('-add-new-contents', ...args)
|
embedder.emit('-add-new-contents', ...args)
|
||||||
@@ -164,7 +164,7 @@ const createGuest = function (embedder, params) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
guest.on('-web-contents-created', (...args) => {
|
guest.on('-web-contents-created', (...args) => {
|
||||||
if (guest.getWebPreferences().nativeWindowOpen === true) {
|
if (guest.getLastWebPreferences().nativeWindowOpen === true) {
|
||||||
const embedder = getEmbedder(guestInstanceId)
|
const embedder = getEmbedder(guestInstanceId)
|
||||||
if (embedder != null) {
|
if (embedder != null) {
|
||||||
embedder.emit('-web-contents-created', ...args)
|
embedder.emit('-web-contents-created', ...args)
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ const mergeOptions = function (child, parent, visited) {
|
|||||||
visited.add(parent)
|
visited.add(parent)
|
||||||
for (const key in parent) {
|
for (const key in parent) {
|
||||||
if (!hasProp.call(parent, key)) continue
|
if (!hasProp.call(parent, key)) continue
|
||||||
if (key in child) continue
|
if (key in child && key !== 'webPreferences') continue
|
||||||
|
|
||||||
const value = parent[key]
|
const value = parent[key]
|
||||||
if (typeof value === 'object') {
|
if (typeof value === 'object') {
|
||||||
child[key] = mergeOptions({}, value, visited)
|
child[key] = mergeOptions(child[key] || {}, value, visited)
|
||||||
} else {
|
} else {
|
||||||
child[key] = value
|
child[key] = value
|
||||||
}
|
}
|
||||||
@@ -46,16 +46,24 @@ const mergeBrowserWindowOptions = function (embedder, options) {
|
|||||||
options.webPreferences = {}
|
options.webPreferences = {}
|
||||||
}
|
}
|
||||||
if (embedder.browserWindowOptions != null) {
|
if (embedder.browserWindowOptions != null) {
|
||||||
|
let parentOptions = embedder.browserWindowOptions
|
||||||
|
|
||||||
|
// if parent's visibility is available, that overrides 'show' flag (#12125)
|
||||||
|
const win = BrowserWindow.fromWebContents(embedder.webContents)
|
||||||
|
if (win != null) {
|
||||||
|
parentOptions = Object.assign({}, embedder.browserWindowOptions, {show: win.isVisible()})
|
||||||
|
}
|
||||||
|
|
||||||
// Inherit the original options if it is a BrowserWindow.
|
// Inherit the original options if it is a BrowserWindow.
|
||||||
mergeOptions(options, embedder.browserWindowOptions)
|
mergeOptions(options, parentOptions)
|
||||||
} else {
|
} else {
|
||||||
// Or only inherit webPreferences if it is a webview.
|
// Or only inherit webPreferences if it is a webview.
|
||||||
mergeOptions(options.webPreferences, embedder.getWebPreferences())
|
mergeOptions(options.webPreferences, embedder.getLastWebPreferences())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inherit certain option values from parent window
|
// Inherit certain option values from parent window
|
||||||
for (const [name, value] of inheritedWebPreferences) {
|
for (const [name, value] of inheritedWebPreferences) {
|
||||||
if (embedder.getWebPreferences()[name] === value) {
|
if (embedder.getLastWebPreferences()[name] === value) {
|
||||||
options.webPreferences[name] = value
|
options.webPreferences[name] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,8 +176,8 @@ const getGuestWindow = function (guestContents) {
|
|||||||
// The W3C does not have anything on this, but from my understanding of the
|
// The W3C does not have anything on this, but from my understanding of the
|
||||||
// security model of |window.opener|, this should be fine.
|
// security model of |window.opener|, this should be fine.
|
||||||
const canAccessWindow = function (sender, target) {
|
const canAccessWindow = function (sender, target) {
|
||||||
return (target.getWebPreferences().openerId === sender.id) ||
|
return (target.getLastWebPreferences().openerId === sender.id) ||
|
||||||
(sender.getWebPreferences().nodeIntegration === true) ||
|
(sender.getLastWebPreferences().nodeIntegration === true) ||
|
||||||
isSameOrigin(sender.getURL(), target.getURL())
|
isSameOrigin(sender.getURL(), target.getURL())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
const timers = require('timers')
|
const timers = require('timers')
|
||||||
|
const util = require('util')
|
||||||
|
|
||||||
process.atomBinding = require('./atom-binding-setup')(process.binding, process.type)
|
process.atomBinding = require('./atom-binding-setup')(process.binding, process.type)
|
||||||
|
|
||||||
@@ -8,11 +9,21 @@ process.atomBinding = require('./atom-binding-setup')(process.binding, process.t
|
|||||||
// which would delay the callbacks for arbitrary long time. So we should
|
// which would delay the callbacks for arbitrary long time. So we should
|
||||||
// initiatively activate the uv loop once setImmediate and process.nextTick is
|
// initiatively activate the uv loop once setImmediate and process.nextTick is
|
||||||
// called.
|
// called.
|
||||||
var wrapWithActivateUvLoop = function (func) {
|
const wrapWithActivateUvLoop = function (func) {
|
||||||
return function () {
|
return wrap(func, function (func) {
|
||||||
process.activateUvLoop()
|
return function () {
|
||||||
return func.apply(this, arguments)
|
process.activateUvLoop()
|
||||||
|
return func.apply(this, arguments)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrap (func, wrapper) {
|
||||||
|
const wrapped = wrapper(func)
|
||||||
|
if (func[util.promisify.custom]) {
|
||||||
|
wrapped[util.promisify.custom] = wrapper(func[util.promisify.custom])
|
||||||
}
|
}
|
||||||
|
return wrapped
|
||||||
}
|
}
|
||||||
|
|
||||||
process.nextTick = wrapWithActivateUvLoop(process.nextTick)
|
process.nextTick = wrapWithActivateUvLoop(process.nextTick)
|
||||||
|
|||||||
@@ -121,7 +121,18 @@ if (nodeIntegration === 'true') {
|
|||||||
|
|
||||||
// Set the __filename to the path of html file if it is file: protocol.
|
// Set the __filename to the path of html file if it is file: protocol.
|
||||||
if (window.location.protocol === 'file:') {
|
if (window.location.protocol === 'file:') {
|
||||||
var pathname = process.platform === 'win32' && window.location.pathname[0] === '/' ? window.location.pathname.substr(1) : window.location.pathname
|
const location = window.location
|
||||||
|
let pathname = location.pathname
|
||||||
|
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
if (pathname[0] === '/') pathname = pathname.substr(1)
|
||||||
|
|
||||||
|
const isWindowsNetworkSharePath = location.hostname.length > 0 && globalPaths[0].startsWith('\\')
|
||||||
|
if (isWindowsNetworkSharePath) {
|
||||||
|
pathname = `//${location.host}/${pathname}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
global.__filename = path.normalize(decodeURIComponent(pathname))
|
global.__filename = path.normalize(decodeURIComponent(pathname))
|
||||||
global.__dirname = path.dirname(global.__filename)
|
global.__dirname = path.dirname(global.__filename)
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ const preloadModules = new Map([
|
|||||||
['timers', require('timers')]
|
['timers', require('timers')]
|
||||||
])
|
])
|
||||||
|
|
||||||
const preloadSrc = fs.readFileSync(preloadPath).toString()
|
|
||||||
|
|
||||||
// Pass different process object to the preload script(which should not have
|
// Pass different process object to the preload script(which should not have
|
||||||
// access to things like `process.atomBinding`).
|
// access to things like `process.atomBinding`).
|
||||||
const preloadProcess = new events.EventEmitter()
|
const preloadProcess = new events.EventEmitter()
|
||||||
@@ -54,6 +52,11 @@ function preloadRequire (module) {
|
|||||||
throw new Error('module not found')
|
throw new Error('module not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window.location.protocol === 'chrome-devtools:') {
|
||||||
|
// Override some inspector APIs.
|
||||||
|
require('../renderer/inspector')
|
||||||
|
}
|
||||||
|
|
||||||
// Wrap the script into a function executed in global scope. It won't have
|
// Wrap the script into a function executed in global scope. It won't have
|
||||||
// access to the current scope, so we'll expose a few objects as arguments:
|
// access to the current scope, so we'll expose a few objects as arguments:
|
||||||
//
|
//
|
||||||
@@ -73,13 +76,16 @@ function preloadRequire (module) {
|
|||||||
// and any `require('electron')` calls in `preload.js` will work as expected
|
// and any `require('electron')` calls in `preload.js` will work as expected
|
||||||
// since browserify won't try to include `electron` in the bundle, falling back
|
// since browserify won't try to include `electron` in the bundle, falling back
|
||||||
// to the `preloadRequire` function above.
|
// to the `preloadRequire` function above.
|
||||||
const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate) {
|
if (preloadPath) {
|
||||||
${preloadSrc}
|
const preloadSrc = fs.readFileSync(preloadPath).toString()
|
||||||
})`
|
const preloadWrapperSrc = `(function(require, process, Buffer, global, setImmediate) {
|
||||||
|
${preloadSrc}
|
||||||
|
})`
|
||||||
|
|
||||||
// eval in window scope:
|
// eval in window scope:
|
||||||
// http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2
|
// http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2
|
||||||
const geval = eval
|
const geval = eval
|
||||||
const preloadFn = geval(preloadWrapperSrc)
|
const preloadFn = geval(preloadWrapperSrc)
|
||||||
const {setImmediate} = require('timers')
|
const {setImmediate} = require('timers')
|
||||||
preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate)
|
preloadFn(preloadRequire, preloadProcess, Buffer, global, setImmediate)
|
||||||
|
}
|
||||||
|
|||||||
10156
package-lock.json
generated
Normal file
10156
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "electron",
|
"name": "electron",
|
||||||
"version": "1.8.2-beta.2",
|
"version": "1.8.8",
|
||||||
"repository": "https://github.com/electron/electron",
|
"repository": "https://github.com/electron/electron",
|
||||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"dugite": "^1.45.0",
|
"dugite": "^1.45.0",
|
||||||
"electabul": "~0.0.4",
|
"electabul": "~0.0.4",
|
||||||
"electron-docs-linter": "^2.3.4",
|
"electron-docs-linter": "^2.3.4",
|
||||||
"electron-typescript-definitions": "^1.2.11",
|
"electron-typescript-definitions": "~1.2.11",
|
||||||
"github": "^9.2.0",
|
"github": "^9.2.0",
|
||||||
"husky": "^0.14.3",
|
"husky": "^0.14.3",
|
||||||
"minimist": "^1.2.0",
|
"minimist": "^1.2.0",
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ def main():
|
|||||||
if args.target_arch == 'mips64el':
|
if args.target_arch == 'mips64el':
|
||||||
download_mips64el_toolchain()
|
download_mips64el_toolchain()
|
||||||
|
|
||||||
|
if args.target_arch.startswith('arm'):
|
||||||
|
download_native_mksnapshot(args.target_arch)
|
||||||
|
|
||||||
# Redirect to use local libchromiumcontent build.
|
# Redirect to use local libchromiumcontent build.
|
||||||
if args.build_release_libcc or args.build_debug_libcc:
|
if args.build_release_libcc or args.build_debug_libcc:
|
||||||
build_libchromiumcontent(args.verbose, args.target_arch, defines,
|
build_libchromiumcontent(args.verbose, args.target_arch, defines,
|
||||||
@@ -218,6 +221,15 @@ def download_mips64el_toolchain():
|
|||||||
subprocess.check_call(['tar', '-xf', tar_name, '-C', VENDOR_DIR])
|
subprocess.check_call(['tar', '-xf', tar_name, '-C', VENDOR_DIR])
|
||||||
os.remove(tar_name)
|
os.remove(tar_name)
|
||||||
|
|
||||||
|
def download_native_mksnapshot(arch):
|
||||||
|
if not os.path.exists(os.path.join(VENDOR_DIR,
|
||||||
|
'native_mksnapshot')):
|
||||||
|
zip_name = 'native-mksnapshot.zip'
|
||||||
|
url = '{0}/linux/{1}/{2}/{3}'.format(BASE_URL, arch,
|
||||||
|
get_libchromiumcontent_commit(), zip_name)
|
||||||
|
download(zip_name, url, os.path.join(SOURCE_ROOT, zip_name))
|
||||||
|
subprocess.call(['unzip', zip_name, '-d', VENDOR_DIR])
|
||||||
|
os.remove(zip_name)
|
||||||
|
|
||||||
def create_chrome_version_h():
|
def create_chrome_version_h():
|
||||||
version_file = os.path.join(VENDOR_DIR, 'libchromiumcontent', 'VERSION')
|
version_file = os.path.join(VENDOR_DIR, 'libchromiumcontent', 'VERSION')
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ def main():
|
|||||||
ninja += '.exe'
|
ninja += '.exe'
|
||||||
|
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
|
if args.ninja_path:
|
||||||
|
ninja = args.ninja_path
|
||||||
if args.libcc:
|
if args.libcc:
|
||||||
if ('D' not in args.configuration
|
if ('D' not in args.configuration
|
||||||
or not os.path.exists(GCLIENT_DONE)
|
or not os.path.exists(GCLIENT_DONE)
|
||||||
@@ -67,6 +69,9 @@ def parse_args():
|
|||||||
'-d --debug_libchromiumcontent.'
|
'-d --debug_libchromiumcontent.'
|
||||||
),
|
),
|
||||||
action='store_true', default=False)
|
action='store_true', default=False)
|
||||||
|
parser.add_argument('--ninja-path',
|
||||||
|
help='Path of ninja command to use.',
|
||||||
|
required=False)
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
const buildAppVeyorURL = 'https://windows-ci.electronjs.org/api/builds'
|
const buildAppVeyorURL = 'https://windows-ci.electronjs.org/api/builds'
|
||||||
const jenkinsServer = 'https://mac-ci.electronjs.org'
|
|
||||||
|
|
||||||
const circleCIJobs = [
|
const circleCIJobs = [
|
||||||
'electron-linux-arm',
|
'electron-linux-arm',
|
||||||
@@ -11,11 +10,6 @@ const circleCIJobs = [
|
|||||||
'electron-linux-x64'
|
'electron-linux-x64'
|
||||||
]
|
]
|
||||||
|
|
||||||
const jenkinsJobs = [
|
|
||||||
'electron-mas-x64-release',
|
|
||||||
'electron-osx-x64-release'
|
|
||||||
]
|
|
||||||
|
|
||||||
async function makeRequest (requestOptions, parseResponse) {
|
async function makeRequest (requestOptions, parseResponse) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
request(requestOptions, (err, res, body) => {
|
request(requestOptions, (err, res, body) => {
|
||||||
@@ -32,7 +26,7 @@ async function makeRequest (requestOptions, parseResponse) {
|
|||||||
} else {
|
} else {
|
||||||
console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions)
|
console.log('Error: ', `(status ${res.statusCode})`, err || res.body, requestOptions)
|
||||||
}
|
}
|
||||||
reject()
|
reject(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -111,68 +105,6 @@ function buildCircleCI (targetBranch, ghRelease, job) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildJenkins (targetBranch, ghRelease, job) {
|
|
||||||
assert(process.env.JENKINS_AUTH_TOKEN, 'JENKINS_AUTH_TOKEN not found in environment')
|
|
||||||
assert(process.env.JENKINS_BUILD_TOKEN, 'JENKINS_BUILD_TOKEN not found in environment')
|
|
||||||
let jenkinsCrumb = await getJenkinsCrumb()
|
|
||||||
|
|
||||||
if (job) {
|
|
||||||
assert(jenkinsJobs.includes(job), `Unknown CI job name: ${job}.`)
|
|
||||||
callJenkinsBuild(job, jenkinsCrumb, targetBranch, ghRelease)
|
|
||||||
} else {
|
|
||||||
jenkinsJobs.forEach((job) => {
|
|
||||||
callJenkinsBuild(job, jenkinsCrumb, targetBranch, ghRelease)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function callJenkins (path, requestParameters, requestHeaders) {
|
|
||||||
let requestOptions = {
|
|
||||||
url: `${jenkinsServer}/${path}`,
|
|
||||||
auth: {
|
|
||||||
user: 'build',
|
|
||||||
pass: process.env.JENKINS_AUTH_TOKEN
|
|
||||||
},
|
|
||||||
qs: requestParameters
|
|
||||||
}
|
|
||||||
if (requestHeaders) {
|
|
||||||
requestOptions.headers = requestHeaders
|
|
||||||
}
|
|
||||||
let jenkinsResponse = await makeRequest(requestOptions).catch(err => {
|
|
||||||
console.log(`Error calling Jenkins:`, err)
|
|
||||||
})
|
|
||||||
return jenkinsResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
async function callJenkinsBuild (job, jenkinsCrumb, targetBranch, ghRelease) {
|
|
||||||
console.log(`Triggering Jenkins to run build job: ${job} on branch: ${targetBranch} with release flag.`)
|
|
||||||
let jenkinsParams = {
|
|
||||||
token: process.env.JENKINS_BUILD_TOKEN,
|
|
||||||
BRANCH: targetBranch
|
|
||||||
}
|
|
||||||
if (!ghRelease) {
|
|
||||||
jenkinsParams.RUN_RELEASE_BUILD = 1
|
|
||||||
}
|
|
||||||
await callJenkins(`job/${job}/buildWithParameters`, jenkinsParams, jenkinsCrumb)
|
|
||||||
.catch(err => {
|
|
||||||
console.log(`Error calling Jenkins build`, err)
|
|
||||||
})
|
|
||||||
let buildUrl = `${jenkinsServer}/job/${job}/lastBuild/`
|
|
||||||
console.log(`Jenkins build request successful. Check build status at ${buildUrl}.`)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getJenkinsCrumb () {
|
|
||||||
let crumbResponse = await callJenkins('crumbIssuer/api/xml', {
|
|
||||||
xpath: 'concat(//crumbRequestField,":",//crumb)'
|
|
||||||
}).catch(err => {
|
|
||||||
console.log(`Error getting jenkins crumb:`, err)
|
|
||||||
})
|
|
||||||
let crumbDetails = crumbResponse.split(':')
|
|
||||||
let crumbHeader = {}
|
|
||||||
crumbHeader[crumbDetails[0]] = crumbDetails[1]
|
|
||||||
return crumbHeader
|
|
||||||
}
|
|
||||||
|
|
||||||
function runRelease (targetBranch, options) {
|
function runRelease (targetBranch, options) {
|
||||||
if (options.ci) {
|
if (options.ci) {
|
||||||
switch (options.ci) {
|
switch (options.ci) {
|
||||||
@@ -184,26 +116,21 @@ function runRelease (targetBranch, options) {
|
|||||||
buildAppVeyor(targetBranch, options.ghRelease)
|
buildAppVeyor(targetBranch, options.ghRelease)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'Jenkins': {
|
|
||||||
buildJenkins(targetBranch, options.ghRelease, options.job)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buildCircleCI(targetBranch, options.ghRelease, options.job)
|
buildCircleCI(targetBranch, options.ghRelease, options.job)
|
||||||
buildAppVeyor(targetBranch, options.ghRelease)
|
buildAppVeyor(targetBranch, options.ghRelease)
|
||||||
buildJenkins(targetBranch, options.ghRelease, options.job)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = runRelease
|
module.exports = runRelease
|
||||||
|
|
||||||
if (require.main === module) {
|
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]
|
const targetBranch = args._[0]
|
||||||
if (args._.length < 1) {
|
if (args._.length < 1) {
|
||||||
console.log(`Trigger CI to build release builds of electron.
|
console.log(`Trigger CI to build release builds of electron.
|
||||||
Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor|Jenkins] [--ghRelease] TARGET_BRANCH
|
Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor] [--ghRelease] TARGET_BRANCH
|
||||||
`)
|
`)
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ DIST_DIR = os.path.join(SOURCE_ROOT, 'dist')
|
|||||||
OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'R')
|
OUT_DIR = os.path.join(SOURCE_ROOT, 'out', 'R')
|
||||||
CHROMIUM_DIR = os.path.join(SOURCE_ROOT, 'vendor', 'download',
|
CHROMIUM_DIR = os.path.join(SOURCE_ROOT, 'vendor', 'download',
|
||||||
'libchromiumcontent', 'static_library')
|
'libchromiumcontent', 'static_library')
|
||||||
|
NATIVE_MKSNAPSHOT_DIR = os.path.join(SOURCE_ROOT, 'vendor', 'native_mksnapshot')
|
||||||
|
|
||||||
PROJECT_NAME = electron_gyp()['project_name%']
|
PROJECT_NAME = electron_gyp()['project_name%']
|
||||||
PRODUCT_NAME = electron_gyp()['product_name%']
|
PRODUCT_NAME = electron_gyp()['product_name%']
|
||||||
@@ -138,7 +139,6 @@ def copy_chrome_binary(binary):
|
|||||||
shutil.copyfile(src, dest)
|
shutil.copyfile(src, dest)
|
||||||
os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC)
|
os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC)
|
||||||
|
|
||||||
|
|
||||||
def copy_vcruntime_binaries():
|
def copy_vcruntime_binaries():
|
||||||
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
|
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
|
||||||
r"SOFTWARE\Microsoft\VisualStudio\14.0\Setup\VC", 0,
|
r"SOFTWARE\Microsoft\VisualStudio\14.0\Setup\VC", 0,
|
||||||
@@ -215,7 +215,7 @@ def strip_binary(binary_path):
|
|||||||
elif get_target_arch() == 'arm64':
|
elif get_target_arch() == 'arm64':
|
||||||
strip = 'aarch64-linux-gnu-strip'
|
strip = 'aarch64-linux-gnu-strip'
|
||||||
elif get_target_arch() == 'mips64el':
|
elif get_target_arch() == 'mips64el':
|
||||||
strip = 'mips64el-redhat-linux-strip'
|
strip = 'mips64el-loongson-linux-strip'
|
||||||
else:
|
else:
|
||||||
strip = 'strip'
|
strip = 'strip'
|
||||||
execute([strip, binary_path], env=build_env())
|
execute([strip, binary_path], env=build_env())
|
||||||
@@ -257,17 +257,39 @@ def create_dist_zip():
|
|||||||
|
|
||||||
|
|
||||||
def create_chrome_binary_zip(binary, version):
|
def create_chrome_binary_zip(binary, version):
|
||||||
dist_name = get_zip_name(binary, version)
|
file_suffix = ''
|
||||||
|
create_native_mksnapshot = False
|
||||||
|
if binary == 'mksnapshot':
|
||||||
|
arch = get_target_arch()
|
||||||
|
if arch.startswith('arm'):
|
||||||
|
# if the arch is arm/arm64 the mksnapshot executable is an x64 binary,
|
||||||
|
# so name it as such.
|
||||||
|
file_suffix = 'x64'
|
||||||
|
create_native_mksnapshot = True
|
||||||
|
dist_name = get_zip_name(binary, version, file_suffix)
|
||||||
zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name)
|
zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name)
|
||||||
|
|
||||||
|
files = ['LICENSE', 'LICENSES.chromium.html']
|
||||||
|
if PLATFORM == 'win32':
|
||||||
|
files += [binary + '.exe']
|
||||||
|
else:
|
||||||
|
files += [binary]
|
||||||
|
|
||||||
with scoped_cwd(DIST_DIR):
|
with scoped_cwd(DIST_DIR):
|
||||||
files = ['LICENSE', 'LICENSES.chromium.html']
|
|
||||||
if PLATFORM == 'win32':
|
|
||||||
files += [binary + '.exe']
|
|
||||||
else:
|
|
||||||
files += [binary]
|
|
||||||
make_zip(zip_file, files, [])
|
make_zip(zip_file, files, [])
|
||||||
|
|
||||||
|
if create_native_mksnapshot == True:
|
||||||
|
# Create a zip with the native version of the mksnapshot binary.
|
||||||
|
src = os.path.join(NATIVE_MKSNAPSHOT_DIR, binary)
|
||||||
|
dest = os.path.join(DIST_DIR, binary)
|
||||||
|
# Copy file and keep the executable bit.
|
||||||
|
shutil.copyfile(src, dest)
|
||||||
|
os.chmod(dest, os.stat(dest).st_mode | stat.S_IEXEC)
|
||||||
|
|
||||||
|
dist_name = get_zip_name(binary, version)
|
||||||
|
zip_file = os.path.join(SOURCE_ROOT, 'dist', dist_name)
|
||||||
|
with scoped_cwd(DIST_DIR):
|
||||||
|
make_zip(zip_file, files, [])
|
||||||
|
|
||||||
def create_ffmpeg_zip():
|
def create_ffmpeg_zip():
|
||||||
dist_name = get_zip_name('ffmpeg', ELECTRON_VERSION)
|
dist_name = get_zip_name('ffmpeg', ELECTRON_VERSION)
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import sys
|
|||||||
# URL to the mips64el sysroot image.
|
# 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'
|
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.
|
# URL to the mips64el toolchain.
|
||||||
MIPS64EL_GCC = 'gcc-4.8.3-d197-n64-loongson'
|
MIPS64EL_GCC = 'cross-gcc-4.9.3-n64-loongson-rc5.4'
|
||||||
MIPS64EL_GCC_URL = 'http://ftp.loongnix.org/toolchain/gcc/release/' + MIPS64EL_GCC + '.tar.gz'
|
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 \
|
BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \
|
||||||
'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent'
|
'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent'
|
||||||
@@ -93,11 +93,11 @@ def build_env():
|
|||||||
VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor')
|
VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor')
|
||||||
gcc_dir = os.path.join(VENDOR_DIR, MIPS64EL_GCC)
|
gcc_dir = os.path.join(VENDOR_DIR, MIPS64EL_GCC)
|
||||||
ldlib_dirs = [
|
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/lib64',
|
||||||
gcc_dir + '/usr/mips64el-redhat-linux/lib64',
|
gcc_dir + '/usr/mips64el-loongson-linux/lib64',
|
||||||
gcc_dir + '/usr/mips64el-redhat-linux/sysroot/lib64',
|
gcc_dir + '/usr/mips64el-loongson-linux/sysroot/lib64',
|
||||||
gcc_dir + '/usr/mips64el-redhat-linux/sysroot/usr/lib64',
|
gcc_dir + '/usr/mips64el-loongson-linux/sysroot/usr/lib64',
|
||||||
]
|
]
|
||||||
env['LD_LIBRARY_PATH'] = os.pathsep.join(ldlib_dirs)
|
env['LD_LIBRARY_PATH'] = os.pathsep.join(ldlib_dirs)
|
||||||
env['PATH'] = os.pathsep.join([gcc_dir + '/usr/bin', env['PATH']])
|
env['PATH'] = os.pathsep.join([gcc_dir + '/usr/bin', env['PATH']])
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const GitHub = require('github')
|
|||||||
const pass = '\u2713'.green
|
const pass = '\u2713'.green
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const pkg = require('../package.json')
|
const pkg = require('../package.json')
|
||||||
|
const readline = require('readline')
|
||||||
const versionType = args._[0]
|
const versionType = args._[0]
|
||||||
|
|
||||||
// TODO (future) automatically determine version based on conventional commits
|
// 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.`)
|
console.log(`Bumping for new "${versionType}" version.`)
|
||||||
let bumpScript = path.join(__dirname, 'bump-version.py')
|
let bumpScript = path.join(__dirname, 'bump-version.py')
|
||||||
let scriptArgs = [bumpScript, `--bump ${versionType}`]
|
let scriptArgs = [bumpScript, `--bump ${versionType}`]
|
||||||
if (args.stable) {
|
if (args.stable) {
|
||||||
scriptArgs.push('--stable')
|
scriptArgs.push('--stable')
|
||||||
}
|
}
|
||||||
|
if (dryRun) {
|
||||||
|
scriptArgs.push('--dry-run')
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
let bumpVersion = execSync(scriptArgs.join(' '), {encoding: 'UTF-8'})
|
let bumpVersion = execSync(scriptArgs.join(' '), {encoding: 'UTF-8'})
|
||||||
bumpVersion = bumpVersion.substr(bumpVersion.indexOf(':') + 1).trim()
|
bumpVersion = bumpVersion.substr(bumpVersion.indexOf(':') + 1).trim()
|
||||||
let newVersion = `v${bumpVersion}`
|
let newVersion = `v${bumpVersion}`
|
||||||
console.log(`${pass} Successfully bumped version to ${newVersion}`)
|
if (!dryRun) {
|
||||||
|
console.log(`${pass} Successfully bumped version to ${newVersion}`)
|
||||||
|
}
|
||||||
return newVersion
|
return newVersion
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(`${fail} Could not bump version, error was:`, err)
|
console.log(`${fail} Could not bump version, error was:`, err)
|
||||||
@@ -119,23 +125,25 @@ async function createRelease (branchToTarget, isBeta) {
|
|||||||
.catch(err => {
|
.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)
|
let drafts = releases.data.filter(release => release.draft &&
|
||||||
|
release.tag_name === newVersion)
|
||||||
if (drafts.length > 0) {
|
if (drafts.length > 0) {
|
||||||
console.log(`${fail} Aborting because draft release for
|
console.log(`${fail} Aborting because draft release for
|
||||||
${drafts[0].tag_name} already exists.`)
|
${drafts[0].tag_name} already exists.`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
console.log(`${pass} A draft release does not exist; creating one.`)
|
console.log(`${pass} A draft release does not exist; creating one.`)
|
||||||
githubOpts.body = releaseNotes
|
|
||||||
githubOpts.draft = true
|
githubOpts.draft = true
|
||||||
githubOpts.name = `electron ${newVersion}`
|
githubOpts.name = `electron ${newVersion}`
|
||||||
if (isBeta) {
|
if (isBeta) {
|
||||||
githubOpts.body = `Note: This is a beta release. Please file new issues ` +
|
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 ` +
|
`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, ` +
|
`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.name = `${githubOpts.name}`
|
||||||
githubOpts.prerelease = true
|
githubOpts.prerelease = true
|
||||||
|
} else {
|
||||||
|
githubOpts.body = releaseNotes
|
||||||
}
|
}
|
||||||
githubOpts.tag_name = newVersion
|
githubOpts.tag_name = newVersion
|
||||||
githubOpts.target_commitish = branchToTarget
|
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) {
|
async function prepareRelease (isBeta, notesOnly) {
|
||||||
let currentBranch = await getCurrentBranch(gitDir)
|
let currentBranch = await getCurrentBranch(gitDir)
|
||||||
if (notesOnly) {
|
if (notesOnly) {
|
||||||
let releaseNotes = await getReleaseNotes(currentBranch)
|
let releaseNotes = await getReleaseNotes(currentBranch)
|
||||||
console.log(`Draft release notes are: ${releaseNotes}`)
|
console.log(`Draft release notes are: ${releaseNotes}`)
|
||||||
} else {
|
} else {
|
||||||
|
await verifyNewVersion()
|
||||||
await createReleaseBranch()
|
await createReleaseBranch()
|
||||||
await createRelease(currentBranch, isBeta)
|
await createRelease(currentBranch, isBeta)
|
||||||
await pushRelease()
|
await pushRelease()
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ const files = [
|
|||||||
'index.js',
|
'index.js',
|
||||||
'install.js',
|
'install.js',
|
||||||
'package.json',
|
'package.json',
|
||||||
'README.md'
|
'README.md',
|
||||||
|
'LICENSE'
|
||||||
]
|
]
|
||||||
|
|
||||||
const jsonFields = [
|
const jsonFields = [
|
||||||
@@ -49,9 +50,10 @@ new Promise((resolve, reject) => {
|
|||||||
tempDir = dirPath
|
tempDir = dirPath
|
||||||
// copy files from `/npm` to temp directory
|
// copy files from `/npm` to temp directory
|
||||||
files.forEach((name) => {
|
files.forEach((name) => {
|
||||||
|
const noThirdSegment = name === 'README.md' || name === 'LICENSE'
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.join(tempDir, name),
|
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
|
// copy from root package.json to temp/package.json
|
||||||
|
|||||||
@@ -31,21 +31,18 @@ async function getDraftRelease (version, skipValidation) {
|
|||||||
let drafts
|
let drafts
|
||||||
let versionToCheck
|
let versionToCheck
|
||||||
if (version) {
|
if (version) {
|
||||||
drafts = releaseInfo.data
|
|
||||||
.filter(release => release.tag_name === version)
|
|
||||||
versionToCheck = version
|
versionToCheck = version
|
||||||
} else {
|
} else {
|
||||||
drafts = releaseInfo.data
|
|
||||||
.filter(release => release.draft)
|
|
||||||
versionToCheck = pkgVersion
|
versionToCheck = pkgVersion
|
||||||
}
|
}
|
||||||
|
drafts = releaseInfo.data
|
||||||
|
.filter(release => release.tag_name === versionToCheck &&
|
||||||
|
release.draft === true)
|
||||||
const draft = drafts[0]
|
const draft = drafts[0]
|
||||||
if (!skipValidation) {
|
if (!skipValidation) {
|
||||||
failureCount = 0
|
failureCount = 0
|
||||||
check(drafts.length === 1, 'one draft exists', true)
|
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') > -1) {
|
||||||
if (versionToCheck.indexOf('beta')) {
|
|
||||||
check(draft.prerelease, 'draft is a prerelease')
|
check(draft.prerelease, 'draft is a prerelease')
|
||||||
}
|
}
|
||||||
check(draft.body.length > 50 && !draft.body.includes('(placeholder)'), 'draft has release notes')
|
check(draft.body.length > 50 && !draft.body.includes('(placeholder)'), 'draft has release notes')
|
||||||
@@ -54,8 +51,8 @@ async function getDraftRelease (version, skipValidation) {
|
|||||||
return draft
|
return draft
|
||||||
}
|
}
|
||||||
|
|
||||||
async function validateReleaseAssets (release) {
|
async function validateReleaseAssets (release, validatingRelease) {
|
||||||
const requiredAssets = assetsForVersion(release.tag_name).sort()
|
const requiredAssets = assetsForVersion(release.tag_name, validatingRelease).sort()
|
||||||
const extantAssets = release.assets.map(asset => asset.name).sort()
|
const extantAssets = release.assets.map(asset => asset.name).sort()
|
||||||
const downloadUrls = release.assets.map(asset => asset.browser_download_url).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 = [
|
const patterns = [
|
||||||
`electron-${version}-darwin-x64-dsym.zip`,
|
`electron-${version}-darwin-x64-dsym.zip`,
|
||||||
`electron-${version}-darwin-x64-symbols.zip`,
|
`electron-${version}-darwin-x64-symbols.zip`,
|
||||||
@@ -123,9 +120,11 @@ function assetsForVersion (version) {
|
|||||||
`ffmpeg-${version}-linux-x64.zip`,
|
`ffmpeg-${version}-linux-x64.zip`,
|
||||||
`ffmpeg-${version}-mas-x64.zip`,
|
`ffmpeg-${version}-mas-x64.zip`,
|
||||||
`ffmpeg-${version}-win32-ia32.zip`,
|
`ffmpeg-${version}-win32-ia32.zip`,
|
||||||
`ffmpeg-${version}-win32-x64.zip`,
|
`ffmpeg-${version}-win32-x64.zip`
|
||||||
`SHASUMS256.txt`
|
|
||||||
]
|
]
|
||||||
|
if (!validatingRelease) {
|
||||||
|
patterns.push('SHASUMS256.txt')
|
||||||
|
}
|
||||||
return patterns
|
return patterns
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +214,7 @@ async function uploadShasumFile (filePath, fileName, release) {
|
|||||||
filePath,
|
filePath,
|
||||||
name: fileName
|
name: fileName
|
||||||
}
|
}
|
||||||
return await github.repos.uploadAsset(githubOpts)
|
return github.repos.uploadAsset(githubOpts)
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(`${fail} Error uploading ${filePath} to GitHub:`, err)
|
console.log(`${fail} Error uploading ${filePath} to GitHub:`, err)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
@@ -250,7 +249,7 @@ async function publishRelease (release) {
|
|||||||
tag_name: release.tag_name,
|
tag_name: release.tag_name,
|
||||||
draft: false
|
draft: false
|
||||||
}
|
}
|
||||||
return await github.repos.editRelease(githubOpts)
|
return github.repos.editRelease(githubOpts)
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(`${fail} Error publishing release:`, err)
|
console.log(`${fail} Error publishing release:`, err)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
@@ -259,9 +258,14 @@ async function publishRelease (release) {
|
|||||||
|
|
||||||
async function makeRelease (releaseToValidate) {
|
async function makeRelease (releaseToValidate) {
|
||||||
if (releaseToValidate) {
|
if (releaseToValidate) {
|
||||||
console.log(`Validating release ${args.validateRelease}`)
|
if (releaseToValidate === true) {
|
||||||
let release = await getDraftRelease(args.validateRelease)
|
releaseToValidate = pkgVersion
|
||||||
await validateReleaseAssets(release)
|
} else {
|
||||||
|
console.log('Release to validate !=== true')
|
||||||
|
}
|
||||||
|
console.log(`Validating release ${releaseToValidate}`)
|
||||||
|
let release = await getDraftRelease(releaseToValidate)
|
||||||
|
await validateReleaseAssets(release, true)
|
||||||
} else {
|
} else {
|
||||||
checkVersion()
|
checkVersion()
|
||||||
let draftRelease = await getDraftRelease()
|
let draftRelease = await getDraftRelease()
|
||||||
@@ -447,7 +451,7 @@ async function cleanupReleaseBranch () {
|
|||||||
await callGit(['branch', '-D', 'release'], errorMessage, successMessage)
|
await callGit(['branch', '-D', 'release'], errorMessage, successMessage)
|
||||||
errorMessage = `Could not delete remote release branch.`
|
errorMessage = `Could not delete remote release branch.`
|
||||||
successMessage = `Successfully deleted 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) {
|
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}
|
LLVM_REPO_URL=${LLVM_URL:-https://llvm.org/svn/llvm-project}
|
||||||
|
|
||||||
CDS_URL=https://commondatastorage.googleapis.com/chromium-browser-clang
|
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.
|
# 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,
|
# 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.
|
# 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
|
echo Trying to download prebuilt clang
|
||||||
if which curl > /dev/null; then
|
rm -rf "${LLVM_BUILD_DIR}"
|
||||||
curl -L --fail "${CDS_FULL_URL}" -o "${CDS_OUTPUT}" || \
|
mkdir -p "${LLVM_BUILD_DIR}"
|
||||||
rm -rf "${CDS_OUT_DIR}"
|
|
||||||
elif which wget > /dev/null; then
|
CDS_FILES=("clang-${PACKAGE_VERSION}.tgz")
|
||||||
wget "${CDS_FULL_URL}" -O "${CDS_OUTPUT}" || rm -rf "${CDS_OUT_DIR}"
|
CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX)
|
||||||
else
|
if [ "${OS}" = "Linux" ]; then
|
||||||
echo "Neither curl nor wget found. Please install one of these."
|
ARCH="$(uname -m)"
|
||||||
exit 1
|
if [ "${ARCH}" = "aarch64" ]; then
|
||||||
fi
|
CDS_URL="${S3_URL}"
|
||||||
if [ -f "${CDS_OUTPUT}" ]; then
|
CDS_SUBDIR="arm64"
|
||||||
rm -rf "${LLVM_BUILD_DIR}"
|
else
|
||||||
mkdir -p "${LLVM_BUILD_DIR}"
|
CDS_FILES+=("llvmgold-${PACKAGE_VERSION}.tgz")
|
||||||
tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}"
|
CDS_SUBDIR="Linux_x64"
|
||||||
echo clang "${PACKAGE_VERSION}" unpacked
|
fi
|
||||||
echo "${PACKAGE_VERSION}" > "${STAMP_FILE}"
|
elif [ "${OS}" = "Darwin" ]; then
|
||||||
rm -rf "${CDS_OUT_DIR}"
|
CDS_SUBDIR="Mac"
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo Did not find prebuilt clang "${PACKAGE_VERSION}", building
|
|
||||||
fi
|
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
|
||||||
|
|||||||
@@ -85,12 +85,16 @@ def main():
|
|||||||
upload_electron(github, release, os.path.join(DIST_DIR, ffmpeg),
|
upload_electron(github, release, os.path.join(DIST_DIR, ffmpeg),
|
||||||
args.upload_to_s3)
|
args.upload_to_s3)
|
||||||
|
|
||||||
# Upload chromedriver and mksnapshot for minor version update.
|
chromedriver = get_zip_name('chromedriver', ELECTRON_VERSION)
|
||||||
if parse_version(args.version)[2] == '0':
|
upload_electron(github, release, os.path.join(DIST_DIR, chromedriver),
|
||||||
chromedriver = get_zip_name('chromedriver', ELECTRON_VERSION)
|
args.upload_to_s3)
|
||||||
upload_electron(github, release, os.path.join(DIST_DIR, chromedriver),
|
mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION)
|
||||||
args.upload_to_s3)
|
upload_electron(github, release, os.path.join(DIST_DIR, mksnapshot),
|
||||||
mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION)
|
args.upload_to_s3)
|
||||||
|
|
||||||
|
if get_target_arch().startswith('arm'):
|
||||||
|
# Upload the x64 binary for arm/arm64 mksnapshot
|
||||||
|
mksnapshot = get_zip_name('mksnapshot', ELECTRON_VERSION, 'x64')
|
||||||
upload_electron(github, release, os.path.join(DIST_DIR, mksnapshot),
|
upload_electron(github, release, os.path.join(DIST_DIR, mksnapshot),
|
||||||
args.upload_to_s3)
|
args.upload_to_s3)
|
||||||
|
|
||||||
@@ -179,7 +183,7 @@ def get_text_with_editor(name):
|
|||||||
def create_or_get_release_draft(github, releases, tag, tag_exists):
|
def create_or_get_release_draft(github, releases, tag, tag_exists):
|
||||||
# Search for existing draft.
|
# Search for existing draft.
|
||||||
for release in releases:
|
for release in releases:
|
||||||
if release['draft']:
|
if release['draft'] and release['tag_name'] == tag:
|
||||||
return release
|
return release
|
||||||
|
|
||||||
if tag_exists:
|
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', () => {
|
describe('getFileIcon() API', () => {
|
||||||
const iconPath = path.join(__dirname, 'fixtures/assets/icon.ico')
|
const iconPath = path.join(__dirname, 'fixtures/assets/icon.ico')
|
||||||
const sizes = {
|
const sizes = {
|
||||||
|
|||||||
@@ -30,6 +30,22 @@ describe('BrowserView module', () => {
|
|||||||
return closeWindow(w).then(() => { w = null })
|
return closeWindow(w).then(() => { w = null })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('BrowserView.destroy()', () => {
|
||||||
|
it('does not throw', () => {
|
||||||
|
view = new BrowserView()
|
||||||
|
view.destroy()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('BrowserView.isDestroyed()', () => {
|
||||||
|
it('returns correct value', () => {
|
||||||
|
view = new BrowserView()
|
||||||
|
assert.ok(!view.isDestroyed())
|
||||||
|
view.destroy()
|
||||||
|
assert.ok(view.isDestroyed())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('BrowserView.setBackgroundColor()', () => {
|
describe('BrowserView.setBackgroundColor()', () => {
|
||||||
it('does not throw for valid args', () => {
|
it('does not throw for valid args', () => {
|
||||||
view = new BrowserView()
|
view = new BrowserView()
|
||||||
|
|||||||
@@ -421,6 +421,29 @@ describe('BrowserWindow module', () => {
|
|||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('preserves transparency', (done) => {
|
||||||
|
w.close()
|
||||||
|
const width = 400
|
||||||
|
const height = 400
|
||||||
|
w = new BrowserWindow({
|
||||||
|
show: false,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
transparent: true
|
||||||
|
})
|
||||||
|
w.loadURL('data:text/html,<html><body background-color: rgba(255,255,255,0)></body></html>')
|
||||||
|
w.once('ready-to-show', () => {
|
||||||
|
w.show()
|
||||||
|
w.capturePage((image) => {
|
||||||
|
let imgBuffer = image.toPNG()
|
||||||
|
// Check 25th byte in the PNG
|
||||||
|
// Values can be 0,2,3,4, or 6. We want 6, which is RGB + Alpha
|
||||||
|
assert.equal(imgBuffer[25], 6)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('BrowserWindow.setSize(width, height)', () => {
|
describe('BrowserWindow.setSize(width, height)', () => {
|
||||||
@@ -2861,7 +2884,7 @@ describe('BrowserWindow module', () => {
|
|||||||
})
|
})
|
||||||
it('enables context isolation on child windows', (done) => {
|
it('enables context isolation on child windows', (done) => {
|
||||||
app.once('browser-window-created', (event, window) => {
|
app.once('browser-window-created', (event, window) => {
|
||||||
assert.equal(window.webContents.getWebPreferences().contextIsolation, true)
|
assert.equal(window.webContents.getLastWebPreferences().contextIsolation, true)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
w.loadURL(`file://${fixtures}/pages/window-open.html`)
|
w.loadURL(`file://${fixtures}/pages/window-open.html`)
|
||||||
|
|||||||
@@ -279,14 +279,26 @@ describe('Menu module', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
menu.closePopup()
|
||||||
|
menu.closePopup(w)
|
||||||
return closeWindow(w).then(() => { w = null })
|
return closeWindow(w).then(() => { w = null })
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('when called with async: true', () => {
|
it('returns immediately', () => {
|
||||||
it('returns immediately', () => {
|
const { browserWindow, x, y, async } = menu.popup(w, {x: 100, y: 101, async: true})
|
||||||
menu.popup(w, {x: 100, y: 100, async: true})
|
|
||||||
menu.closePopup(w)
|
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', () => {
|
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"'
|
let contentDisposition = 'inline; filename="mock.pdf"'
|
||||||
const downloadFilePath = path.join(fixtures, 'mock.pdf')
|
const downloadFilePath = path.join(fixtures, 'mock.pdf')
|
||||||
const downloadServer = http.createServer((req, res) => {
|
const downloadServer = http.createServer((req, res) => {
|
||||||
@@ -286,11 +287,15 @@ describe('session module', () => {
|
|||||||
})
|
})
|
||||||
const assertDownload = (event, state, url, mimeType,
|
const assertDownload = (event, state, url, mimeType,
|
||||||
receivedBytes, totalBytes, disposition,
|
receivedBytes, totalBytes, disposition,
|
||||||
filename, port, savePath) => {
|
filename, port, savePath, isCustom) => {
|
||||||
assert.equal(state, 'completed')
|
assert.equal(state, 'completed')
|
||||||
assert.equal(filename, 'mock.pdf')
|
assert.equal(filename, 'mock.pdf')
|
||||||
assert.equal(savePath, path.join(__dirname, 'fixtures', '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(mimeType, 'application/pdf')
|
||||||
assert.equal(receivedBytes, mockPDF.length)
|
assert.equal(receivedBytes, mockPDF.length)
|
||||||
assert.equal(totalBytes, 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) => {
|
it('can download using WebView.downloadURL', (done) => {
|
||||||
downloadServer.listen(0, '127.0.0.1', () => {
|
downloadServer.listen(0, '127.0.0.1', () => {
|
||||||
const port = downloadServer.address().port
|
const port = downloadServer.address().port
|
||||||
|
|||||||
@@ -115,7 +115,12 @@ describe('chromium feature', () => {
|
|||||||
|
|
||||||
describe('navigator.serviceWorker', () => {
|
describe('navigator.serviceWorker', () => {
|
||||||
it('should register for file scheme', (done) => {
|
it('should register for file scheme', (done) => {
|
||||||
w = new BrowserWindow({ show: false })
|
w = new BrowserWindow({
|
||||||
|
show: false,
|
||||||
|
webPreferences: {
|
||||||
|
partition: 'sw-file-scheme-spec'
|
||||||
|
}
|
||||||
|
})
|
||||||
w.webContents.on('ipc-message', (event, args) => {
|
w.webContents.on('ipc-message', (event, args) => {
|
||||||
if (args[0] === 'reload') {
|
if (args[0] === 'reload') {
|
||||||
w.webContents.reload()
|
w.webContents.reload()
|
||||||
@@ -123,7 +128,7 @@ describe('chromium feature', () => {
|
|||||||
done(`unexpected error : ${args[1]}`)
|
done(`unexpected error : ${args[1]}`)
|
||||||
} else if (args[0] === 'response') {
|
} else if (args[0] === 'response') {
|
||||||
assert.equal(args[1], 'Hello from serviceWorker!')
|
assert.equal(args[1], 'Hello from serviceWorker!')
|
||||||
session.defaultSession.clearStorageData({
|
session.fromPartition('sw-file-scheme-spec').clearStorageData({
|
||||||
storages: ['serviceworkers']
|
storages: ['serviceworkers']
|
||||||
}, () => done())
|
}, () => done())
|
||||||
}
|
}
|
||||||
@@ -208,6 +213,26 @@ describe('chromium feature', () => {
|
|||||||
b = window.open(`file://${fixtures}/pages/window-open-size.html`, '', 'show=no')
|
b = window.open(`file://${fixtures}/pages/window-open-size.html`, '', 'show=no')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
for (const show of [true, false]) {
|
||||||
|
it(`inherits parent visibility over parent {show=${show}} option`, (done) => {
|
||||||
|
const w = new BrowserWindow({show})
|
||||||
|
|
||||||
|
// toggle visibility
|
||||||
|
if (show) {
|
||||||
|
w.hide()
|
||||||
|
} else {
|
||||||
|
w.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
w.webContents.once('new-window', (e, url, frameName, disposition, options) => {
|
||||||
|
assert.equal(options.show, w.isVisible())
|
||||||
|
w.close()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
w.loadURL(`file://${fixtures}/pages/window-open.html`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
it('disables node integration when it is disabled on the parent window', (done) => {
|
it('disables node integration when it is disabled on the parent window', (done) => {
|
||||||
let b
|
let b
|
||||||
listener = (event) => {
|
listener = (event) => {
|
||||||
@@ -228,6 +253,26 @@ describe('chromium feature', () => {
|
|||||||
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
|
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('disables webviewTag when node integration is disabled on the parent window', (done) => {
|
||||||
|
let b
|
||||||
|
listener = (event) => {
|
||||||
|
assert.equal(event.data.isWebViewUndefined, true)
|
||||||
|
b.close()
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
window.addEventListener('message', listener)
|
||||||
|
|
||||||
|
const windowUrl = require('url').format({
|
||||||
|
pathname: `${fixtures}/pages/window-opener-no-web-view-tag.html`,
|
||||||
|
protocol: 'file',
|
||||||
|
query: {
|
||||||
|
p: `${fixtures}/pages/window-opener-web-view.html`
|
||||||
|
},
|
||||||
|
slashes: true
|
||||||
|
})
|
||||||
|
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
|
||||||
|
})
|
||||||
|
|
||||||
it('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => {
|
it('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => {
|
||||||
let b
|
let b
|
||||||
app.once('web-contents-created', (event, contents) => {
|
app.once('web-contents-created', (event, contents) => {
|
||||||
@@ -247,7 +292,7 @@ describe('chromium feature', () => {
|
|||||||
app.once('web-contents-created', (event, contents) => {
|
app.once('web-contents-created', (event, contents) => {
|
||||||
contents.once('did-finish-load', () => {
|
contents.once('did-finish-load', () => {
|
||||||
app.once('browser-window-created', (event, window) => {
|
app.once('browser-window-created', (event, window) => {
|
||||||
const preferences = window.webContents.getWebPreferences()
|
const preferences = window.webContents.getLastWebPreferences()
|
||||||
assert.equal(preferences.javascript, false)
|
assert.equal(preferences.javascript, false)
|
||||||
window.destroy()
|
window.destroy()
|
||||||
b.close()
|
b.close()
|
||||||
@@ -469,7 +514,7 @@ describe('chromium feature', () => {
|
|||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
window.addEventListener('message', listener)
|
window.addEventListener('message', listener)
|
||||||
w = window.open(url, '', 'show=no')
|
w = window.open(url, '', 'show=no,nodeIntegration=no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('works when origin matches', (done) => {
|
it('works when origin matches', (done) => {
|
||||||
@@ -478,7 +523,7 @@ describe('chromium feature', () => {
|
|||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
window.addEventListener('message', listener)
|
window.addEventListener('message', listener)
|
||||||
w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no')
|
w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no,nodeIntegration=no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('works when origin does not match opener but has node integration', (done) => {
|
it('works when origin does not match opener but has node integration', (done) => {
|
||||||
|
|||||||
15
spec/fixtures/pages/window-opener-no-web-view-tag.html
vendored
Normal file
15
spec/fixtures/pages/window-opener-no-web-view-tag.html
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
var windowUrl = decodeURIComponent(window.location.search.substring(3))
|
||||||
|
var opened = window.open('file://' + windowUrl, '', 'webviewTag=yes,show=no')
|
||||||
|
window.addEventListener('message', function (event) {
|
||||||
|
try {
|
||||||
|
opened.close()
|
||||||
|
} finally {
|
||||||
|
window.opener.postMessage(event.data, '*')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
9
spec/fixtures/pages/window-opener-web-view.html
vendored
Normal file
9
spec/fixtures/pages/window-opener-web-view.html
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
window.onload = () => {
|
||||||
|
window.opener.postMessage({isWebViewUndefined: typeof WebView === 'undefined'}, '*')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user