mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
63 Commits
refactor/a
...
v2.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1b19140e5 | ||
|
|
4632ade7ae | ||
|
|
b32f332ce3 | ||
|
|
6ff0d744ee | ||
|
|
37cbf5e4f1 | ||
|
|
f48f486412 | ||
|
|
018b676efd | ||
|
|
c9e5d17950 | ||
|
|
b1dd013425 | ||
|
|
7a91c5668f | ||
|
|
2f47b71211 | ||
|
|
e8a7cc576e | ||
|
|
c00b1ac669 | ||
|
|
c4bde8853f | ||
|
|
ab77b55a90 | ||
|
|
05b0948dd0 | ||
|
|
c9e2140bca | ||
|
|
9843ce743e | ||
|
|
c846f677c9 | ||
|
|
643dd55e07 | ||
|
|
d2045b93b7 | ||
|
|
c22d53be5c | ||
|
|
e9d28f9b14 | ||
|
|
7e53a4c72c | ||
|
|
515fbb6fc3 | ||
|
|
af4dfcf6fe | ||
|
|
176abdbd80 | ||
|
|
cda7b8ccc8 | ||
|
|
1a43ba50b6 | ||
|
|
1174fc0ab8 | ||
|
|
3c5ba35d63 | ||
|
|
0f143fdba0 | ||
|
|
99ae56b782 | ||
|
|
5471bc313f | ||
|
|
b0077241ee | ||
|
|
bb40bc4aca | ||
|
|
76fb7ee87c | ||
|
|
bfc0e3f266 | ||
|
|
48e068997b | ||
|
|
f443974f3d | ||
|
|
36505ae00e | ||
|
|
b330ff8004 | ||
|
|
6cda9460ea | ||
|
|
2cac654974 | ||
|
|
5a210f3d7a | ||
|
|
4bb10c10e4 | ||
|
|
c0076d9c52 | ||
|
|
95539c5b63 | ||
|
|
4f8ca2f03a | ||
|
|
c9b92aebd3 | ||
|
|
6d3f60374e | ||
|
|
8703298e9d | ||
|
|
a42057aabd | ||
|
|
bd2ab27c25 | ||
|
|
1e6d7295cf | ||
|
|
1918da7c2e | ||
|
|
38345c7267 | ||
|
|
c4742df1ee | ||
|
|
5fc485043b | ||
|
|
967dcd3471 | ||
|
|
96f800552c | ||
|
|
afcbb589b6 | ||
|
|
4159103467 |
@@ -3,7 +3,7 @@ version: 2
|
|||||||
jobs:
|
jobs:
|
||||||
electron-linux-arm:
|
electron-linux-arm:
|
||||||
docker:
|
docker:
|
||||||
- image: electronbuilds/electron:0.0.4
|
- image: electronbuilds/electron:0.0.7
|
||||||
environment:
|
environment:
|
||||||
TARGET_ARCH: arm
|
TARGET_ARCH: arm
|
||||||
resource_class: 2xlarge
|
resource_class: 2xlarge
|
||||||
@@ -58,6 +58,25 @@ jobs:
|
|||||||
else
|
else
|
||||||
echo 'Skipping upload distribution because build is not for release'
|
echo 'Skipping upload distribution because build is not for release'
|
||||||
fi
|
fi
|
||||||
|
- run:
|
||||||
|
name: Optionally finish release
|
||||||
|
shell: /bin/sh
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then
|
||||||
|
echo 'Trying to finish release'
|
||||||
|
node script/release.js --automaticRelease
|
||||||
|
releaseExitCode=$?
|
||||||
|
if [ $releaseExitCode -eq 0 ]; then
|
||||||
|
echo 'Release successful, now publishing to npm'
|
||||||
|
echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc
|
||||||
|
npm run publish-to-npm
|
||||||
|
echo 'Release has been published to npm'
|
||||||
|
else
|
||||||
|
echo 'Release is not complete, skipping publish for now'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'Skipping finishing release because build is not for release'
|
||||||
|
fi
|
||||||
- run:
|
- run:
|
||||||
name: Zip out directory
|
name: Zip out directory
|
||||||
command: |
|
command: |
|
||||||
@@ -83,7 +102,7 @@ jobs:
|
|||||||
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||||
docker run -it \
|
docker run -it \
|
||||||
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
||||||
--rm electronbuilds/electronarm7:0.0.4 > version.txt
|
--rm electronbuilds/electronarm7:0.0.5 > version.txt
|
||||||
cat version.txt
|
cat version.txt
|
||||||
if grep -q `script/get-version.py` version.txt; then
|
if grep -q `script/get-version.py` version.txt; then
|
||||||
echo "Versions match"
|
echo "Versions match"
|
||||||
@@ -96,7 +115,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
electron-linux-arm64:
|
electron-linux-arm64:
|
||||||
docker:
|
docker:
|
||||||
- image: electronbuilds/electron:0.0.4
|
- image: electronbuilds/electron:0.0.7
|
||||||
environment:
|
environment:
|
||||||
TARGET_ARCH: arm64
|
TARGET_ARCH: arm64
|
||||||
resource_class: 2xlarge
|
resource_class: 2xlarge
|
||||||
@@ -151,6 +170,25 @@ jobs:
|
|||||||
else
|
else
|
||||||
echo 'Skipping upload distribution because build is not for release'
|
echo 'Skipping upload distribution because build is not for release'
|
||||||
fi
|
fi
|
||||||
|
- run:
|
||||||
|
name: Optionally finish release
|
||||||
|
shell: /bin/sh
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then
|
||||||
|
echo 'Trying to finish release'
|
||||||
|
node script/release.js --automaticRelease
|
||||||
|
releaseExitCode=$?
|
||||||
|
if [ $releaseExitCode -eq 0 ]; then
|
||||||
|
echo 'Release successful, now publishing to npm'
|
||||||
|
echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc
|
||||||
|
npm run publish-to-npm
|
||||||
|
echo 'Release has been published to npm'
|
||||||
|
else
|
||||||
|
echo 'Release is not complete, skipping publish for now'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'Skipping finishing release because build is not for release'
|
||||||
|
fi
|
||||||
- run:
|
- run:
|
||||||
name: Zip out directory
|
name: Zip out directory
|
||||||
command: |
|
command: |
|
||||||
@@ -176,7 +214,7 @@ jobs:
|
|||||||
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||||
docker run -it \
|
docker run -it \
|
||||||
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
||||||
--rm electronbuilds/electronarm64:0.0.5 > version.txt
|
--rm electronbuilds/electronarm64:0.0.6 > version.txt
|
||||||
cat version.txt
|
cat version.txt
|
||||||
if grep -q `script/get-version.py` version.txt; then
|
if grep -q `script/get-version.py` version.txt; then
|
||||||
echo "Versions match"
|
echo "Versions match"
|
||||||
@@ -189,7 +227,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
electron-linux-ia32:
|
electron-linux-ia32:
|
||||||
docker:
|
docker:
|
||||||
- image: electronbuilds/electron:0.0.4
|
- image: electronbuilds/electron:0.0.7
|
||||||
environment:
|
environment:
|
||||||
TARGET_ARCH: ia32
|
TARGET_ARCH: ia32
|
||||||
DISPLAY: ':99.0'
|
DISPLAY: ':99.0'
|
||||||
@@ -248,6 +286,25 @@ jobs:
|
|||||||
else
|
else
|
||||||
echo 'Skipping upload distribution because build is not for release'
|
echo 'Skipping upload distribution because build is not for release'
|
||||||
fi
|
fi
|
||||||
|
- run:
|
||||||
|
name: Optionally finish release
|
||||||
|
shell: /bin/sh
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then
|
||||||
|
echo 'Trying to finish release'
|
||||||
|
node script/release.js --automaticRelease
|
||||||
|
releaseExitCode=$?
|
||||||
|
if [ $releaseExitCode -eq 0 ]; then
|
||||||
|
echo 'Release successful, now publishing to npm'
|
||||||
|
echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc
|
||||||
|
npm run publish-to-npm
|
||||||
|
echo 'Release has been published to npm'
|
||||||
|
else
|
||||||
|
echo 'Release is not complete, skipping publish for now'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'Skipping finishing release because build is not for release'
|
||||||
|
fi
|
||||||
- run:
|
- run:
|
||||||
name: Test
|
name: Test
|
||||||
environment:
|
environment:
|
||||||
@@ -273,7 +330,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
electron-linux-mips64el:
|
electron-linux-mips64el:
|
||||||
docker:
|
docker:
|
||||||
- image: electronbuilds/electron:0.0.4
|
- image: electronbuilds/electron:0.0.7
|
||||||
environment:
|
environment:
|
||||||
TARGET_ARCH: mips64el
|
TARGET_ARCH: mips64el
|
||||||
resource_class: xlarge
|
resource_class: xlarge
|
||||||
@@ -328,10 +385,29 @@ jobs:
|
|||||||
else
|
else
|
||||||
echo 'Skipping upload distribution because build is not for release'
|
echo 'Skipping upload distribution because build is not for release'
|
||||||
fi
|
fi
|
||||||
|
- run:
|
||||||
|
name: Optionally finish release
|
||||||
|
shell: /bin/sh
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then
|
||||||
|
echo 'Trying to finish release'
|
||||||
|
node script/release.js --automaticRelease
|
||||||
|
releaseExitCode=$?
|
||||||
|
if [ $releaseExitCode -eq 0 ]; then
|
||||||
|
echo 'Release successful, now publishing to npm'
|
||||||
|
echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc
|
||||||
|
npm run publish-to-npm
|
||||||
|
echo 'Release has been published to npm'
|
||||||
|
else
|
||||||
|
echo 'Release is not complete, skipping publish for now'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'Skipping finishing release because build is not for release'
|
||||||
|
fi
|
||||||
|
|
||||||
electron-linux-x64:
|
electron-linux-x64:
|
||||||
docker:
|
docker:
|
||||||
- image: electronbuilds/electron:0.0.4
|
- image: electronbuilds/electron:0.0.7
|
||||||
environment:
|
environment:
|
||||||
TARGET_ARCH: x64
|
TARGET_ARCH: x64
|
||||||
DISPLAY: ':99.0'
|
DISPLAY: ':99.0'
|
||||||
@@ -390,6 +466,25 @@ jobs:
|
|||||||
else
|
else
|
||||||
echo 'Skipping upload distribution because build is not for release'
|
echo 'Skipping upload distribution because build is not for release'
|
||||||
fi
|
fi
|
||||||
|
- run:
|
||||||
|
name: Optionally finish release
|
||||||
|
shell: /bin/sh
|
||||||
|
command: |
|
||||||
|
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$AUTO_RELEASE" == "true" ]; then
|
||||||
|
echo 'Trying to finish release'
|
||||||
|
node script/release.js --automaticRelease
|
||||||
|
releaseExitCode=$?
|
||||||
|
if [ $releaseExitCode -eq 0 ]; then
|
||||||
|
echo 'Release successful, now publishing to npm'
|
||||||
|
echo "//registry.npmjs.org/:_authToken=$ELECTRON_NPM_TOKEN" >> ~/.npmrc
|
||||||
|
npm run publish-to-npm
|
||||||
|
echo 'Release has been published to npm'
|
||||||
|
else
|
||||||
|
echo 'Release is not complete, skipping publish for now'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'Skipping finishing release because build is not for release'
|
||||||
|
fi
|
||||||
- run:
|
- run:
|
||||||
name: Test
|
name: Test
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
@@ -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 nodejs
|
RUN apt-get update && apt-get install -y nodejs
|
||||||
|
|
||||||
# Install wget used by crash reporter
|
# Install wget used by crash reporter
|
||||||
@@ -16,6 +16,9 @@ RUN apt-get install -y wget
|
|||||||
# Install python-dbusmock
|
# Install python-dbusmock
|
||||||
RUN apt-get install -y python-dbusmock
|
RUN apt-get install -y python-dbusmock
|
||||||
|
|
||||||
|
# Install libnotify
|
||||||
|
RUN apt-get install -y libnotify-bin
|
||||||
|
|
||||||
# Add xvfb init script
|
# Add xvfb init script
|
||||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||||
RUN chmod a+x /etc/init.d/xvfb
|
RUN chmod a+x /etc/init.d/xvfb
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y\
|
|||||||
libgnome-keyring-dev \
|
libgnome-keyring-dev \
|
||||||
libgtk-3-0 \
|
libgtk-3-0 \
|
||||||
libgtk-3-dev \
|
libgtk-3-dev \
|
||||||
|
libnotify-bin \
|
||||||
libnotify-dev \
|
libnotify-dev \
|
||||||
libnss3 \
|
libnss3 \
|
||||||
libnss3-dev \
|
libnss3-dev \
|
||||||
|
|||||||
63
Dockerfile.arm64v8
Normal file
63
Dockerfile.arm64v8
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
FROM arm64v8/ubuntu:16.04
|
||||||
|
|
||||||
|
RUN groupadd --gid 1000 builduser \
|
||||||
|
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||||
|
|
||||||
|
RUN groupadd --gid 114 jenkins \
|
||||||
|
&& useradd --uid 110 --gid jenkins --shell /bin/bash --create-home jenkins
|
||||||
|
|
||||||
|
# Set up TEMP directory
|
||||||
|
ENV TEMP=/tmp
|
||||||
|
RUN chmod a+rwx /tmp
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y\
|
||||||
|
bison \
|
||||||
|
build-essential \
|
||||||
|
clang \
|
||||||
|
curl \
|
||||||
|
gperf \
|
||||||
|
git \
|
||||||
|
libasound2 \
|
||||||
|
libasound2-dev \
|
||||||
|
libcap-dev \
|
||||||
|
libcups2-dev \
|
||||||
|
libdbus-1-dev \
|
||||||
|
libgconf-2-4 \
|
||||||
|
libgconf2-dev \
|
||||||
|
libgnome-keyring-dev \
|
||||||
|
libgtk2.0-0 \
|
||||||
|
libgtk2.0-dev \
|
||||||
|
libgtk-3-0 \
|
||||||
|
libgtk-3-dev \
|
||||||
|
libnotify-dev \
|
||||||
|
libnss3 \
|
||||||
|
libnss3-dev \
|
||||||
|
libx11-xcb-dev \
|
||||||
|
libxss1 \
|
||||||
|
libxtst-dev \
|
||||||
|
libxtst6 \
|
||||||
|
lsb-release \
|
||||||
|
locales \
|
||||||
|
ninja \
|
||||||
|
python-setuptools \
|
||||||
|
python-pip \
|
||||||
|
python-dbusmock \
|
||||||
|
wget \
|
||||||
|
xvfb
|
||||||
|
|
||||||
|
# Install node.js
|
||||||
|
RUN curl -sL https://deb.nodesource.com/setup_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
|
||||||
@@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y\
|
|||||||
libgnome-keyring-dev \
|
libgnome-keyring-dev \
|
||||||
libgtk-3-0 \
|
libgtk-3-0 \
|
||||||
libgtk-3-dev \
|
libgtk-3-dev \
|
||||||
|
libnotify-bin \
|
||||||
libnotify-dev \
|
libnotify-dev \
|
||||||
libnss3 \
|
libnss3 \
|
||||||
libnss3-dev \
|
libnss3-dev \
|
||||||
|
|||||||
@@ -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 nodejs
|
RUN apt-get update && apt-get install -y nodejs
|
||||||
|
|
||||||
# Install wget used by crash reporter
|
# Install wget used by crash reporter
|
||||||
@@ -12,6 +12,9 @@ RUN apt-get install -y wget
|
|||||||
# Install python-dbusmock
|
# Install python-dbusmock
|
||||||
RUN apt-get install -y python-dbusmock
|
RUN apt-get install -y python-dbusmock
|
||||||
|
|
||||||
|
# Install libnotify
|
||||||
|
RUN apt-get install -y libnotify-bin
|
||||||
|
|
||||||
# Add xvfb init script
|
# Add xvfb init script
|
||||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||||
RUN chmod a+x /etc/init.d/xvfb
|
RUN chmod a+x /etc/init.d/xvfb
|
||||||
|
|||||||
36
Jenkinsfile.arm64
Normal file
36
Jenkinsfile.arm64
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
pipeline {
|
||||||
|
agent {
|
||||||
|
docker {
|
||||||
|
image 'electronbuilds/arm64v8:0.0.1'
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,7 +21,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.
|
||||||
|
|
||||||
|
|||||||
@@ -23,20 +23,16 @@ MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
|||||||
|
|
||||||
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item,
|
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item,
|
||||||
const base::Closure& callback) {
|
const base::Closure& callback) {
|
||||||
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
|
auto* native_window = static_cast<NativeWindowViews*>(window->window());
|
||||||
if (!native_window)
|
if (!native_window)
|
||||||
return;
|
return;
|
||||||
auto* web_contents = native_window->inspectable_web_contents();
|
|
||||||
if (!web_contents)
|
|
||||||
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 {
|
||||||
auto* view = web_contents->GetView()->GetWebView();
|
gfx::Point origin = native_window->GetContentBounds().origin();
|
||||||
gfx::Point origin = view->bounds().origin();
|
|
||||||
location = gfx::Point(origin.x() + x, origin.y() + y);
|
location = gfx::Point(origin.x() + x, origin.y() + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +48,7 @@ void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item,
|
|||||||
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));
|
||||||
menu_runners_[window_id]->RunMenuAt(
|
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,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace atom {
|
|||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
|
//TODO(codebytere): deprecated; remove in 3.0
|
||||||
int Screen::getMenuBarHeight() {
|
int Screen::getMenuBarHeight() {
|
||||||
return [[NSApp mainMenu] menuBarHeight];
|
return [[NSApp mainMenu] menuBarHeight];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -441,13 +441,14 @@ void DownloadIdCallback(content::DownloadManager* download_manager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetDevToolsNetworkEmulationClientIdInIO(
|
void SetDevToolsNetworkEmulationClientIdInIO(
|
||||||
brightray::URLRequestContextGetter* context_getter,
|
brightray::URLRequestContextGetter* url_request_context_getter,
|
||||||
const std::string& client_id) {
|
const std::string& client_id) {
|
||||||
if (!context_getter)
|
if (!url_request_context_getter)
|
||||||
return;
|
return;
|
||||||
auto network_delegate =
|
net::URLRequestContext* context =
|
||||||
static_cast<AtomNetworkDelegate*>(context_getter->network_delegate());
|
url_request_context_getter->GetURLRequestContext();
|
||||||
if (network_delegate)
|
AtomNetworkDelegate* network_delegate =
|
||||||
|
static_cast<AtomNetworkDelegate*>(context->network_delegate());
|
||||||
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
|
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -277,6 +277,27 @@ void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
struct WebContents::FrameDispatchHelper {
|
||||||
|
WebContents* api_web_contents;
|
||||||
|
content::RenderFrameHost* rfh;
|
||||||
|
|
||||||
|
bool Send(IPC::Message* msg) { return rfh->Send(msg); }
|
||||||
|
|
||||||
|
void OnSetTemporaryZoomLevel(double level, IPC::Message* reply_msg) {
|
||||||
|
api_web_contents->OnSetTemporaryZoomLevel(rfh, level, reply_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGetZoomLevel(IPC::Message* reply_msg) {
|
||||||
|
api_web_contents->OnGetZoomLevel(rfh, reply_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnRendererMessageSync(const base::string16& channel,
|
||||||
|
const base::ListValue& args,
|
||||||
|
IPC::Message* message) {
|
||||||
|
api_web_contents->OnRendererMessageSync(rfh, channel, args, message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
WebContents::WebContents(v8::Isolate* isolate,
|
WebContents::WebContents(v8::Isolate* isolate,
|
||||||
content::WebContents* web_contents,
|
content::WebContents* web_contents,
|
||||||
Type type)
|
Type type)
|
||||||
@@ -923,13 +944,6 @@ void WebContents::ShowAutofillPopup(content::RenderFrameHost* frame_host,
|
|||||||
bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||||
bool handled = true;
|
bool handled = true;
|
||||||
IPC_BEGIN_MESSAGE_MAP(WebContents, message)
|
IPC_BEGIN_MESSAGE_MAP(WebContents, message)
|
||||||
IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
|
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
|
|
||||||
OnRendererMessageSync)
|
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_SetTemporaryZoomLevel,
|
|
||||||
OnSetTemporaryZoomLevel)
|
|
||||||
IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_GetZoomLevel,
|
|
||||||
OnGetZoomLevel)
|
|
||||||
IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
|
IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
|
||||||
handled = false)
|
handled = false)
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
@@ -941,17 +955,28 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
|||||||
bool WebContents::OnMessageReceived(const IPC::Message& message,
|
bool WebContents::OnMessageReceived(const IPC::Message& message,
|
||||||
content::RenderFrameHost* frame_host) {
|
content::RenderFrameHost* frame_host) {
|
||||||
bool handled = true;
|
bool handled = true;
|
||||||
|
FrameDispatchHelper helper = {this, frame_host};
|
||||||
auto relay = NativeWindowRelay::FromWebContents(web_contents());
|
auto relay = NativeWindowRelay::FromWebContents(web_contents());
|
||||||
if (!relay)
|
if (relay) {
|
||||||
return false;
|
|
||||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host)
|
|
||||||
IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup)
|
|
||||||
IPC_END_MESSAGE_MAP()
|
|
||||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host)
|
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, frame_host)
|
||||||
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup,
|
IPC_MESSAGE_FORWARD(AtomAutofillFrameHostMsg_HidePopup,
|
||||||
relay->window.get(), NativeWindow::HideAutofillPopup)
|
relay->window.get(), NativeWindow::HideAutofillPopup)
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
IPC_END_MESSAGE_MAP()
|
IPC_END_MESSAGE_MAP()
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(WebContents, message, frame_host)
|
||||||
|
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_Message, OnRendererMessage)
|
||||||
|
IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_Message_Sync, &helper,
|
||||||
|
FrameDispatchHelper::OnRendererMessageSync)
|
||||||
|
IPC_MESSAGE_FORWARD_DELAY_REPLY(
|
||||||
|
AtomFrameHostMsg_SetTemporaryZoomLevel, &helper,
|
||||||
|
FrameDispatchHelper::OnSetTemporaryZoomLevel)
|
||||||
|
IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_GetZoomLevel, &helper,
|
||||||
|
FrameDispatchHelper::OnGetZoomLevel)
|
||||||
|
IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup)
|
||||||
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
|
IPC_END_MESSAGE_MAP()
|
||||||
|
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
@@ -1468,7 +1493,12 @@ void WebContents::TabTraverse(bool reverse) {
|
|||||||
bool WebContents::SendIPCMessage(bool all_frames,
|
bool WebContents::SendIPCMessage(bool all_frames,
|
||||||
const base::string16& channel,
|
const base::string16& channel,
|
||||||
const base::ListValue& args) {
|
const base::ListValue& args) {
|
||||||
return Send(new AtomViewMsg_Message(routing_id(), all_frames, channel, args));
|
auto frame_host = web_contents()->GetMainFrame();
|
||||||
|
if (frame_host) {
|
||||||
|
return frame_host->Send(new AtomFrameMsg_Message(
|
||||||
|
frame_host->GetRoutingID(), all_frames, channel, args));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::SendInputEvent(v8::Isolate* isolate,
|
void WebContents::SendInputEvent(v8::Isolate* isolate,
|
||||||
@@ -1752,25 +1782,38 @@ double WebContents::GetZoomFactor() {
|
|||||||
return content::ZoomLevelToZoomFactor(level);
|
return content::ZoomLevelToZoomFactor(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::OnSetTemporaryZoomLevel(double level,
|
void WebContents::OnSetTemporaryZoomLevel(content::RenderFrameHost* rfh,
|
||||||
|
double level,
|
||||||
IPC::Message* reply_msg) {
|
IPC::Message* reply_msg) {
|
||||||
zoom_controller_->SetTemporaryZoomLevel(level);
|
zoom_controller_->SetTemporaryZoomLevel(level);
|
||||||
double new_level = zoom_controller_->GetZoomLevel();
|
double new_level = zoom_controller_->GetZoomLevel();
|
||||||
AtomViewHostMsg_SetTemporaryZoomLevel::WriteReplyParams(reply_msg, new_level);
|
AtomFrameHostMsg_SetTemporaryZoomLevel::WriteReplyParams(reply_msg,
|
||||||
Send(reply_msg);
|
new_level);
|
||||||
|
rfh->Send(reply_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::OnGetZoomLevel(IPC::Message* reply_msg) {
|
void WebContents::OnGetZoomLevel(content::RenderFrameHost* rfh,
|
||||||
AtomViewHostMsg_GetZoomLevel::WriteReplyParams(reply_msg, GetZoomLevel());
|
IPC::Message* reply_msg) {
|
||||||
Send(reply_msg);
|
AtomFrameHostMsg_GetZoomLevel::WriteReplyParams(reply_msg, GetZoomLevel());
|
||||||
|
rfh->Send(reply_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
|
v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
|
||||||
WebContentsPreferences* web_preferences =
|
WebContentsPreferences* web_preferences =
|
||||||
WebContentsPreferences::FromWebContents(web_contents());
|
WebContentsPreferences::FromWebContents(web_contents());
|
||||||
|
if (!web_preferences)
|
||||||
|
return v8::Null(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());
|
||||||
@@ -1922,6 +1965,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",
|
||||||
@@ -1955,17 +1999,19 @@ AtomBrowserContext* WebContents::GetBrowserContext() const {
|
|||||||
return static_cast<AtomBrowserContext*>(web_contents()->GetBrowserContext());
|
return static_cast<AtomBrowserContext*>(web_contents()->GetBrowserContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::OnRendererMessage(const base::string16& channel,
|
void WebContents::OnRendererMessage(content::RenderFrameHost* frame_host,
|
||||||
|
const base::string16& channel,
|
||||||
const base::ListValue& args) {
|
const base::ListValue& args) {
|
||||||
// webContents.emit(channel, new Event(), args...);
|
// webContents.emit(channel, new Event(), args...);
|
||||||
Emit(base::UTF16ToUTF8(channel), args);
|
Emit(base::UTF16ToUTF8(channel), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContents::OnRendererMessageSync(const base::string16& channel,
|
void WebContents::OnRendererMessageSync(content::RenderFrameHost* frame_host,
|
||||||
|
const base::string16& channel,
|
||||||
const base::ListValue& args,
|
const base::ListValue& args,
|
||||||
IPC::Message* message) {
|
IPC::Message* message) {
|
||||||
// webContents.emit(channel, new Event(sender, message), args...);
|
// webContents.emit(channel, new Event(sender, message), args...);
|
||||||
EmitWithSender(base::UTF16ToUTF8(channel), web_contents(), message, args);
|
EmitWithSender(base::UTF16ToUTF8(channel), frame_host, message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|||||||
@@ -214,6 +214,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();
|
||||||
@@ -367,6 +368,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
|||||||
const std::vector<base::string16>& labels);
|
const std::vector<base::string16>& labels);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct FrameDispatchHelper;
|
||||||
AtomBrowserContext* GetBrowserContext() const;
|
AtomBrowserContext* GetBrowserContext() const;
|
||||||
|
|
||||||
uint32_t GetNextRequestId() {
|
uint32_t GetNextRequestId() {
|
||||||
@@ -377,21 +379,26 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
|||||||
void OnCursorChange(const content::WebCursor& cursor);
|
void OnCursorChange(const content::WebCursor& cursor);
|
||||||
|
|
||||||
// Called when received a message from renderer.
|
// Called when received a message from renderer.
|
||||||
void OnRendererMessage(const base::string16& channel,
|
void OnRendererMessage(content::RenderFrameHost* frame_host,
|
||||||
|
const base::string16& channel,
|
||||||
const base::ListValue& args);
|
const base::ListValue& args);
|
||||||
|
|
||||||
// Called when received a synchronous message from renderer.
|
// Called when received a synchronous message from renderer.
|
||||||
void OnRendererMessageSync(const base::string16& channel,
|
void OnRendererMessageSync(content::RenderFrameHost* frame_host,
|
||||||
|
const base::string16& channel,
|
||||||
const base::ListValue& args,
|
const base::ListValue& args,
|
||||||
IPC::Message* message);
|
IPC::Message* message);
|
||||||
|
|
||||||
// Called when received a synchronous message from renderer to
|
// Called when received a synchronous message from renderer to
|
||||||
// set temporary zoom level.
|
// set temporary zoom level.
|
||||||
void OnSetTemporaryZoomLevel(double level, IPC::Message* reply_msg);
|
void OnSetTemporaryZoomLevel(content::RenderFrameHost* frame_host,
|
||||||
|
double level,
|
||||||
|
IPC::Message* reply_msg);
|
||||||
|
|
||||||
// Called when received a synchronous message from renderer to
|
// Called when received a synchronous message from renderer to
|
||||||
// get the zoom level.
|
// get the zoom level.
|
||||||
void OnGetZoomLevel(IPC::Message* reply_msg);
|
void OnGetZoomLevel(content::RenderFrameHost* frame_host,
|
||||||
|
IPC::Message* reply_msg);
|
||||||
|
|
||||||
void InitZoomController(content::WebContents* web_contents,
|
void InitZoomController(content::WebContents* web_contents,
|
||||||
const mate::Dictionary& options);
|
const mate::Dictionary& options);
|
||||||
|
|||||||
@@ -37,6 +37,26 @@ namespace atom {
|
|||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template<typename Method, typename Event, typename Listener>
|
||||||
|
void CallNetworkDelegateMethod(
|
||||||
|
brightray::URLRequestContextGetter* url_request_context_getter,
|
||||||
|
Method method,
|
||||||
|
Event type,
|
||||||
|
URLPatterns patterns,
|
||||||
|
Listener listener) {
|
||||||
|
// Force creating network delegate.
|
||||||
|
net::URLRequestContext* context =
|
||||||
|
url_request_context_getter->GetURLRequestContext();
|
||||||
|
// Then call the method.
|
||||||
|
AtomNetworkDelegate* network_delegate =
|
||||||
|
static_cast<AtomNetworkDelegate*>(context->network_delegate());
|
||||||
|
(network_delegate->*method)(type, std::move(patterns), std::move(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
WebRequest::WebRequest(v8::Isolate* isolate,
|
WebRequest::WebRequest(v8::Isolate* isolate,
|
||||||
AtomBrowserContext* browser_context)
|
AtomBrowserContext* browser_context)
|
||||||
: browser_context_(browser_context) {
|
: browser_context_(browser_context) {
|
||||||
@@ -74,16 +94,15 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto url_request_context_getter =
|
brightray::URLRequestContextGetter* url_request_context_getter =
|
||||||
browser_context_->url_request_context_getter();
|
browser_context_->url_request_context_getter();
|
||||||
if (!url_request_context_getter)
|
if (!url_request_context_getter)
|
||||||
return;
|
return;
|
||||||
BrowserThread::PostTask(
|
BrowserThread::PostTask(
|
||||||
BrowserThread::IO, FROM_HERE,
|
BrowserThread::IO, FROM_HERE,
|
||||||
base::Bind(method,
|
base::Bind(&CallNetworkDelegateMethod<Method, Event, Listener>,
|
||||||
base::Unretained(static_cast<AtomNetworkDelegate*>(
|
base::RetainedRef(url_request_context_getter),
|
||||||
url_request_context_getter->network_delegate())),
|
method, type, std::move(patterns), std::move(listener)));
|
||||||
type, patterns, listener));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|||||||
@@ -952,8 +952,11 @@ void Window::ToggleTabBar() {
|
|||||||
window_->ToggleTabBar();
|
window_->ToggleTabBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::AddTabbedWindow(NativeWindow* window) {
|
void Window::AddTabbedWindow(NativeWindow* window,
|
||||||
window_->AddTabbedWindow(window);
|
mate::Arguments* args) {
|
||||||
|
const bool windowAdded = window_->AddTabbedWindow(window);
|
||||||
|
if (!windowAdded)
|
||||||
|
args->ThrowError("AddTabbedWindow cannot be called by a window on itself.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::SetVibrancy(mate::Arguments* args) {
|
void Window::SetVibrancy(mate::Arguments* args) {
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ class Window : public mate::TrackableObject<Window>,
|
|||||||
void MergeAllWindows();
|
void MergeAllWindows();
|
||||||
void MoveTabToNewWindow();
|
void MoveTabToNewWindow();
|
||||||
void ToggleTabBar();
|
void ToggleTabBar();
|
||||||
void AddTabbedWindow(NativeWindow* window);
|
void AddTabbedWindow(NativeWindow* window, mate::Arguments* args);
|
||||||
|
|
||||||
void SetVibrancy(mate::Arguments* args);
|
void SetVibrancy(mate::Arguments* args);
|
||||||
void SetTouchBar(const std::vector<mate::PersistentDictionary>& items);
|
void SetTouchBar(const std::vector<mate::PersistentDictionary>& items);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "atom/common/api/api_messages.h"
|
#include "atom/common/api/api_messages.h"
|
||||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||||
|
#include "content/public/browser/render_frame_host.h"
|
||||||
#include "content/public/browser/web_contents.h"
|
#include "content/public/browser/web_contents.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
|
|
||||||
@@ -20,17 +21,32 @@ Event::Event(v8::Isolate* isolate)
|
|||||||
Event::~Event() {
|
Event::~Event() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Event::SetSenderAndMessage(content::WebContents* sender,
|
void Event::SetSenderAndMessage(content::RenderFrameHost* sender,
|
||||||
IPC::Message* message) {
|
IPC::Message* message) {
|
||||||
DCHECK(!sender_);
|
DCHECK(!sender_);
|
||||||
DCHECK(!message_);
|
DCHECK(!message_);
|
||||||
sender_ = sender;
|
sender_ = sender;
|
||||||
message_ = message;
|
message_ = message;
|
||||||
|
|
||||||
Observe(sender);
|
Observe(content::WebContents::FromRenderFrameHost(sender));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Event::WebContentsDestroyed() {
|
void Event::RenderFrameDeleted(content::RenderFrameHost* rfh) {
|
||||||
|
if (sender_ != rfh)
|
||||||
|
return;
|
||||||
|
sender_ = nullptr;
|
||||||
|
message_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event::RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
|
||||||
|
content::RenderFrameHost* new_rfh) {
|
||||||
|
if (sender_ && sender_ == old_rfh)
|
||||||
|
sender_ = new_rfh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event::FrameDeleted(content::RenderFrameHost* rfh) {
|
||||||
|
if (sender_ != rfh)
|
||||||
|
return;
|
||||||
sender_ = nullptr;
|
sender_ = nullptr;
|
||||||
message_ = nullptr;
|
message_ = nullptr;
|
||||||
}
|
}
|
||||||
@@ -44,7 +60,7 @@ bool Event::SendReply(const base::string16& json) {
|
|||||||
if (message_ == nullptr || sender_ == nullptr)
|
if (message_ == nullptr || sender_ == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json);
|
AtomFrameHostMsg_Message_Sync::WriteReplyParams(message_, json);
|
||||||
bool success = sender_->Send(message_);
|
bool success = sender_->Send(message_);
|
||||||
message_ = nullptr;
|
message_ = nullptr;
|
||||||
sender_ = nullptr;
|
sender_ = nullptr;
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ class Event : public Wrappable<Event>,
|
|||||||
v8::Local<v8::FunctionTemplate> prototype);
|
v8::Local<v8::FunctionTemplate> prototype);
|
||||||
|
|
||||||
// Pass the sender and message to be replied.
|
// Pass the sender and message to be replied.
|
||||||
void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message);
|
void SetSenderAndMessage(content::RenderFrameHost* sender,
|
||||||
|
IPC::Message* message);
|
||||||
|
|
||||||
// event.PreventDefault().
|
// event.PreventDefault().
|
||||||
void PreventDefault(v8::Isolate* isolate);
|
void PreventDefault(v8::Isolate* isolate);
|
||||||
@@ -37,11 +38,14 @@ class Event : public Wrappable<Event>,
|
|||||||
~Event() override;
|
~Event() override;
|
||||||
|
|
||||||
// content::WebContentsObserver implementations:
|
// content::WebContentsObserver implementations:
|
||||||
void WebContentsDestroyed() override;
|
void RenderFrameDeleted(content::RenderFrameHost* rfh) override;
|
||||||
|
void RenderFrameHostChanged(content::RenderFrameHost* old_rfh,
|
||||||
|
content::RenderFrameHost* new_rfh) override;
|
||||||
|
void FrameDeleted(content::RenderFrameHost* rfh) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Replyer for the synchronous messages.
|
// Replyer for the synchronous messages.
|
||||||
content::WebContents* sender_;
|
content::RenderFrameHost* sender_;
|
||||||
IPC::Message* message_;
|
IPC::Message* message_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Event);
|
DISALLOW_COPY_AND_ASSIGN(Event);
|
||||||
|
|||||||
@@ -39,10 +39,9 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
v8::Local<v8::Object> CreateJSEvent(
|
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
||||||
v8::Isolate* isolate,
|
|
||||||
v8::Local<v8::Object> object,
|
v8::Local<v8::Object> object,
|
||||||
content::WebContents* sender,
|
content::RenderFrameHost* sender,
|
||||||
IPC::Message* message) {
|
IPC::Message* message) {
|
||||||
v8::Local<v8::Object> event;
|
v8::Local<v8::Object> event;
|
||||||
bool use_native_event = sender && message;
|
bool use_native_event = sender && message;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "native_mate/wrappable.h"
|
#include "native_mate/wrappable.h"
|
||||||
|
|
||||||
namespace content {
|
namespace content {
|
||||||
class WebContents;
|
class RenderFrameHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
@@ -24,7 +24,7 @@ namespace internal {
|
|||||||
|
|
||||||
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
|
||||||
v8::Local<v8::Object> object,
|
v8::Local<v8::Object> object,
|
||||||
content::WebContents* sender,
|
content::RenderFrameHost* sender,
|
||||||
IPC::Message* message);
|
IPC::Message* message);
|
||||||
v8::Local<v8::Object> CreateCustomEvent(
|
v8::Local<v8::Object> CreateCustomEvent(
|
||||||
v8::Isolate* isolate,
|
v8::Isolate* isolate,
|
||||||
@@ -76,7 +76,7 @@ class EventEmitter : public Wrappable<T> {
|
|||||||
// this.emit(name, new Event(sender, message), args...);
|
// this.emit(name, new Event(sender, message), args...);
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
bool EmitWithSender(const base::StringPiece& name,
|
bool EmitWithSender(const base::StringPiece& name,
|
||||||
content::WebContents* sender,
|
content::RenderFrameHost* sender,
|
||||||
IPC::Message* message,
|
IPC::Message* message,
|
||||||
const Args&... args) {
|
const Args&... args) {
|
||||||
v8::Locker locker(isolate());
|
v8::Locker locker(isolate());
|
||||||
|
|||||||
@@ -108,14 +108,13 @@ void Browser::SetVersion(const std::string& version) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string Browser::GetName() const {
|
std::string Browser::GetName() const {
|
||||||
std::string ret = name_override_;
|
std::string ret = brightray::GetOverriddenApplicationName();
|
||||||
if (ret.empty())
|
if (ret.empty())
|
||||||
ret = GetExecutableFileProductName();
|
ret = GetExecutableFileProductName();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Browser::SetName(const std::string& name) {
|
void Browser::SetName(const std::string& name) {
|
||||||
name_override_ = name;
|
|
||||||
brightray::OverrideApplicationName(name);
|
brightray::OverrideApplicationName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -273,8 +273,6 @@ class Browser : public WindowListObserver {
|
|||||||
// The browser is being shutdown.
|
// The browser is being shutdown.
|
||||||
bool is_shutdown_;
|
bool is_shutdown_;
|
||||||
|
|
||||||
std::string name_override_;
|
|
||||||
|
|
||||||
int badge_count_ = 0;
|
int badge_count_ = 0;
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
|
|||||||
@@ -362,7 +362,8 @@ void NativeWindow::MoveTabToNewWindow() {
|
|||||||
void NativeWindow::ToggleTabBar() {
|
void NativeWindow::ToggleTabBar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindow::AddTabbedWindow(NativeWindow* window) {
|
bool NativeWindow::AddTabbedWindow(NativeWindow* window) {
|
||||||
|
return true; // for non-Mac platforms
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindow::SetVibrancy(const std::string& filename) {
|
void NativeWindow::SetVibrancy(const std::string& filename) {
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ class NativeWindow : public base::SupportsUserData,
|
|||||||
virtual void MergeAllWindows();
|
virtual void MergeAllWindows();
|
||||||
virtual void MoveTabToNewWindow();
|
virtual void MoveTabToNewWindow();
|
||||||
virtual void ToggleTabBar();
|
virtual void ToggleTabBar();
|
||||||
virtual void AddTabbedWindow(NativeWindow* window);
|
virtual bool AddTabbedWindow(NativeWindow* window);
|
||||||
|
|
||||||
// Webview APIs.
|
// Webview APIs.
|
||||||
virtual void FocusOnWebView();
|
virtual void FocusOnWebView();
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ class NativeWindowMac : public NativeWindow,
|
|||||||
void MergeAllWindows() override;
|
void MergeAllWindows() override;
|
||||||
void MoveTabToNewWindow() override;
|
void MoveTabToNewWindow() override;
|
||||||
void ToggleTabBar() override;
|
void ToggleTabBar() override;
|
||||||
void AddTabbedWindow(NativeWindow* window) override;
|
bool AddTabbedWindow(NativeWindow* window) override;
|
||||||
|
|
||||||
void SetVibrancy(const std::string& type) override;
|
void SetVibrancy(const std::string& type) override;
|
||||||
void SetTouchBar(
|
void SetTouchBar(
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "skia/ext/skia_utils_mac.h"
|
#include "skia/ext/skia_utils_mac.h"
|
||||||
#include "third_party/skia/include/core/SkRegion.h"
|
#include "third_party/skia/include/core/SkRegion.h"
|
||||||
#include "ui/gfx/skia_util.h"
|
#include "ui/gfx/skia_util.h"
|
||||||
|
#include "ui/gl/gpu_switching_manager.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -1677,10 +1678,14 @@ void NativeWindowMac::ToggleTabBar() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
|
bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
|
||||||
if ([window_ respondsToSelector:@selector(addTabbedWindow:ordered:)]) {
|
if (window_.get() == window->GetNativeWindow()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if ([window_ respondsToSelector:@selector(addTabbedWindow:ordered:)])
|
||||||
[window_ addTabbedWindow:window->GetNativeWindow() ordered:NSWindowAbove];
|
[window_ addTabbedWindow:window->GetNativeWindow() ordered:NSWindowAbove];
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowMac::SetRenderWidgetHostOpaque(bool opaque) {
|
void NativeWindowMac::SetRenderWidgetHostOpaque(bool opaque) {
|
||||||
@@ -1712,6 +1717,7 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
|||||||
|
|
||||||
[vibrant_view removeFromSuperview];
|
[vibrant_view removeFromSuperview];
|
||||||
[window_ setVibrantView:nil];
|
[window_ setVibrantView:nil];
|
||||||
|
ui::GpuSwitchingManager::SetTransparent(transparent());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1719,9 +1725,12 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
|
|||||||
SetRenderWidgetHostOpaque(false);
|
SetRenderWidgetHostOpaque(false);
|
||||||
background_color_before_vibrancy_.reset([window_ backgroundColor]);
|
background_color_before_vibrancy_.reset([window_ backgroundColor]);
|
||||||
transparency_before_vibrancy_ = [window_ titlebarAppearsTransparent];
|
transparency_before_vibrancy_ = [window_ titlebarAppearsTransparent];
|
||||||
|
ui::GpuSwitchingManager::SetTransparent(true);
|
||||||
|
|
||||||
|
if (title_bar_style_ != NORMAL) {
|
||||||
[window_ setTitlebarAppearsTransparent:YES];
|
[window_ setTitlebarAppearsTransparent:YES];
|
||||||
[window_ setBackgroundColor:[NSColor clearColor]];
|
[window_ setBackgroundColor:[NSColor clearColor]];
|
||||||
|
}
|
||||||
|
|
||||||
NSVisualEffectView* effect_view = (NSVisualEffectView*)vibrant_view;
|
NSVisualEffectView* effect_view = (NSVisualEffectView*)vibrant_view;
|
||||||
if (effect_view == nil) {
|
if (effect_view == nil) {
|
||||||
|
|||||||
@@ -1139,6 +1139,8 @@ void NativeWindowViews::OnWidgetActivationChanged(
|
|||||||
// Hide menu bar when window is blured.
|
// Hide menu bar when window is blured.
|
||||||
if (!active && menu_bar_autohide_ && menu_bar_visible_)
|
if (!active && menu_bar_autohide_ && menu_bar_visible_)
|
||||||
SetMenuBarVisibility(false);
|
SetMenuBarVisibility(false);
|
||||||
|
|
||||||
|
menu_bar_alt_pressed_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeWindowViews::OnWidgetBoundsChanged(
|
void NativeWindowViews::OnWidgetBoundsChanged(
|
||||||
|
|||||||
@@ -227,22 +227,22 @@ AtomNetworkDelegate::~AtomNetworkDelegate() {
|
|||||||
|
|
||||||
void AtomNetworkDelegate::SetSimpleListenerInIO(
|
void AtomNetworkDelegate::SetSimpleListenerInIO(
|
||||||
SimpleEvent type,
|
SimpleEvent type,
|
||||||
const URLPatterns& patterns,
|
URLPatterns patterns,
|
||||||
const SimpleListener& callback) {
|
SimpleListener callback) {
|
||||||
if (callback.is_null())
|
if (callback.is_null())
|
||||||
simple_listeners_.erase(type);
|
simple_listeners_.erase(type);
|
||||||
else
|
else
|
||||||
simple_listeners_[type] = { patterns, callback };
|
simple_listeners_[type] = { std::move(patterns), std::move(callback) };
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomNetworkDelegate::SetResponseListenerInIO(
|
void AtomNetworkDelegate::SetResponseListenerInIO(
|
||||||
ResponseEvent type,
|
ResponseEvent type,
|
||||||
const URLPatterns& patterns,
|
URLPatterns patterns,
|
||||||
const ResponseListener& callback) {
|
ResponseListener callback) {
|
||||||
if (callback.is_null())
|
if (callback.is_null())
|
||||||
response_listeners_.erase(type);
|
response_listeners_.erase(type);
|
||||||
else
|
else
|
||||||
response_listeners_[type] = { patterns, callback };
|
response_listeners_[type] = { std::move(patterns), std::move(callback) };
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomNetworkDelegate::SetDevToolsNetworkEmulationClientId(
|
void AtomNetworkDelegate::SetDevToolsNetworkEmulationClientId(
|
||||||
|
|||||||
@@ -62,11 +62,11 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
|
|||||||
~AtomNetworkDelegate() override;
|
~AtomNetworkDelegate() override;
|
||||||
|
|
||||||
void SetSimpleListenerInIO(SimpleEvent type,
|
void SetSimpleListenerInIO(SimpleEvent type,
|
||||||
const URLPatterns& patterns,
|
URLPatterns patterns,
|
||||||
const SimpleListener& callback);
|
SimpleListener callback);
|
||||||
void SetResponseListenerInIO(ResponseEvent type,
|
void SetResponseListenerInIO(ResponseEvent type,
|
||||||
const URLPatterns& patterns,
|
URLPatterns patterns,
|
||||||
const ResponseListener& callback);
|
ResponseListener callback);
|
||||||
|
|
||||||
void SetDevToolsNetworkEmulationClientId(const std::string& client_id);
|
void SetDevToolsNetworkEmulationClientId(const std::string& client_id);
|
||||||
|
|
||||||
|
|||||||
@@ -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>2.0.0</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.8.2</string>
|
<string>2.0.0</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 2,0,0,4
|
||||||
PRODUCTVERSION 1,8,2,2
|
PRODUCTVERSION 2,0,0,4
|
||||||
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", "2.0.0"
|
||||||
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", "2.0.0"
|
||||||
VALUE "SquirrelAwareVersion", "1"
|
VALUE "SquirrelAwareVersion", "1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|||||||
@@ -9,12 +9,15 @@
|
|||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/strings/sys_string_conversions.h"
|
#include "base/strings/sys_string_conversions.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "ui/base/accelerators/accelerator.h"
|
#include "ui/base/accelerators/accelerator.h"
|
||||||
#include "ui/base/accelerators/platform_accelerator_cocoa.h"
|
#include "ui/base/accelerators/platform_accelerator_cocoa.h"
|
||||||
#include "ui/base/l10n/l10n_util_mac.h"
|
#include "ui/base/l10n/l10n_util_mac.h"
|
||||||
#include "ui/events/cocoa/cocoa_event_utils.h"
|
#include "ui/events/cocoa/cocoa_event_utils.h"
|
||||||
#include "ui/gfx/image/image.h"
|
#include "ui/gfx/image/image.h"
|
||||||
|
|
||||||
|
using content::BrowserThread;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct Role {
|
struct Role {
|
||||||
@@ -335,7 +338,11 @@ static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
|||||||
if (isMenuOpen_) {
|
if (isMenuOpen_) {
|
||||||
isMenuOpen_ = NO;
|
isMenuOpen_ = NO;
|
||||||
model_->MenuWillClose();
|
model_->MenuWillClose();
|
||||||
closeCallback.Run();
|
// Post async task so that itemSelected runs before the close callback
|
||||||
|
// deletes the controller from the map which deallocates it
|
||||||
|
if (!closeCallback.is_null()) {
|
||||||
|
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closeCallback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,28 @@ WebContentsPreferences::WebContentsPreferences(
|
|||||||
web_contents->SetUserData(UserDataKey(), base::WrapUnique(this));
|
web_contents->SetUserData(UserDataKey(), base::WrapUnique(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);
|
||||||
|
SetDefaultBoolIfUndefined("webSecurity", true);
|
||||||
|
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() {
|
||||||
@@ -56,6 +78,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);
|
||||||
}
|
}
|
||||||
@@ -80,6 +112,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)
|
||||||
|
|||||||
@@ -53,10 +53,16 @@ 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>;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
@@ -64,6 +70,7 @@ class WebContentsPreferences
|
|||||||
|
|
||||||
content::WebContents* web_contents_;
|
content::WebContents* web_contents_;
|
||||||
base::DictionaryValue web_preferences_;
|
base::DictionaryValue web_preferences_;
|
||||||
|
base::DictionaryValue last_web_preferences_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(WebContentsPreferences);
|
DISALLOW_COPY_AND_ASSIGN(WebContentsPreferences);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,16 +22,16 @@ IPC_STRUCT_TRAITS_BEGIN(atom::DraggableRegion)
|
|||||||
IPC_STRUCT_TRAITS_MEMBER(bounds)
|
IPC_STRUCT_TRAITS_MEMBER(bounds)
|
||||||
IPC_STRUCT_TRAITS_END()
|
IPC_STRUCT_TRAITS_END()
|
||||||
|
|
||||||
IPC_MESSAGE_ROUTED2(AtomViewHostMsg_Message,
|
IPC_MESSAGE_ROUTED2(AtomFrameHostMsg_Message,
|
||||||
base::string16 /* channel */,
|
base::string16 /* channel */,
|
||||||
base::ListValue /* arguments */)
|
base::ListValue /* arguments */)
|
||||||
|
|
||||||
IPC_SYNC_MESSAGE_ROUTED2_1(AtomViewHostMsg_Message_Sync,
|
IPC_SYNC_MESSAGE_ROUTED2_1(AtomFrameHostMsg_Message_Sync,
|
||||||
base::string16 /* channel */,
|
base::string16 /* channel */,
|
||||||
base::ListValue /* arguments */,
|
base::ListValue /* arguments */,
|
||||||
base::string16 /* result (in JSON) */)
|
base::string16 /* result (in JSON) */)
|
||||||
|
|
||||||
IPC_MESSAGE_ROUTED3(AtomViewMsg_Message,
|
IPC_MESSAGE_ROUTED3(AtomFrameMsg_Message,
|
||||||
bool /* send_to_all */,
|
bool /* send_to_all */,
|
||||||
base::string16 /* channel */,
|
base::string16 /* channel */,
|
||||||
base::ListValue /* arguments */)
|
base::ListValue /* arguments */)
|
||||||
@@ -56,9 +56,9 @@ IPC_MESSAGE_ROUTED1(AtomFrameHostMsg_UpdateDraggableRegions,
|
|||||||
IPC_MESSAGE_CONTROL1(AtomMsg_UpdatePreferences, base::ListValue)
|
IPC_MESSAGE_CONTROL1(AtomMsg_UpdatePreferences, base::ListValue)
|
||||||
|
|
||||||
// Sent by renderer to set the temporary zoom level.
|
// Sent by renderer to set the temporary zoom level.
|
||||||
IPC_SYNC_MESSAGE_ROUTED1_1(AtomViewHostMsg_SetTemporaryZoomLevel,
|
IPC_SYNC_MESSAGE_ROUTED1_1(AtomFrameHostMsg_SetTemporaryZoomLevel,
|
||||||
double /* zoom level */,
|
double /* zoom level */,
|
||||||
double /* result */)
|
double /* result */)
|
||||||
|
|
||||||
// Sent by renderer to get the zoom level.
|
// Sent by renderer to get the zoom level.
|
||||||
IPC_SYNC_MESSAGE_ROUTED0_1(AtomViewHostMsg_GetZoomLevel, double /* result */)
|
IPC_SYNC_MESSAGE_ROUTED0_1(AtomFrameHostMsg_GetZoomLevel, double /* result */)
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include "atom/common/api/api_messages.h"
|
#include "atom/common/api/api_messages.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
|
#include "content/public/browser/render_frame_host.h"
|
||||||
|
#include "content/public/browser/web_contents.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
@@ -35,7 +37,11 @@ void RemoteCallbackFreer::RunDestructor() {
|
|||||||
base::ASCIIToUTF16("ELECTRON_RENDERER_RELEASE_CALLBACK");
|
base::ASCIIToUTF16("ELECTRON_RENDERER_RELEASE_CALLBACK");
|
||||||
base::ListValue args;
|
base::ListValue args;
|
||||||
args.AppendInteger(object_id_);
|
args.AppendInteger(object_id_);
|
||||||
Send(new AtomViewMsg_Message(routing_id(), false, channel, args));
|
auto frame_host = web_contents()->GetMainFrame();
|
||||||
|
if (frame_host) {
|
||||||
|
frame_host->Send(new AtomFrameMsg_Message(frame_host->GetRoutingID(), false,
|
||||||
|
channel, args));
|
||||||
|
}
|
||||||
|
|
||||||
Observe(nullptr);
|
Observe(nullptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,27 +7,21 @@
|
|||||||
#include "atom/common/api/api_messages.h"
|
#include "atom/common/api/api_messages.h"
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "content/public/renderer/render_view.h"
|
#include "content/public/renderer/render_frame.h"
|
||||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||||
#include "third_party/WebKit/public/web/WebView.h"
|
|
||||||
|
|
||||||
using blink::WebLocalFrame;
|
using blink::WebLocalFrame;
|
||||||
using blink::WebView;
|
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
content::RenderView* GetCurrentRenderView() {
|
content::RenderFrame* GetCurrentRenderFrame() {
|
||||||
WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
|
WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
|
||||||
if (!frame)
|
if (!frame)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
WebView* view = frame->View();
|
return content::RenderFrame::FromWebFrame(frame);
|
||||||
if (!view)
|
|
||||||
return nullptr; // can happen during closing.
|
|
||||||
|
|
||||||
return content::RenderView::FromWebView(view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -43,9 +37,9 @@ RemoteObjectFreer::RemoteObjectFreer(
|
|||||||
: ObjectLifeMonitor(isolate, target),
|
: ObjectLifeMonitor(isolate, target),
|
||||||
object_id_(object_id),
|
object_id_(object_id),
|
||||||
routing_id_(MSG_ROUTING_NONE) {
|
routing_id_(MSG_ROUTING_NONE) {
|
||||||
content::RenderView* render_view = GetCurrentRenderView();
|
content::RenderFrame* render_frame = GetCurrentRenderFrame();
|
||||||
if (render_view) {
|
if (render_frame) {
|
||||||
routing_id_ = render_view->GetRoutingID();
|
routing_id_ = render_frame->GetRoutingID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,17 +47,17 @@ RemoteObjectFreer::~RemoteObjectFreer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RemoteObjectFreer::RunDestructor() {
|
void RemoteObjectFreer::RunDestructor() {
|
||||||
content::RenderView* render_view =
|
content::RenderFrame* render_frame =
|
||||||
content::RenderView::FromRoutingID(routing_id_);
|
content::RenderFrame::FromRoutingID(routing_id_);
|
||||||
if (!render_view)
|
if (!render_frame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
base::string16 channel = base::ASCIIToUTF16("ipc-message");
|
base::string16 channel = base::ASCIIToUTF16("ipc-message");
|
||||||
base::ListValue args;
|
base::ListValue args;
|
||||||
args.AppendString("ELECTRON_BROWSER_DEREFERENCE");
|
args.AppendString("ELECTRON_BROWSER_DEREFERENCE");
|
||||||
args.AppendInteger(object_id_);
|
args.AppendInteger(object_id_);
|
||||||
render_view->Send(
|
render_frame->Send(new AtomFrameHostMsg_Message(render_frame->GetRoutingID(),
|
||||||
new AtomViewHostMsg_Message(render_view->GetRoutingID(), channel, args));
|
channel, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
#ifndef ATOM_COMMON_ATOM_VERSION_H_
|
#ifndef ATOM_COMMON_ATOM_VERSION_H_
|
||||||
#define ATOM_COMMON_ATOM_VERSION_H_
|
#define ATOM_COMMON_ATOM_VERSION_H_
|
||||||
|
|
||||||
#define ATOM_MAJOR_VERSION 1
|
#define ATOM_MAJOR_VERSION 2
|
||||||
#define ATOM_MINOR_VERSION 8
|
#define ATOM_MINOR_VERSION 0
|
||||||
#define ATOM_PATCH_VERSION 2
|
#define ATOM_PATCH_VERSION 0
|
||||||
#define ATOM_PRE_RELEASE_VERSION -beta.2
|
#define ATOM_PRE_RELEASE_VERSION -beta.4
|
||||||
|
|
||||||
#ifndef ATOM_STRINGIFY
|
#ifndef ATOM_STRINGIFY
|
||||||
#define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n)
|
#define ATOM_STRINGIFY(n) ATOM_STRINGIFY_HELPER(n)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
if (skip_system_crash_handler_)
|
||||||
TerminateProcessWithoutDump();
|
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;
|
||||||
|
|||||||
@@ -13,15 +13,19 @@
|
|||||||
#include "atom/common/atom_version.h"
|
#include "atom/common/atom_version.h"
|
||||||
#include "base/environment.h"
|
#include "base/environment.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
#include "brightray/common/platform_util.h"
|
||||||
#include "chrome/browser/ui/libgtkui/gtk_util.h"
|
#include "chrome/browser/ui/libgtkui/gtk_util.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
GDesktopAppInfo* get_desktop_app_info() {
|
GDesktopAppInfo* get_desktop_app_info() {
|
||||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
GDesktopAppInfo * ret = nullptr;
|
||||||
const std::string desktop_id = libgtkui::GetDesktopName(env.get());
|
|
||||||
return desktop_id.empty() ? nullptr
|
std::string desktop_id;
|
||||||
: g_desktop_app_info_new(desktop_id.c_str());
|
if (brightray::platform_util::GetDesktopName(&desktop_id))
|
||||||
|
ret = g_desktop_app_info_new(desktop_id.c_str());
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -7,43 +7,38 @@
|
|||||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||||
#include "atom/common/native_mate_converters/value_converter.h"
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
#include "content/public/renderer/render_view.h"
|
#include "content/public/renderer/render_frame.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||||
#include "third_party/WebKit/public/web/WebView.h"
|
#include "third_party/WebKit/public/web/WebView.h"
|
||||||
|
|
||||||
using content::RenderView;
|
using content::RenderFrame;
|
||||||
using blink::WebLocalFrame;
|
using blink::WebLocalFrame;
|
||||||
using blink::WebView;
|
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|
||||||
RenderView* GetCurrentRenderView() {
|
RenderFrame* GetCurrentRenderFrame() {
|
||||||
WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
|
WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
|
||||||
if (!frame)
|
if (!frame)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
WebView* view = frame->View();
|
return RenderFrame::FromWebFrame(frame);
|
||||||
if (!view)
|
|
||||||
return nullptr; // can happen during closing.
|
|
||||||
|
|
||||||
return RenderView::FromWebView(view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Send(mate::Arguments* args,
|
void Send(mate::Arguments* args,
|
||||||
const base::string16& channel,
|
const base::string16& channel,
|
||||||
const base::ListValue& arguments) {
|
const base::ListValue& arguments) {
|
||||||
RenderView* render_view = GetCurrentRenderView();
|
RenderFrame* render_frame = GetCurrentRenderFrame();
|
||||||
if (render_view == nullptr)
|
if (render_frame == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool success = render_view->Send(new AtomViewHostMsg_Message(
|
bool success = render_frame->Send(new AtomFrameHostMsg_Message(
|
||||||
render_view->GetRoutingID(), channel, arguments));
|
render_frame->GetRoutingID(), channel, arguments));
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
args->ThrowError("Unable to send AtomViewHostMsg_Message");
|
args->ThrowError("Unable to send AtomFrameHostMsg_Message");
|
||||||
}
|
}
|
||||||
|
|
||||||
base::string16 SendSync(mate::Arguments* args,
|
base::string16 SendSync(mate::Arguments* args,
|
||||||
@@ -51,16 +46,16 @@ base::string16 SendSync(mate::Arguments* args,
|
|||||||
const base::ListValue& arguments) {
|
const base::ListValue& arguments) {
|
||||||
base::string16 json;
|
base::string16 json;
|
||||||
|
|
||||||
RenderView* render_view = GetCurrentRenderView();
|
RenderFrame* render_frame = GetCurrentRenderFrame();
|
||||||
if (render_view == nullptr)
|
if (render_frame == nullptr)
|
||||||
return json;
|
return json;
|
||||||
|
|
||||||
IPC::SyncMessage* message = new AtomViewHostMsg_Message_Sync(
|
IPC::SyncMessage* message = new AtomFrameHostMsg_Message_Sync(
|
||||||
render_view->GetRoutingID(), channel, arguments, &json);
|
render_frame->GetRoutingID(), channel, arguments, &json);
|
||||||
bool success = render_view->Send(message);
|
bool success = render_frame->Send(message);
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
args->ThrowError("Unable to send AtomViewHostMsg_Message_Sync");
|
args->ThrowError("Unable to send AtomFrameHostMsg_Message_Sync");
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,19 +125,19 @@ void WebFrame::SetName(const std::string& name) {
|
|||||||
|
|
||||||
double WebFrame::SetZoomLevel(double level) {
|
double WebFrame::SetZoomLevel(double level) {
|
||||||
double result = 0.0;
|
double result = 0.0;
|
||||||
content::RenderView* render_view =
|
content::RenderFrame* render_frame =
|
||||||
content::RenderView::FromWebView(web_frame_->View());
|
content::RenderFrame::FromWebFrame(web_frame_);
|
||||||
render_view->Send(new AtomViewHostMsg_SetTemporaryZoomLevel(
|
render_frame->Send(new AtomFrameHostMsg_SetTemporaryZoomLevel(
|
||||||
render_view->GetRoutingID(), level, &result));
|
render_frame->GetRoutingID(), level, &result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
double WebFrame::GetZoomLevel() const {
|
double WebFrame::GetZoomLevel() const {
|
||||||
double result = 0.0;
|
double result = 0.0;
|
||||||
content::RenderView* render_view =
|
content::RenderFrame* render_frame =
|
||||||
content::RenderView::FromWebView(web_frame_->View());
|
content::RenderFrame::FromWebFrame(web_frame_);
|
||||||
render_view->Send(
|
render_frame->Send(
|
||||||
new AtomViewHostMsg_GetZoomLevel(render_view->GetRoutingID(), &result));
|
new AtomFrameHostMsg_GetZoomLevel(render_frame->GetRoutingID(), &result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,29 +4,90 @@
|
|||||||
|
|
||||||
#include "atom/renderer/atom_render_frame_observer.h"
|
#include "atom/renderer/atom_render_frame_observer.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||||
|
|
||||||
#include "atom/common/api/api_messages.h"
|
#include "atom/common/api/api_messages.h"
|
||||||
|
#include "atom/common/api/event_emitter_caller.h"
|
||||||
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
|
#include "atom/common/node_includes.h"
|
||||||
|
#include "base/strings/string_number_conversions.h"
|
||||||
|
#include "base/trace_event/trace_event.h"
|
||||||
#include "content/public/renderer/render_frame.h"
|
#include "content/public/renderer/render_frame.h"
|
||||||
#include "content/public/renderer/render_view.h"
|
#include "content/public/renderer/render_view.h"
|
||||||
|
#include "ipc/ipc_message_macros.h"
|
||||||
|
#include "native_mate/dictionary.h"
|
||||||
|
#include "net/base/net_module.h"
|
||||||
|
#include "net/grit/net_resources.h"
|
||||||
#include "third_party/WebKit/public/web/WebDocument.h"
|
#include "third_party/WebKit/public/web/WebDocument.h"
|
||||||
#include "third_party/WebKit/public/web/WebDraggableRegion.h"
|
#include "third_party/WebKit/public/web/WebDraggableRegion.h"
|
||||||
|
#include "third_party/WebKit/public/web/WebElement.h"
|
||||||
|
#include "third_party/WebKit/public/web/WebKit.h"
|
||||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||||
#include "third_party/WebKit/public/web/WebScriptSource.h"
|
#include "third_party/WebKit/public/web/WebScriptSource.h"
|
||||||
|
#include "ui/base/resource/resource_bundle.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool GetIPCObject(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Context> context,
|
||||||
|
v8::Local<v8::Object>* ipc) {
|
||||||
|
v8::Local<v8::String> key = mate::StringToV8(isolate, "ipc");
|
||||||
|
v8::Local<v8::Private> privateKey = v8::Private::ForApi(isolate, key);
|
||||||
|
v8::Local<v8::Object> global_object = context->Global();
|
||||||
|
v8::Local<v8::Value> value;
|
||||||
|
if (!global_object->GetPrivate(context, privateKey).ToLocal(&value))
|
||||||
|
return false;
|
||||||
|
if (value.IsEmpty() || !value->IsObject())
|
||||||
|
return false;
|
||||||
|
*ipc = value->ToObject();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<v8::Local<v8::Value>> ListValueToVector(
|
||||||
|
v8::Isolate* isolate,
|
||||||
|
const base::ListValue& list) {
|
||||||
|
v8::Local<v8::Value> array = mate::ConvertToV8(isolate, list);
|
||||||
|
std::vector<v8::Local<v8::Value>> result;
|
||||||
|
mate::ConvertFromV8(isolate, array, &result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
base::StringPiece NetResourceProvider(int key) {
|
||||||
|
if (key == IDR_DIR_HEADER_HTML) {
|
||||||
|
base::StringPiece html_data =
|
||||||
|
ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
|
||||||
|
IDR_DIR_HEADER_HTML);
|
||||||
|
return html_data;
|
||||||
|
}
|
||||||
|
return base::StringPiece();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
AtomRenderFrameObserver::AtomRenderFrameObserver(
|
AtomRenderFrameObserver::AtomRenderFrameObserver(
|
||||||
content::RenderFrame* frame,
|
content::RenderFrame* frame,
|
||||||
RendererClientBase* renderer_client)
|
RendererClientBase* renderer_client)
|
||||||
: content::RenderFrameObserver(frame),
|
: content::RenderFrameObserver(frame),
|
||||||
render_frame_(frame),
|
render_frame_(frame),
|
||||||
renderer_client_(renderer_client) {}
|
renderer_client_(renderer_client),
|
||||||
|
document_created_(false) {
|
||||||
|
// Initialise resource for directory listing.
|
||||||
|
net::NetModule::SetResourceProvider(NetResourceProvider);
|
||||||
|
}
|
||||||
|
|
||||||
void AtomRenderFrameObserver::DidClearWindowObject() {
|
void AtomRenderFrameObserver::DidClearWindowObject() {
|
||||||
renderer_client_->DidClearWindowObject(render_frame_);
|
renderer_client_->DidClearWindowObject(render_frame_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AtomRenderFrameObserver::DidCreateDocumentElement() {
|
||||||
|
document_created_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
void AtomRenderFrameObserver::DidCreateScriptContext(
|
void AtomRenderFrameObserver::DidCreateScriptContext(
|
||||||
v8::Handle<v8::Context> context,
|
v8::Handle<v8::Context> context,
|
||||||
int world_id) {
|
int world_id) {
|
||||||
@@ -99,4 +160,70 @@ bool AtomRenderFrameObserver::ShouldNotifyClient(int world_id) {
|
|||||||
return IsMainWorld(world_id);
|
return IsMainWorld(world_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AtomRenderFrameObserver::OnMessageReceived(const IPC::Message& message) {
|
||||||
|
bool handled = true;
|
||||||
|
IPC_BEGIN_MESSAGE_MAP(AtomRenderFrameObserver, message)
|
||||||
|
IPC_MESSAGE_HANDLER(AtomFrameMsg_Message, OnBrowserMessage)
|
||||||
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
|
IPC_END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomRenderFrameObserver::OnBrowserMessage(bool send_to_all,
|
||||||
|
const base::string16& channel,
|
||||||
|
const base::ListValue& args) {
|
||||||
|
// Don't handle browser messages before document element is created.
|
||||||
|
// When we receive a message from the browser, we try to transfer it
|
||||||
|
// to a web page, and when we do that Blink creates an empty
|
||||||
|
// document element if it hasn't been created yet, and it makes our init
|
||||||
|
// script to run while `window.location` is still "about:blank".
|
||||||
|
if (!document_created_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
blink::WebLocalFrame* frame = render_frame_->GetWebFrame();
|
||||||
|
if (!frame || !render_frame_->IsMainFrame())
|
||||||
|
return;
|
||||||
|
|
||||||
|
EmitIPCEvent(frame, channel, args);
|
||||||
|
|
||||||
|
// Also send the message to all sub-frames.
|
||||||
|
if (send_to_all) {
|
||||||
|
for (blink::WebFrame* child = frame->FirstChild(); child;
|
||||||
|
child = child->NextSibling())
|
||||||
|
if (child->IsWebLocalFrame()) {
|
||||||
|
EmitIPCEvent(child->ToWebLocalFrame(), channel, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AtomRenderFrameObserver::EmitIPCEvent(blink::WebLocalFrame* frame,
|
||||||
|
const base::string16& channel,
|
||||||
|
const base::ListValue& args) {
|
||||||
|
if (!frame)
|
||||||
|
return;
|
||||||
|
|
||||||
|
v8::Isolate* isolate = blink::MainThreadIsolate();
|
||||||
|
v8::HandleScope handle_scope(isolate);
|
||||||
|
|
||||||
|
v8::Local<v8::Context> context = renderer_client_->GetContext(frame, isolate);
|
||||||
|
v8::Context::Scope context_scope(context);
|
||||||
|
|
||||||
|
// Only emit IPC event for context with node integration.
|
||||||
|
node::Environment* env = node::Environment::GetCurrent(context);
|
||||||
|
if (!env)
|
||||||
|
return;
|
||||||
|
|
||||||
|
v8::Local<v8::Object> ipc;
|
||||||
|
if (GetIPCObject(isolate, context, &ipc)) {
|
||||||
|
TRACE_EVENT0("devtools.timeline", "FunctionCall");
|
||||||
|
auto args_vector = ListValueToVector(isolate, args);
|
||||||
|
// Insert the Event object, event.sender is ipc.
|
||||||
|
mate::Dictionary event = mate::Dictionary::CreateEmpty(isolate);
|
||||||
|
event.Set("sender", ipc);
|
||||||
|
args_vector.insert(args_vector.begin(), event.GetHandle());
|
||||||
|
mate::EmitEvent(isolate, ipc, channel, args_vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace atom
|
} // namespace atom
|
||||||
|
|||||||
@@ -6,7 +6,13 @@
|
|||||||
#define ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_
|
#define ATOM_RENDERER_ATOM_RENDER_FRAME_OBSERVER_H_
|
||||||
|
|
||||||
#include "atom/renderer/renderer_client_base.h"
|
#include "atom/renderer/renderer_client_base.h"
|
||||||
|
#include "base/strings/string16.h"
|
||||||
#include "content/public/renderer/render_frame_observer.h"
|
#include "content/public/renderer/render_frame_observer.h"
|
||||||
|
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
class ListValue;
|
||||||
|
}
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
@@ -31,15 +37,26 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver {
|
|||||||
void WillReleaseScriptContext(v8::Local<v8::Context> context,
|
void WillReleaseScriptContext(v8::Local<v8::Context> context,
|
||||||
int world_id) override;
|
int world_id) override;
|
||||||
void OnDestruct() override;
|
void OnDestruct() override;
|
||||||
|
bool OnMessageReceived(const IPC::Message& message) override;
|
||||||
|
void DidCreateDocumentElement() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void EmitIPCEvent(blink::WebLocalFrame* frame,
|
||||||
|
const base::string16& channel,
|
||||||
|
const base::ListValue& args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ShouldNotifyClient(int world_id);
|
bool ShouldNotifyClient(int world_id);
|
||||||
void CreateIsolatedWorldContext();
|
void CreateIsolatedWorldContext();
|
||||||
bool IsMainWorld(int world_id);
|
bool IsMainWorld(int world_id);
|
||||||
bool IsIsolatedWorld(int world_id);
|
bool IsIsolatedWorld(int world_id);
|
||||||
|
void OnBrowserMessage(bool send_to_all,
|
||||||
|
const base::string16& channel,
|
||||||
|
const base::ListValue& args);
|
||||||
|
|
||||||
content::RenderFrame* render_frame_;
|
content::RenderFrame* render_frame_;
|
||||||
RendererClientBase* renderer_client_;
|
RendererClientBase* renderer_client_;
|
||||||
|
bool document_created_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver);
|
DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,118 +4,21 @@
|
|||||||
|
|
||||||
#include "atom/renderer/atom_render_view_observer.h"
|
#include "atom/renderer/atom_render_view_observer.h"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// Put this before event_emitter_caller.h to have string16 support.
|
|
||||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
|
||||||
|
|
||||||
#include "atom/common/api/api_messages.h"
|
#include "atom/common/api/api_messages.h"
|
||||||
#include "atom/common/api/event_emitter_caller.h"
|
|
||||||
#include "atom/common/native_mate_converters/value_converter.h"
|
|
||||||
#include "atom/common/node_includes.h"
|
|
||||||
#include "atom/renderer/atom_renderer_client.h"
|
|
||||||
#include "base/command_line.h"
|
|
||||||
#include "base/strings/string_number_conversions.h"
|
|
||||||
#include "base/trace_event/trace_event.h"
|
|
||||||
#include "content/public/renderer/render_view.h"
|
#include "content/public/renderer/render_view.h"
|
||||||
#include "ipc/ipc_message_macros.h"
|
#include "ipc/ipc_message_macros.h"
|
||||||
#include "native_mate/dictionary.h"
|
|
||||||
#include "net/base/net_module.h"
|
|
||||||
#include "net/grit/net_resources.h"
|
|
||||||
#include "third_party/WebKit/public/web/WebDocument.h"
|
|
||||||
#include "third_party/WebKit/public/web/WebElement.h"
|
|
||||||
#include "third_party/WebKit/public/web/WebFrame.h"
|
|
||||||
#include "third_party/WebKit/public/web/WebKit.h"
|
|
||||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
|
||||||
#include "third_party/WebKit/public/web/WebView.h"
|
#include "third_party/WebKit/public/web/WebView.h"
|
||||||
#include "ui/base/resource/resource_bundle.h"
|
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
namespace {
|
AtomRenderViewObserver::AtomRenderViewObserver(content::RenderView* render_view)
|
||||||
|
: content::RenderViewObserver(render_view) {}
|
||||||
|
|
||||||
bool GetIPCObject(v8::Isolate* isolate,
|
AtomRenderViewObserver::~AtomRenderViewObserver() {}
|
||||||
v8::Local<v8::Context> context,
|
|
||||||
v8::Local<v8::Object>* ipc) {
|
|
||||||
v8::Local<v8::String> key = mate::StringToV8(isolate, "ipc");
|
|
||||||
v8::Local<v8::Private> privateKey = v8::Private::ForApi(isolate, key);
|
|
||||||
v8::Local<v8::Object> global_object = context->Global();
|
|
||||||
v8::Local<v8::Value> value;
|
|
||||||
if (!global_object->GetPrivate(context, privateKey).ToLocal(&value))
|
|
||||||
return false;
|
|
||||||
if (value.IsEmpty() || !value->IsObject())
|
|
||||||
return false;
|
|
||||||
*ipc = value->ToObject();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<v8::Local<v8::Value>> ListValueToVector(
|
|
||||||
v8::Isolate* isolate,
|
|
||||||
const base::ListValue& list) {
|
|
||||||
v8::Local<v8::Value> array = mate::ConvertToV8(isolate, list);
|
|
||||||
std::vector<v8::Local<v8::Value>> result;
|
|
||||||
mate::ConvertFromV8(isolate, array, &result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
base::StringPiece NetResourceProvider(int key) {
|
|
||||||
if (key == IDR_DIR_HEADER_HTML) {
|
|
||||||
base::StringPiece html_data =
|
|
||||||
ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
|
|
||||||
IDR_DIR_HEADER_HTML);
|
|
||||||
return html_data;
|
|
||||||
}
|
|
||||||
return base::StringPiece();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
AtomRenderViewObserver::AtomRenderViewObserver(
|
|
||||||
content::RenderView* render_view,
|
|
||||||
AtomRendererClient* renderer_client)
|
|
||||||
: content::RenderViewObserver(render_view),
|
|
||||||
renderer_client_(renderer_client) {
|
|
||||||
// Initialise resource for directory listing.
|
|
||||||
net::NetModule::SetResourceProvider(NetResourceProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
AtomRenderViewObserver::~AtomRenderViewObserver() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void AtomRenderViewObserver::EmitIPCEvent(blink::WebLocalFrame* frame,
|
|
||||||
const base::string16& channel,
|
|
||||||
const base::ListValue& args) {
|
|
||||||
if (!frame)
|
|
||||||
return;
|
|
||||||
|
|
||||||
v8::Isolate* isolate = blink::MainThreadIsolate();
|
|
||||||
v8::HandleScope handle_scope(isolate);
|
|
||||||
|
|
||||||
v8::Local<v8::Context> context = renderer_client_->GetContext(frame, isolate);
|
|
||||||
v8::Context::Scope context_scope(context);
|
|
||||||
|
|
||||||
// Only emit IPC event for context with node integration.
|
|
||||||
node::Environment* env = node::Environment::GetCurrent(context);
|
|
||||||
if (!env)
|
|
||||||
return;
|
|
||||||
|
|
||||||
v8::Local<v8::Object> ipc;
|
|
||||||
if (GetIPCObject(isolate, context, &ipc)) {
|
|
||||||
TRACE_EVENT0("devtools.timeline", "FunctionCall");
|
|
||||||
auto args_vector = ListValueToVector(isolate, args);
|
|
||||||
// Insert the Event object, event.sender is ipc.
|
|
||||||
mate::Dictionary event = mate::Dictionary::CreateEmpty(isolate);
|
|
||||||
event.Set("sender", ipc);
|
|
||||||
args_vector.insert(args_vector.begin(), event.GetHandle());
|
|
||||||
mate::EmitEvent(isolate, ipc, channel, args_vector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
|
bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
|
||||||
bool handled = true;
|
bool handled = true;
|
||||||
IPC_BEGIN_MESSAGE_MAP(AtomRenderViewObserver, message)
|
IPC_BEGIN_MESSAGE_MAP(AtomRenderViewObserver, message)
|
||||||
IPC_MESSAGE_HANDLER(AtomViewMsg_Message, OnBrowserMessage)
|
|
||||||
IPC_MESSAGE_HANDLER(AtomViewMsg_Offscreen, OnOffscreen)
|
IPC_MESSAGE_HANDLER(AtomViewMsg_Offscreen, OnOffscreen)
|
||||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||||
IPC_END_MESSAGE_MAP()
|
IPC_END_MESSAGE_MAP()
|
||||||
@@ -127,39 +30,6 @@ void AtomRenderViewObserver::OnDestruct() {
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomRenderViewObserver::OnBrowserMessage(bool send_to_all,
|
|
||||||
const base::string16& channel,
|
|
||||||
const base::ListValue& args) {
|
|
||||||
if (!render_view()->GetWebView())
|
|
||||||
return;
|
|
||||||
|
|
||||||
blink::WebFrame* frame = render_view()->GetWebView()->MainFrame();
|
|
||||||
if (!frame || !frame->IsWebLocalFrame())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Don't handle browser messages before document element is created.
|
|
||||||
// When we receive a message from the browser, we try to transfer it
|
|
||||||
// to a web page, and when we do that Blink creates an empty
|
|
||||||
// document element if it hasn't been created yet, and it makes our init
|
|
||||||
// script to run while `window.location` is still "about:blank".
|
|
||||||
blink::WebDocument document = frame->ToWebLocalFrame()->GetDocument();
|
|
||||||
blink::WebElement html_element = document.DocumentElement();
|
|
||||||
if (html_element.IsNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
EmitIPCEvent(frame->ToWebLocalFrame(), channel, args);
|
|
||||||
|
|
||||||
// Also send the message to all sub-frames.
|
|
||||||
if (send_to_all) {
|
|
||||||
for (blink::WebFrame* child = frame->FirstChild(); child;
|
|
||||||
child = child->NextSibling())
|
|
||||||
if (child->IsWebLocalFrame()) {
|
|
||||||
EmitIPCEvent(child->ToWebLocalFrame(), channel, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AtomRenderViewObserver::OnOffscreen() {
|
void AtomRenderViewObserver::OnOffscreen() {
|
||||||
blink::WebView::SetUseExternalPopupMenus(false);
|
blink::WebView::SetUseExternalPopupMenus(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,43 +5,24 @@
|
|||||||
#ifndef ATOM_RENDERER_ATOM_RENDER_VIEW_OBSERVER_H_
|
#ifndef ATOM_RENDERER_ATOM_RENDER_VIEW_OBSERVER_H_
|
||||||
#define ATOM_RENDERER_ATOM_RENDER_VIEW_OBSERVER_H_
|
#define ATOM_RENDERER_ATOM_RENDER_VIEW_OBSERVER_H_
|
||||||
|
|
||||||
#include "base/strings/string16.h"
|
|
||||||
#include "content/public/renderer/render_view_observer.h"
|
#include "content/public/renderer/render_view_observer.h"
|
||||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
class ListValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
class AtomRendererClient;
|
|
||||||
|
|
||||||
class AtomRenderViewObserver : public content::RenderViewObserver {
|
class AtomRenderViewObserver : public content::RenderViewObserver {
|
||||||
public:
|
public:
|
||||||
explicit AtomRenderViewObserver(content::RenderView* render_view,
|
explicit AtomRenderViewObserver(content::RenderView* render_view);
|
||||||
AtomRendererClient* renderer_client);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~AtomRenderViewObserver();
|
virtual ~AtomRenderViewObserver();
|
||||||
|
|
||||||
virtual void EmitIPCEvent(blink::WebLocalFrame* frame,
|
|
||||||
const base::string16& channel,
|
|
||||||
const base::ListValue& args);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// content::RenderViewObserver implementation.
|
// content::RenderViewObserver implementation.
|
||||||
bool OnMessageReceived(const IPC::Message& message) override;
|
bool OnMessageReceived(const IPC::Message& message) override;
|
||||||
void OnDestruct() override;
|
void OnDestruct() override;
|
||||||
|
|
||||||
void OnBrowserMessage(bool send_to_all,
|
|
||||||
const base::string16& channel,
|
|
||||||
const base::ListValue& args);
|
|
||||||
|
|
||||||
void OnOffscreen();
|
void OnOffscreen();
|
||||||
|
|
||||||
AtomRendererClient* renderer_client_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomRenderViewObserver);
|
DISALLOW_COPY_AND_ASSIGN(AtomRenderViewObserver);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include "atom/common/options_switches.h"
|
#include "atom/common/options_switches.h"
|
||||||
#include "atom/renderer/api/atom_api_renderer_ipc.h"
|
#include "atom/renderer/api/atom_api_renderer_ipc.h"
|
||||||
#include "atom/renderer/atom_render_frame_observer.h"
|
#include "atom/renderer/atom_render_frame_observer.h"
|
||||||
#include "atom/renderer/atom_render_view_observer.h"
|
|
||||||
#include "atom/renderer/web_worker_observer.h"
|
#include "atom/renderer/web_worker_observer.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "content/public/renderer/render_frame.h"
|
#include "content/public/renderer/render_frame.h"
|
||||||
@@ -53,11 +52,11 @@ void AtomRendererClient::RenderThreadStarted() {
|
|||||||
|
|
||||||
void AtomRendererClient::RenderFrameCreated(
|
void AtomRendererClient::RenderFrameCreated(
|
||||||
content::RenderFrame* render_frame) {
|
content::RenderFrame* render_frame) {
|
||||||
|
new AtomRenderFrameObserver(render_frame, this);
|
||||||
RendererClientBase::RenderFrameCreated(render_frame);
|
RendererClientBase::RenderFrameCreated(render_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
|
void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {
|
||||||
new AtomRenderViewObserver(render_view, this);
|
|
||||||
RendererClientBase::RenderViewCreated(render_view);
|
RendererClientBase::RenderViewCreated(render_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,20 +13,12 @@
|
|||||||
#include "atom/common/native_mate_converters/value_converter.h"
|
#include "atom/common/native_mate_converters/value_converter.h"
|
||||||
#include "atom/common/options_switches.h"
|
#include "atom/common/options_switches.h"
|
||||||
#include "atom/renderer/api/atom_api_renderer_ipc.h"
|
#include "atom/renderer/api/atom_api_renderer_ipc.h"
|
||||||
#include "atom/renderer/atom_render_view_observer.h"
|
#include "atom/renderer/atom_render_frame_observer.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "chrome/renderer/printing/print_web_view_helper.h"
|
#include "chrome/renderer/printing/print_web_view_helper.h"
|
||||||
#include "content/public/renderer/render_frame.h"
|
#include "content/public/renderer/render_frame.h"
|
||||||
#include "content/public/renderer/render_view.h"
|
|
||||||
#include "content/public/renderer/render_view_observer.h"
|
|
||||||
#include "ipc/ipc_message_macros.h"
|
|
||||||
#include "native_mate/converter.h"
|
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "third_party/WebKit/public/web/WebFrame.h"
|
|
||||||
#include "third_party/WebKit/public/web/WebKit.h"
|
#include "third_party/WebKit/public/web/WebKit.h"
|
||||||
#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
|
||||||
#include "third_party/WebKit/public/web/WebScriptSource.h"
|
|
||||||
#include "third_party/WebKit/public/web/WebView.h"
|
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
#include "atom_natives.h" // NOLINT: This file is generated with js2c
|
#include "atom_natives.h" // NOLINT: This file is generated with js2c
|
||||||
@@ -95,11 +87,11 @@ void InitializeBindings(v8::Local<v8::Object> binding,
|
|||||||
b.SetMethod("getSystemMemoryInfo", &AtomBindings::GetSystemMemoryInfo);
|
b.SetMethod("getSystemMemoryInfo", &AtomBindings::GetSystemMemoryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AtomSandboxedRenderViewObserver : public AtomRenderViewObserver {
|
class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver {
|
||||||
public:
|
public:
|
||||||
AtomSandboxedRenderViewObserver(content::RenderView* render_view,
|
AtomSandboxedRenderFrameObserver(content::RenderFrame* render_frame,
|
||||||
AtomSandboxedRendererClient* renderer_client)
|
AtomSandboxedRendererClient* renderer_client)
|
||||||
: AtomRenderViewObserver(render_view, nullptr),
|
: AtomRenderFrameObserver(render_frame, renderer_client),
|
||||||
v8_converter_(new atom::V8ValueConverter),
|
v8_converter_(new atom::V8ValueConverter),
|
||||||
renderer_client_(renderer_client) {
|
renderer_client_(renderer_client) {
|
||||||
v8_converter_->SetDisableNode(true);
|
v8_converter_->SetDisableNode(true);
|
||||||
@@ -108,7 +100,7 @@ class AtomSandboxedRenderViewObserver : public AtomRenderViewObserver {
|
|||||||
protected:
|
protected:
|
||||||
void EmitIPCEvent(blink::WebLocalFrame* frame,
|
void EmitIPCEvent(blink::WebLocalFrame* frame,
|
||||||
const base::string16& channel,
|
const base::string16& channel,
|
||||||
const base::ListValue& args) override {
|
const base::ListValue& args) {
|
||||||
if (!frame)
|
if (!frame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -129,7 +121,7 @@ class AtomSandboxedRenderViewObserver : public AtomRenderViewObserver {
|
|||||||
private:
|
private:
|
||||||
std::unique_ptr<atom::V8ValueConverter> v8_converter_;
|
std::unique_ptr<atom::V8ValueConverter> v8_converter_;
|
||||||
AtomSandboxedRendererClient* renderer_client_;
|
AtomSandboxedRendererClient* renderer_client_;
|
||||||
DISALLOW_COPY_AND_ASSIGN(AtomSandboxedRenderViewObserver);
|
DISALLOW_COPY_AND_ASSIGN(AtomSandboxedRenderFrameObserver);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -143,12 +135,12 @@ AtomSandboxedRendererClient::~AtomSandboxedRendererClient() {
|
|||||||
|
|
||||||
void AtomSandboxedRendererClient::RenderFrameCreated(
|
void AtomSandboxedRendererClient::RenderFrameCreated(
|
||||||
content::RenderFrame* render_frame) {
|
content::RenderFrame* render_frame) {
|
||||||
|
new AtomSandboxedRenderFrameObserver(render_frame, this);
|
||||||
RendererClientBase::RenderFrameCreated(render_frame);
|
RendererClientBase::RenderFrameCreated(render_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomSandboxedRendererClient::RenderViewCreated(
|
void AtomSandboxedRendererClient::RenderViewCreated(
|
||||||
content::RenderView* render_view) {
|
content::RenderView* render_view) {
|
||||||
new AtomSandboxedRenderViewObserver(render_view, this);
|
|
||||||
RendererClientBase::RenderViewCreated(render_view);
|
RendererClientBase::RenderViewCreated(render_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "atom/common/options_switches.h"
|
#include "atom/common/options_switches.h"
|
||||||
#include "atom/renderer/atom_autofill_agent.h"
|
#include "atom/renderer/atom_autofill_agent.h"
|
||||||
#include "atom/renderer/atom_render_frame_observer.h"
|
#include "atom/renderer/atom_render_frame_observer.h"
|
||||||
|
#include "atom/renderer/atom_render_view_observer.h"
|
||||||
#include "atom/renderer/content_settings_observer.h"
|
#include "atom/renderer/content_settings_observer.h"
|
||||||
#include "atom/renderer/guest_view_container.h"
|
#include "atom/renderer/guest_view_container.h"
|
||||||
#include "atom/renderer/preferences_manager.h"
|
#include "atom/renderer/preferences_manager.h"
|
||||||
@@ -26,13 +27,13 @@
|
|||||||
#include "content/public/common/content_constants.h"
|
#include "content/public/common/content_constants.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 "third_party/WebKit/public/web/WebCustomElement.h"
|
#include "third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h"
|
||||||
|
#include "third_party/WebKit/public/web/WebCustomElement.h" // NOLINT(build/include_alpha)
|
||||||
#include "third_party/WebKit/public/web/WebFrameWidget.h"
|
#include "third_party/WebKit/public/web/WebFrameWidget.h"
|
||||||
#include "third_party/WebKit/public/web/WebKit.h"
|
#include "third_party/WebKit/public/web/WebKit.h"
|
||||||
#include "third_party/WebKit/public/web/WebPluginParams.h"
|
#include "third_party/WebKit/public/web/WebPluginParams.h"
|
||||||
#include "third_party/WebKit/public/web/WebScriptSource.h"
|
#include "third_party/WebKit/public/web/WebScriptSource.h"
|
||||||
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
|
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
|
||||||
#include "third_party/WebKit/Source/platform/weborigin/SchemeRegistry.h"
|
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
#include "base/mac/mac_util.h"
|
#include "base/mac/mac_util.h"
|
||||||
@@ -144,7 +145,6 @@ void RendererClientBase::RenderThreadStarted() {
|
|||||||
|
|
||||||
void RendererClientBase::RenderFrameCreated(
|
void RendererClientBase::RenderFrameCreated(
|
||||||
content::RenderFrame* render_frame) {
|
content::RenderFrame* render_frame) {
|
||||||
new AtomRenderFrameObserver(render_frame, this);
|
|
||||||
new AutofillAgent(render_frame);
|
new AutofillAgent(render_frame);
|
||||||
new PepperHelper(render_frame);
|
new PepperHelper(render_frame);
|
||||||
new ContentSettingsObserver(render_frame);
|
new ContentSettingsObserver(render_frame);
|
||||||
@@ -159,6 +159,7 @@ void RendererClientBase::RenderFrameCreated(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RendererClientBase::RenderViewCreated(content::RenderView* render_view) {
|
void RendererClientBase::RenderViewCreated(content::RenderView* render_view) {
|
||||||
|
new AtomRenderViewObserver(render_view);
|
||||||
blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
|
blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
|
||||||
if (!web_frame_widget)
|
if (!web_frame_widget)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -157,7 +157,6 @@
|
|||||||
'-ldl',
|
'-ldl',
|
||||||
'-lresolv',
|
'-lresolv',
|
||||||
'-lfontconfig',
|
'-lfontconfig',
|
||||||
'-lfreetype',
|
|
||||||
'-lexpat',
|
'-lexpat',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -169,14 +168,6 @@
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
# On ARM64 libchromiumcontent always links to system libfreetype
|
|
||||||
['target_arch=="arm64"', {
|
|
||||||
'link_settings': {
|
|
||||||
'libraries': [
|
|
||||||
'-lfreetype',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
],
|
],
|
||||||
}], # OS=="linux"
|
}], # OS=="linux"
|
||||||
['OS=="mac"', {
|
['OS=="mac"', {
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "brightray/browser/notification_delegate.h"
|
#include "brightray/browser/notification_delegate.h"
|
||||||
#include "brightray/common/application_info.h"
|
#include "brightray/common/application_info.h"
|
||||||
|
#include "brightray/common/platform_util.h"
|
||||||
|
#include "chrome/browser/ui/libgtkui/gtk_util.h"
|
||||||
#include "chrome/browser/ui/libgtkui/skia_utils_gtk.h"
|
#include "chrome/browser/ui/libgtkui/skia_utils_gtk.h"
|
||||||
#include "third_party/skia/include/core/SkBitmap.h"
|
#include "third_party/skia/include/core/SkBitmap.h"
|
||||||
|
|
||||||
@@ -126,6 +128,19 @@ void LibnotifyNotification::Show(const NotificationOptions& options) {
|
|||||||
notification_, "x-canonical-append", "true");
|
notification_, "x-canonical-append", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send the desktop name to identify the application
|
||||||
|
// The desktop-entry is the part before the .desktop
|
||||||
|
std::string desktop_id;
|
||||||
|
if (platform_util::GetDesktopName(&desktop_id)) {
|
||||||
|
const std::string suffix{".desktop"};
|
||||||
|
if (base::EndsWith(desktop_id, suffix,
|
||||||
|
base::CompareCase::INSENSITIVE_ASCII)) {
|
||||||
|
desktop_id.resize(desktop_id.size() - suffix.size());
|
||||||
|
}
|
||||||
|
libnotify_loader_.notify_notification_set_hint_string(
|
||||||
|
notification_, "desktop-entry", desktop_id.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
GError* error = nullptr;
|
GError* error = nullptr;
|
||||||
libnotify_loader_.notify_notification_show(notification_, &error);
|
libnotify_loader_.notify_notification_show(notification_, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|||||||
@@ -80,11 +80,6 @@ class URLRequestContextGetter : public net::URLRequestContextGetter {
|
|||||||
|
|
||||||
net::HostResolver* host_resolver();
|
net::HostResolver* host_resolver();
|
||||||
net::URLRequestJobFactory* job_factory() const { return job_factory_; }
|
net::URLRequestJobFactory* job_factory() const { return job_factory_; }
|
||||||
net::NetworkDelegate* network_delegate() const {
|
|
||||||
if (url_request_context_)
|
|
||||||
return url_request_context_->network_delegate();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Delegate* delegate_;
|
Delegate* delegate_;
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ namespace {
|
|||||||
std::string g_overridden_application_name;
|
std::string g_overridden_application_name;
|
||||||
std::string g_overridden_application_version;
|
std::string g_overridden_application_version;
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
|
// name
|
||||||
void OverrideApplicationName(const std::string& name) {
|
void OverrideApplicationName(const std::string& name) {
|
||||||
g_overridden_application_name = name;
|
g_overridden_application_name = name;
|
||||||
}
|
}
|
||||||
@@ -16,6 +17,7 @@ std::string GetOverriddenApplicationName() {
|
|||||||
return g_overridden_application_name;
|
return g_overridden_application_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// version
|
||||||
void OverrideApplicationVersion(const std::string& version) {
|
void OverrideApplicationVersion(const std::string& version) {
|
||||||
g_overridden_application_version = version;
|
g_overridden_application_version = version;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,10 +47,7 @@ PCWSTR GetRawAppUserModelID() {
|
|||||||
if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(¤t_app_id))) {
|
if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(¤t_app_id))) {
|
||||||
g_app_user_model_id = current_app_id;
|
g_app_user_model_id = current_app_id;
|
||||||
} else {
|
} else {
|
||||||
std::string name = GetOverriddenApplicationName();
|
std::string name = GetApplicationName();
|
||||||
if (name.empty()) {
|
|
||||||
name = GetApplicationName();
|
|
||||||
}
|
|
||||||
base::string16 generated_app_id = base::ReplaceStringPlaceholders(
|
base::string16 generated_app_id = base::ReplaceStringPlaceholders(
|
||||||
kAppUserModelIDFormat, base::UTF8ToUTF16(name), nullptr);
|
kAppUserModelIDFormat, base::UTF8ToUTF16(name), nullptr);
|
||||||
SetAppUserModelID(generated_app_id);
|
SetAppUserModelID(generated_app_id);
|
||||||
|
|||||||
24
brightray/common/platform_util.h
Normal file
24
brightray/common/platform_util.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// 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 BRIGHTRAY_COMMON_PLATFORM_UTIL_H_
|
||||||
|
#define BRIGHTRAY_COMMON_PLATFORM_UTIL_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
namespace platform_util {
|
||||||
|
|
||||||
|
#if defined(OS_LINUX)
|
||||||
|
// Returns a success flag.
|
||||||
|
// Unlike libgtkui, does *not* use "chromium-browser.desktop" as a fallback.
|
||||||
|
bool GetDesktopName(std::string* setme);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace platform_util
|
||||||
|
|
||||||
|
} // namespace brightray
|
||||||
|
|
||||||
|
#endif // BRIGHTRAY_COMMON_PLATFORM_UTIL_H_
|
||||||
30
brightray/common/platform_util_linux.cc
Normal file
30
brightray/common/platform_util_linux.cc
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) 2018 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "brightray/common/platform_util.h"
|
||||||
|
|
||||||
|
#include "base/environment.h"
|
||||||
|
#include "chrome/browser/ui/libgtkui/gtk_util.h"
|
||||||
|
|
||||||
|
namespace brightray {
|
||||||
|
|
||||||
|
namespace platform_util {
|
||||||
|
|
||||||
|
bool GetDesktopName(std::string* setme) {
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||||
|
std::string desktop_id = libgtkui::GetDesktopName(env.get());
|
||||||
|
constexpr char const* libcc_default_id = "chromium-browser.desktop";
|
||||||
|
if (!desktop_id.empty() && (desktop_id != libcc_default_id)) {
|
||||||
|
*setme = desktop_id;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace platform_util
|
||||||
|
|
||||||
|
} // namespace brightray
|
||||||
@@ -124,6 +124,8 @@
|
|||||||
'common/main_delegate_mac.mm',
|
'common/main_delegate_mac.mm',
|
||||||
'common/switches.cc',
|
'common/switches.cc',
|
||||||
'common/switches.h',
|
'common/switches.h',
|
||||||
|
'common/platform_util_linux.cc',
|
||||||
|
'common/platform_util.h',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -235,7 +235,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
|||||||
window shadow and window animations. Default is `true`.
|
window shadow and window animations. Default is `true`.
|
||||||
* `vibrancy` String (optional) - Add a type of vibrancy effect to the window, only on
|
* `vibrancy` String (optional) - Add a type of vibrancy effect to the window, only on
|
||||||
macOS. Can be `appearance-based`, `light`, `dark`, `titlebar`, `selection`,
|
macOS. Can be `appearance-based`, `light`, `dark`, `titlebar`, `selection`,
|
||||||
`menu`, `popover`, `sidebar`, `medium-light` or `ultra-dark`.
|
`menu`, `popover`, `sidebar`, `medium-light` or `ultra-dark`. Please note that
|
||||||
|
using `frame: false` in combination with a vibrancy value requires that you use a
|
||||||
|
non-default `titleBarStyle` as well.
|
||||||
* `zoomToPageWidth` Boolean (optional) - Controls the behavior on macOS when
|
* `zoomToPageWidth` Boolean (optional) - Controls the behavior on macOS when
|
||||||
option-clicking the green stoplight button on the toolbar or by clicking the
|
option-clicking the green stoplight button on the toolbar or by clicking the
|
||||||
Window > Zoom menu item. If `true`, the window will grow to the preferred
|
Window > Zoom menu item. If `true`, the window will grow to the preferred
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# Planned Breaking API Changes
|
# Planned Breaking API Changes
|
||||||
|
|
||||||
The following list includes the APIs that will be removed in Electron 2.0.
|
The following list includes the APIs that will be removed in Electron 3.0.
|
||||||
|
|
||||||
There is no timetable for when this release will occur but deprecation
|
There is no timetable for when this release will occur but deprecation
|
||||||
warnings will be added at least 90 days beforehand.
|
warnings will be added at least [one major version](electron-versioning.md#semver) beforehand.
|
||||||
|
|
||||||
## `app`
|
## `app`
|
||||||
|
|
||||||
@@ -25,16 +25,6 @@ let optionsB = {webPreferences: {enableBlinkFeatures: ''}}
|
|||||||
let windowB = new BrowserWindow(optionsB)
|
let windowB = new BrowserWindow(optionsB)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Deprecated
|
|
||||||
let optionsA = {titleBarStyle: 'hidden-inset'}
|
|
||||||
let windowA = new BrowserWindow(optionsA)
|
|
||||||
// Replace with
|
|
||||||
let optionsB = {titleBarStyle: 'hiddenInset'}
|
|
||||||
let windowB = new BrowserWindow(optionsB)
|
|
||||||
```
|
|
||||||
|
|
||||||
## `clipboard`
|
## `clipboard`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@@ -76,28 +66,9 @@ crashReporter.start({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## `menu`
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Deprecated
|
|
||||||
menu.popup(browserWindow, 100, 200, 2)
|
|
||||||
// Replace with
|
|
||||||
menu.popup(browserWindow, {x: 100, y: 200, positioningItem: 2})
|
|
||||||
```
|
|
||||||
|
|
||||||
## `nativeImage`
|
## `nativeImage`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Deprecated
|
|
||||||
nativeImage.toPng()
|
|
||||||
// Replace with
|
|
||||||
nativeImage.toPNG()
|
|
||||||
|
|
||||||
// Deprecated
|
|
||||||
nativeImage.toJpeg()
|
|
||||||
// Replace with
|
|
||||||
nativeImage.toJPEG()
|
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
nativeImage.createFromBuffer(buffer, 1.0)
|
nativeImage.createFromBuffer(buffer, 1.0)
|
||||||
// Replace with
|
// Replace with
|
||||||
@@ -106,19 +77,15 @@ nativeImage.createFromBuffer(buffer, {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## `process`
|
## `screen`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Deprecated
|
// Deprecated
|
||||||
process.versions['atom-shell']
|
screen.getMenuBarHeight()
|
||||||
// Replace with
|
// Replace with
|
||||||
process.versions.electron
|
screen.getPrimaryDisplay().workArea
|
||||||
```
|
```
|
||||||
|
|
||||||
* `process.versions.electron` and `process.version.chrome` will be made
|
|
||||||
read-only properties for consistency with the other `process.versions`
|
|
||||||
properties set by Node.
|
|
||||||
|
|
||||||
## `session`
|
## `session`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@@ -155,21 +122,9 @@ webContents.openDevTools({detach: true})
|
|||||||
webContents.openDevTools({mode: 'detach'})
|
webContents.openDevTools({mode: 'detach'})
|
||||||
```
|
```
|
||||||
|
|
||||||
```js
|
|
||||||
// Deprecated
|
|
||||||
webContents.setZoomLevelLimits(1, 2)
|
|
||||||
// Replace with
|
|
||||||
webContents.setVisualZoomLevelLimits(1, 2)
|
|
||||||
```
|
|
||||||
|
|
||||||
## `webFrame`
|
## `webFrame`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Deprecated
|
|
||||||
webFrame.setZoomLevelLimits(1, 2)
|
|
||||||
// Replace with
|
|
||||||
webFrame.setVisualZoomLevelLimits(1, 2)
|
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
webFrame.registerURLSchemeAsSecure('app')
|
webFrame.registerURLSchemeAsSecure('app')
|
||||||
// Replace with
|
// Replace with
|
||||||
@@ -181,15 +136,6 @@ webFrame.registerURLSchemeAsPrivileged('app', {secure: true})
|
|||||||
protocol.registerStandardSchemes(['app'], {secure: true})
|
protocol.registerStandardSchemes(['app'], {secure: true})
|
||||||
```
|
```
|
||||||
|
|
||||||
## `<webview>`
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Deprecated
|
|
||||||
webview.setZoomLevelLimits(1, 2)
|
|
||||||
// Replace with
|
|
||||||
webview.setVisualZoomLevelLimits(1, 2)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Node Headers URL
|
## Node Headers URL
|
||||||
|
|
||||||
This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url`
|
This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url`
|
||||||
@@ -199,26 +145,8 @@ Deprecated: https://atom.io/download/atom-shell
|
|||||||
|
|
||||||
Replace with: https://atom.io/download/electron
|
Replace with: https://atom.io/download/electron
|
||||||
|
|
||||||
## Duplicate ARM Assets
|
|
||||||
|
|
||||||
Each Electron release includes two identical ARM builds with slightly different
|
|
||||||
filenames, like `electron-v1.7.3-linux-arm.zip` and
|
|
||||||
`electron-v1.7.3-linux-armv7l.zip`. The asset with the `v7l` prefix was added
|
|
||||||
to clarify to users which ARM version it supports, and to disambiguate it from
|
|
||||||
future armv6l and arm64 assets that may be produced.
|
|
||||||
|
|
||||||
The file _without the prefix_ is still being published to avoid breaking any
|
|
||||||
setups that may be consuming it. Starting at 2.0, the un-prefixed file will
|
|
||||||
no longer be published.
|
|
||||||
|
|
||||||
For details, see
|
|
||||||
[6986](https://github.com/electron/electron/pull/6986)
|
|
||||||
and
|
|
||||||
[7189](https://github.com/electron/electron/pull/7189).
|
|
||||||
|
|
||||||
|
|
||||||
## `FIXME` comments
|
## `FIXME` comments
|
||||||
|
|
||||||
The `FIXME` string is used in code comments to denote things that should be
|
The `FIXME` string is used in code comments to denote things that should be
|
||||||
fixed for the 2.0 release. See
|
fixed for the 3.0 release. See
|
||||||
https://github.com/electron/electron/search?q=fixme
|
https://github.com/electron/electron/search?q=fixme
|
||||||
|
|||||||
@@ -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%': '2.0.0-beta.4',
|
||||||
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
|
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
|
||||||
},
|
},
|
||||||
'includes': [
|
'includes': [
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ const electron = require('electron')
|
|||||||
const {deprecate, Menu} = electron
|
const {deprecate, Menu} = electron
|
||||||
const {EventEmitter} = require('events')
|
const {EventEmitter} = require('events')
|
||||||
|
|
||||||
|
let dockMenu = null
|
||||||
|
|
||||||
// App is an EventEmitter.
|
// App is an EventEmitter.
|
||||||
Object.setPrototypeOf(App.prototype, EventEmitter.prototype)
|
Object.setPrototypeOf(App.prototype, EventEmitter.prototype)
|
||||||
EventEmitter.call(app)
|
EventEmitter.call(app)
|
||||||
@@ -49,7 +51,13 @@ if (process.platform === 'darwin') {
|
|||||||
hide: bindings.dockHide,
|
hide: bindings.dockHide,
|
||||||
show: bindings.dockShow,
|
show: bindings.dockShow,
|
||||||
isVisible: bindings.dockIsVisible,
|
isVisible: bindings.dockIsVisible,
|
||||||
setMenu: bindings.dockSetMenu,
|
setMenu (menu) {
|
||||||
|
dockMenu = menu
|
||||||
|
bindings.dockSetMenu(menu)
|
||||||
|
},
|
||||||
|
getMenu () {
|
||||||
|
return dockMenu
|
||||||
|
},
|
||||||
setIcon: bindings.dockSetIcon
|
setIcon: bindings.dockSetIcon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
const {EventEmitter} = require('events')
|
const {EventEmitter} = require('events')
|
||||||
|
const {deprecate} = require('electron')
|
||||||
const {screen, Screen} = process.atomBinding('screen')
|
const {screen, Screen} = process.atomBinding('screen')
|
||||||
|
|
||||||
// Screen is an EventEmitter.
|
// Screen is an EventEmitter.
|
||||||
Object.setPrototypeOf(Screen.prototype, EventEmitter.prototype)
|
Object.setPrototypeOf(Screen.prototype, EventEmitter.prototype)
|
||||||
EventEmitter.call(screen)
|
EventEmitter.call(screen)
|
||||||
|
|
||||||
|
const nativeFn = screen.getMenuBarHeight
|
||||||
|
screen.getMenuBarHeight = function () {
|
||||||
|
if (!process.noDeprecations) {
|
||||||
|
deprecate.warn('screen.getMenuBarHeight', 'screen.getPrimaryDisplay().workArea')
|
||||||
|
}
|
||||||
|
return nativeFn.call(this)
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = screen
|
module.exports = screen
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -47,16 +47,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 = {...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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,8 +177,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())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,12 @@ class CrashReporter {
|
|||||||
|
|
||||||
getLastCrashReport () {
|
getLastCrashReport () {
|
||||||
const reports = this.getUploadedReports()
|
const reports = this.getUploadedReports()
|
||||||
|
.sort((a, b) => {
|
||||||
|
const ats = (a && a.date) ? new Date(a.date).getTime() : 0
|
||||||
|
const bts = (b && b.date) ? new Date(b.date).getTime() : 0
|
||||||
|
return bts - ats
|
||||||
|
})
|
||||||
|
|
||||||
return (reports.length > 0) ? reports[0] : null
|
return (reports.length > 0) ? reports[0] : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,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)
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ const getWebPreferences = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { remote } = require('electron')
|
const { remote } = require('electron')
|
||||||
webPreferences = remote.getCurrentWindow().webContents.getWebPreferences()
|
webPreferences = remote.getCurrentWebContents().getLastWebPreferences()
|
||||||
return webPreferences
|
return webPreferences
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "electron",
|
"name": "electron",
|
||||||
"version": "1.8.2-beta.2",
|
"version": "2.0.0-beta.4",
|
||||||
"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": {
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
"remark-cli": "^4.0.0",
|
"remark-cli": "^4.0.0",
|
||||||
"remark-preset-lint-markdown-style-guide": "^2.1.1",
|
"remark-preset-lint-markdown-style-guide": "^2.1.1",
|
||||||
"request": "^2.68.0",
|
"request": "^2.68.0",
|
||||||
|
"serve": "^6.5.3",
|
||||||
"standard": "^10.0.0",
|
"standard": "^10.0.0",
|
||||||
"standard-markdown": "^4.0.0",
|
"standard-markdown": "^4.0.0",
|
||||||
"sumchecker": "^2.0.2",
|
"sumchecker": "^2.0.2",
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ const circleCIJobs = [
|
|||||||
'electron-linux-arm',
|
'electron-linux-arm',
|
||||||
'electron-linux-arm64',
|
'electron-linux-arm64',
|
||||||
'electron-linux-ia32',
|
'electron-linux-ia32',
|
||||||
'electron-linux-mips64el',
|
// 'electron-linux-mips64el',
|
||||||
'electron-linux-x64'
|
'electron-linux-x64'
|
||||||
]
|
]
|
||||||
|
|
||||||
const jenkinsJobs = [
|
const jenkinsJobs = [
|
||||||
'electron-mas-x64-release',
|
'electron-release'
|
||||||
'electron-osx-x64-release'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
async function makeRequest (requestOptions, parseResponse) {
|
async function makeRequest (requestOptions, parseResponse) {
|
||||||
@@ -38,7 +37,7 @@ async function makeRequest (requestOptions, parseResponse) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function circleCIcall (buildUrl, targetBranch, job, ghRelease) {
|
async function circleCIcall (buildUrl, targetBranch, job, options) {
|
||||||
assert(process.env.CIRCLE_TOKEN, 'CIRCLE_TOKEN not found in environment')
|
assert(process.env.CIRCLE_TOKEN, 'CIRCLE_TOKEN not found in environment')
|
||||||
console.log(`Triggering CircleCI to run build job: ${job} on branch: ${targetBranch} with release flag.`)
|
console.log(`Triggering CircleCI to run build job: ${job} on branch: ${targetBranch} with release flag.`)
|
||||||
let buildRequest = {
|
let buildRequest = {
|
||||||
@@ -47,12 +46,16 @@ async function circleCIcall (buildUrl, targetBranch, job, ghRelease) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ghRelease) {
|
if (options.ghRelease) {
|
||||||
buildRequest.build_parameters.ELECTRON_RELEASE = 1
|
buildRequest.build_parameters.ELECTRON_RELEASE = 1
|
||||||
} else {
|
} else {
|
||||||
buildRequest.build_parameters.RUN_RELEASE_BUILD = 'true'
|
buildRequest.build_parameters.RUN_RELEASE_BUILD = 'true'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.automaticRelease) {
|
||||||
|
buildRequest.build_parameters.AUTO_RELEASE = 'true'
|
||||||
|
}
|
||||||
|
|
||||||
let circleResponse = await makeRequest({
|
let circleResponse = await makeRequest({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: buildUrl,
|
url: buildUrl,
|
||||||
@@ -67,17 +70,21 @@ async function circleCIcall (buildUrl, targetBranch, job, ghRelease) {
|
|||||||
console.log(`Check ${circleResponse.build_url} for status. (${job})`)
|
console.log(`Check ${circleResponse.build_url} for status. (${job})`)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildAppVeyor (targetBranch, ghRelease) {
|
async function buildAppVeyor (targetBranch, options) {
|
||||||
console.log(`Triggering AppVeyor to run build on branch: ${targetBranch} with release flag.`)
|
console.log(`Triggering AppVeyor to run build on branch: ${targetBranch} with release flag.`)
|
||||||
assert(process.env.APPVEYOR_TOKEN, 'APPVEYOR_TOKEN not found in environment')
|
assert(process.env.APPVEYOR_TOKEN, 'APPVEYOR_TOKEN not found in environment')
|
||||||
let environmentVariables = {}
|
let environmentVariables = {}
|
||||||
|
|
||||||
if (ghRelease) {
|
if (options.ghRelease) {
|
||||||
environmentVariables.ELECTRON_RELEASE = 1
|
environmentVariables.ELECTRON_RELEASE = 1
|
||||||
} else {
|
} else {
|
||||||
environmentVariables.RUN_RELEASE_BUILD = 'true'
|
environmentVariables.RUN_RELEASE_BUILD = 'true'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.automaticRelease) {
|
||||||
|
environmentVariables.AUTO_RELEASE = 'true'
|
||||||
|
}
|
||||||
|
|
||||||
const requestOpts = {
|
const requestOpts = {
|
||||||
url: buildAppVeyorURL,
|
url: buildAppVeyorURL,
|
||||||
auth: {
|
auth: {
|
||||||
@@ -101,27 +108,27 @@ async function buildAppVeyor (targetBranch, ghRelease) {
|
|||||||
console.log(`AppVeyor release build request successful. Check build status at ${buildUrl}`)
|
console.log(`AppVeyor release build request successful. Check build status at ${buildUrl}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildCircleCI (targetBranch, ghRelease, job) {
|
function buildCircleCI (targetBranch, options) {
|
||||||
const circleBuildUrl = `https://circleci.com/api/v1.1/project/github/electron/electron/tree/${targetBranch}?circle-token=${process.env.CIRCLE_TOKEN}`
|
const circleBuildUrl = `https://circleci.com/api/v1.1/project/github/electron/electron/tree/${targetBranch}?circle-token=${process.env.CIRCLE_TOKEN}`
|
||||||
if (job) {
|
if (options.job) {
|
||||||
assert(circleCIJobs.includes(job), `Unknown CI job name: ${job}.`)
|
assert(circleCIJobs.includes(options.job), `Unknown CI job name: ${options.job}.`)
|
||||||
circleCIcall(circleBuildUrl, targetBranch, job, ghRelease)
|
circleCIcall(circleBuildUrl, targetBranch, options.job, options)
|
||||||
} else {
|
} else {
|
||||||
circleCIJobs.forEach((job) => circleCIcall(circleBuildUrl, targetBranch, job, ghRelease))
|
circleCIJobs.forEach((job) => circleCIcall(circleBuildUrl, targetBranch, job, options))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildJenkins (targetBranch, ghRelease, job) {
|
async function buildJenkins (targetBranch, options) {
|
||||||
assert(process.env.JENKINS_AUTH_TOKEN, 'JENKINS_AUTH_TOKEN not found in environment')
|
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')
|
assert(process.env.JENKINS_BUILD_TOKEN, 'JENKINS_BUILD_TOKEN not found in environment')
|
||||||
let jenkinsCrumb = await getJenkinsCrumb()
|
let jenkinsCrumb = await getJenkinsCrumb()
|
||||||
|
|
||||||
if (job) {
|
if (options.job) {
|
||||||
assert(jenkinsJobs.includes(job), `Unknown CI job name: ${job}.`)
|
assert(jenkinsJobs.includes(options.job), `Unknown CI job name: ${options.job}.`)
|
||||||
callJenkinsBuild(job, jenkinsCrumb, targetBranch, ghRelease)
|
callJenkinsBuild(options.job, jenkinsCrumb, targetBranch, options)
|
||||||
} else {
|
} else {
|
||||||
jenkinsJobs.forEach((job) => {
|
jenkinsJobs.forEach((job) => {
|
||||||
callJenkinsBuild(job, jenkinsCrumb, targetBranch, ghRelease)
|
callJenkinsBuild(job, jenkinsCrumb, targetBranch, options)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,15 +151,18 @@ async function callJenkins (path, requestParameters, requestHeaders) {
|
|||||||
return jenkinsResponse
|
return jenkinsResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
async function callJenkinsBuild (job, jenkinsCrumb, targetBranch, ghRelease) {
|
async function callJenkinsBuild (job, jenkinsCrumb, targetBranch, options) {
|
||||||
console.log(`Triggering Jenkins to run build job: ${job} on branch: ${targetBranch} with release flag.`)
|
console.log(`Triggering Jenkins to run build job: ${job} on branch: ${targetBranch} with release flag.`)
|
||||||
let jenkinsParams = {
|
let jenkinsParams = {
|
||||||
token: process.env.JENKINS_BUILD_TOKEN,
|
token: process.env.JENKINS_BUILD_TOKEN,
|
||||||
BRANCH: targetBranch
|
BRANCH: targetBranch
|
||||||
}
|
}
|
||||||
if (!ghRelease) {
|
if (!options.ghRelease) {
|
||||||
jenkinsParams.RUN_RELEASE_BUILD = 1
|
jenkinsParams.RUN_RELEASE_BUILD = 1
|
||||||
}
|
}
|
||||||
|
if (options.automaticRelease) {
|
||||||
|
jenkinsParams.AUTO_RELEASE = 'true'
|
||||||
|
}
|
||||||
await callJenkins(`job/${job}/buildWithParameters`, jenkinsParams, jenkinsCrumb)
|
await callJenkins(`job/${job}/buildWithParameters`, jenkinsParams, jenkinsCrumb)
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(`Error calling Jenkins build`, err)
|
console.log(`Error calling Jenkins build`, err)
|
||||||
@@ -177,33 +187,35 @@ function runRelease (targetBranch, options) {
|
|||||||
if (options.ci) {
|
if (options.ci) {
|
||||||
switch (options.ci) {
|
switch (options.ci) {
|
||||||
case 'CircleCI': {
|
case 'CircleCI': {
|
||||||
buildCircleCI(targetBranch, options.ghRelease, options.job)
|
buildCircleCI(targetBranch, options)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'AppVeyor': {
|
case 'AppVeyor': {
|
||||||
buildAppVeyor(targetBranch, options.ghRelease)
|
buildAppVeyor(targetBranch, options)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'Jenkins': {
|
case 'Jenkins': {
|
||||||
buildJenkins(targetBranch, options.ghRelease, options.job)
|
buildJenkins(targetBranch, options)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buildCircleCI(targetBranch, options.ghRelease, options.job)
|
buildCircleCI(targetBranch, options)
|
||||||
buildAppVeyor(targetBranch, options.ghRelease)
|
buildAppVeyor(targetBranch, options)
|
||||||
buildJenkins(targetBranch, options.ghRelease, options.job)
|
buildJenkins(targetBranch, options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = runRelease
|
module.exports = runRelease
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
const args = require('minimist')(process.argv.slice(2), { boolean: 'ghRelease' })
|
const args = require('minimist')(process.argv.slice(2), {
|
||||||
|
boolean: ['ghRelease', 'automaticRelease']
|
||||||
|
})
|
||||||
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|Jenkins] [--ghRelease] [--automaticRelease] TARGET_BRANCH
|
||||||
`)
|
`)
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
|
from config import is_verbose_mode
|
||||||
from dbusmock import DBusTestCase
|
from dbusmock import DBusTestCase
|
||||||
|
|
||||||
import atexit
|
import atexit
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def cleanup():
|
def cleanup():
|
||||||
DBusTestCase.stop_dbus(DBusTestCase.system_bus_pid)
|
DBusTestCase.stop_dbus(DBusTestCase.system_bus_pid)
|
||||||
|
DBusTestCase.stop_dbus(DBusTestCase.session_bus_pid)
|
||||||
|
|
||||||
|
|
||||||
atexit.register(cleanup)
|
atexit.register(cleanup)
|
||||||
|
|
||||||
|
dbusmock_log = sys.stdout if is_verbose_mode() else open(os.devnull, 'w')
|
||||||
|
|
||||||
DBusTestCase.start_system_bus()
|
DBusTestCase.start_system_bus()
|
||||||
# create a mock for "org.freedesktop.login1" using python-dbusmock
|
DBusTestCase.spawn_server_template('logind', None, dbusmock_log)
|
||||||
# preconfigured template
|
|
||||||
(logind_mock, logind) = DBusTestCase.spawn_server_template('logind')
|
DBusTestCase.start_session_bus()
|
||||||
|
DBusTestCase.spawn_server_template('notification_daemon', None, dbusmock_log)
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
require('colors')
|
require('colors')
|
||||||
const args = require('minimist')(process.argv.slice(2))
|
const args = require('minimist')(process.argv.slice(2), {
|
||||||
|
boolean: ['automaticRelease', 'notesOnly', 'stable']
|
||||||
|
})
|
||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const ciReleaseBuild = require('./ci-release-build')
|
const ciReleaseBuild = require('./ci-release-build')
|
||||||
const { execSync } = require('child_process')
|
const { execSync } = require('child_process')
|
||||||
@@ -20,7 +22,7 @@ const versionType = args._[0]
|
|||||||
assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment')
|
assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment')
|
||||||
if (!versionType && !args.notesOnly) {
|
if (!versionType && !args.notesOnly) {
|
||||||
console.log(`Usage: prepare-release versionType [major | minor | patch | beta]` +
|
console.log(`Usage: prepare-release versionType [major | minor | patch | beta]` +
|
||||||
` (--stable) (--notesOnly)`)
|
` (--stable) (--notesOnly) (--automaticRelease)`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +78,12 @@ async function getReleaseNotes (currentBranch) {
|
|||||||
base: `v${pkg.version}`,
|
base: `v${pkg.version}`,
|
||||||
head: currentBranch
|
head: currentBranch
|
||||||
}
|
}
|
||||||
let releaseNotes = '(placeholder)\n'
|
let releaseNotes
|
||||||
|
if (args.automaticRelease) {
|
||||||
|
releaseNotes = '## Bug Fixes/Changes \n\n'
|
||||||
|
} else {
|
||||||
|
releaseNotes = '(placeholder)\n'
|
||||||
|
}
|
||||||
console.log(`Checking for commits from ${pkg.version} to ${currentBranch}`)
|
console.log(`Checking for commits from ${pkg.version} to ${currentBranch}`)
|
||||||
let commitComparison = await github.repos.compareCommits(githubOpts)
|
let commitComparison = await github.repos.compareCommits(githubOpts)
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
@@ -85,13 +92,45 @@ async function getReleaseNotes (currentBranch) {
|
|||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (commitComparison.data.commits.length === 0) {
|
||||||
|
console.log(`${pass} There are no commits from ${pkg.version} to ` +
|
||||||
|
`${currentBranch}, skipping release.`)
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
let prCount = 0
|
||||||
|
const mergeRE = /Merge pull request #(\d+) from .*\n/
|
||||||
|
const newlineRE = /(.*)\n*.*/
|
||||||
|
const prRE = /(.* )\(#(\d+)\)(?:.*)/
|
||||||
commitComparison.data.commits.forEach(commitEntry => {
|
commitComparison.data.commits.forEach(commitEntry => {
|
||||||
let commitMessage = commitEntry.commit.message
|
let commitMessage = commitEntry.commit.message
|
||||||
if (commitMessage.toLowerCase().indexOf('merge') > -1) {
|
if (commitMessage.indexOf('#') > -1) {
|
||||||
releaseNotes += `${commitMessage} \n`
|
let prMatch = commitMessage.match(mergeRE)
|
||||||
|
let prNumber
|
||||||
|
if (prMatch) {
|
||||||
|
commitMessage = commitMessage.replace(mergeRE, '').replace('\n', '')
|
||||||
|
let newlineMatch = commitMessage.match(newlineRE)
|
||||||
|
if (newlineMatch) {
|
||||||
|
commitMessage = newlineMatch[1]
|
||||||
|
}
|
||||||
|
prNumber = prMatch[1]
|
||||||
|
} else {
|
||||||
|
prMatch = commitMessage.match(prRE)
|
||||||
|
if (prMatch) {
|
||||||
|
commitMessage = prMatch[1].trim()
|
||||||
|
prNumber = prMatch[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (prMatch) {
|
||||||
|
if (commitMessage.substr(commitMessage.length - 1, commitMessage.length) !== '.') {
|
||||||
|
commitMessage += '.'
|
||||||
|
}
|
||||||
|
releaseNotes += `* ${commitMessage} #${prNumber} \n\n`
|
||||||
|
prCount++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log(`${pass} Done generating release notes for ${currentBranch}.`)
|
console.log(`${pass} Done generating release notes for ${currentBranch}. Found ${prCount} PRs.`)
|
||||||
return releaseNotes
|
return releaseNotes
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +191,8 @@ async function pushRelease () {
|
|||||||
|
|
||||||
async function runReleaseBuilds (branch) {
|
async function runReleaseBuilds (branch) {
|
||||||
await ciReleaseBuild(branch, {
|
await ciReleaseBuild(branch, {
|
||||||
ghRelease: true
|
ghRelease: true,
|
||||||
|
automaticRelease: args.automaticRelease
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +210,12 @@ async function tagRelease (version) {
|
|||||||
|
|
||||||
async function verifyNewVersion () {
|
async function verifyNewVersion () {
|
||||||
let newVersion = getNewVersion(true)
|
let newVersion = getNewVersion(true)
|
||||||
let response = await promptForVersion(newVersion)
|
let response
|
||||||
|
if (args.automaticRelease) {
|
||||||
|
response = 'y'
|
||||||
|
} else {
|
||||||
|
response = await promptForVersion(newVersion)
|
||||||
|
}
|
||||||
if (response.match(/^y/i)) {
|
if (response.match(/^y/i)) {
|
||||||
console.log(`${pass} Starting release of ${newVersion}`)
|
console.log(`${pass} Starting release of ${newVersion}`)
|
||||||
} else {
|
} else {
|
||||||
@@ -193,10 +238,15 @@ async function promptForVersion (version) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function prepareRelease (isBeta, notesOnly) {
|
async function prepareRelease (isBeta, notesOnly) {
|
||||||
|
if (args.automaticRelease && (pkg.version.indexOf('beta') === -1 ||
|
||||||
|
versionType !== 'beta')) {
|
||||||
|
console.log(`${fail} Automatic release is only supported for beta releases`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
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: \n${releaseNotes}`)
|
||||||
} else {
|
} else {
|
||||||
await verifyNewVersion()
|
await verifyNewVersion()
|
||||||
await createRelease(currentBranch, isBeta)
|
await createRelease(currentBranch, isBeta)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ const assert = require('assert')
|
|||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const { execSync } = require('child_process')
|
const { execSync } = require('child_process')
|
||||||
const GitHub = require('github')
|
const GitHub = require('github')
|
||||||
const { GitProcess } = require('dugite')
|
|
||||||
const nugget = require('nugget')
|
const nugget = require('nugget')
|
||||||
const pkg = require('../package.json')
|
const pkg = require('../package.json')
|
||||||
const pkgVersion = `v${pkg.version}`
|
const pkgVersion = `v${pkg.version}`
|
||||||
@@ -24,7 +23,6 @@ const github = new GitHub({
|
|||||||
followRedirects: false
|
followRedirects: false
|
||||||
})
|
})
|
||||||
github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN})
|
github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN})
|
||||||
const gitDir = path.resolve(__dirname, '..')
|
|
||||||
|
|
||||||
async function getDraftRelease (version, skipValidation) {
|
async function getDraftRelease (version, skipValidation) {
|
||||||
let releaseInfo = await github.repos.getReleases({owner: 'electron', repo: 'electron'})
|
let releaseInfo = await github.repos.getReleases({owner: 'electron', repo: 'electron'})
|
||||||
@@ -62,6 +60,7 @@ async function validateReleaseAssets (release, validatingRelease) {
|
|||||||
})
|
})
|
||||||
check((failureCount === 0), `All required GitHub assets exist for release`, true)
|
check((failureCount === 0), `All required GitHub assets exist for release`, true)
|
||||||
|
|
||||||
|
if (!validatingRelease || !release.draft) {
|
||||||
if (release.draft) {
|
if (release.draft) {
|
||||||
await verifyAssets(release)
|
await verifyAssets(release)
|
||||||
} else {
|
} else {
|
||||||
@@ -73,6 +72,7 @@ async function validateReleaseAssets (release, validatingRelease) {
|
|||||||
const s3Urls = s3UrlsForVersion(release.tag_name)
|
const s3Urls = s3UrlsForVersion(release.tag_name)
|
||||||
await verifyShasums(s3Urls, true)
|
await verifyShasums(s3Urls, true)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function check (condition, statement, exitIfFail = false) {
|
function check (condition, statement, exitIfFail = false) {
|
||||||
if (condition) {
|
if (condition) {
|
||||||
@@ -97,7 +97,7 @@ function assetsForVersion (version, validatingRelease) {
|
|||||||
`electron-${version}-linux-armv7l.zip`,
|
`electron-${version}-linux-armv7l.zip`,
|
||||||
`electron-${version}-linux-ia32-symbols.zip`,
|
`electron-${version}-linux-ia32-symbols.zip`,
|
||||||
`electron-${version}-linux-ia32.zip`,
|
`electron-${version}-linux-ia32.zip`,
|
||||||
`electron-${version}-linux-mips64el.zip`,
|
// `electron-${version}-linux-mips64el.zip`,
|
||||||
`electron-${version}-linux-x64-symbols.zip`,
|
`electron-${version}-linux-x64-symbols.zip`,
|
||||||
`electron-${version}-linux-x64.zip`,
|
`electron-${version}-linux-x64.zip`,
|
||||||
`electron-${version}-mas-x64-dsym.zip`,
|
`electron-${version}-mas-x64-dsym.zip`,
|
||||||
@@ -116,7 +116,7 @@ function assetsForVersion (version, validatingRelease) {
|
|||||||
`ffmpeg-${version}-linux-arm64.zip`,
|
`ffmpeg-${version}-linux-arm64.zip`,
|
||||||
`ffmpeg-${version}-linux-armv7l.zip`,
|
`ffmpeg-${version}-linux-armv7l.zip`,
|
||||||
`ffmpeg-${version}-linux-ia32.zip`,
|
`ffmpeg-${version}-linux-ia32.zip`,
|
||||||
`ffmpeg-${version}-linux-mips64el.zip`,
|
// `ffmpeg-${version}-linux-mips64el.zip`,
|
||||||
`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`,
|
||||||
@@ -148,7 +148,11 @@ function s3UrlsForVersion (version) {
|
|||||||
function checkVersion () {
|
function checkVersion () {
|
||||||
console.log(`Verifying that app version matches package version ${pkgVersion}.`)
|
console.log(`Verifying that app version matches package version ${pkgVersion}.`)
|
||||||
let startScript = path.join(__dirname, 'start.py')
|
let startScript = path.join(__dirname, 'start.py')
|
||||||
let appVersion = runScript(startScript, ['--version']).trim()
|
let scriptArgs = ['--version']
|
||||||
|
if (args.automaticRelease) {
|
||||||
|
scriptArgs.unshift('-R')
|
||||||
|
}
|
||||||
|
let appVersion = runScript(startScript, scriptArgs).trim()
|
||||||
check((pkgVersion.indexOf(appVersion) === 0), `App version ${appVersion} matches ` +
|
check((pkgVersion.indexOf(appVersion) === 0), `App version ${appVersion} matches ` +
|
||||||
`package version ${pkgVersion}.`, true)
|
`package version ${pkgVersion}.`, true)
|
||||||
}
|
}
|
||||||
@@ -276,7 +280,6 @@ async function makeRelease (releaseToValidate) {
|
|||||||
draftRelease = await getDraftRelease(pkgVersion, true)
|
draftRelease = await getDraftRelease(pkgVersion, true)
|
||||||
await validateReleaseAssets(draftRelease)
|
await validateReleaseAssets(draftRelease)
|
||||||
await publishRelease(draftRelease)
|
await publishRelease(draftRelease)
|
||||||
await cleanupReleaseBranch()
|
|
||||||
console.log(`${pass} SUCCESS!!! Release has been published. Please run ` +
|
console.log(`${pass} SUCCESS!!! Release has been published. Please run ` +
|
||||||
`"npm run publish-to-npm" to publish release to npm.`)
|
`"npm run publish-to-npm" to publish release to npm.`)
|
||||||
}
|
}
|
||||||
@@ -444,25 +447,4 @@ async function validateChecksums (validationArgs) {
|
|||||||
`shasums defined in ${validationArgs.shaSumFile}.`)
|
`shasums defined in ${validationArgs.shaSumFile}.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cleanupReleaseBranch () {
|
|
||||||
console.log(`Cleaning up release branch.`)
|
|
||||||
let errorMessage = `Could not delete local release branch.`
|
|
||||||
let successMessage = `Successfully deleted local release branch.`
|
|
||||||
await callGit(['branch', '-D', 'release'], errorMessage, successMessage)
|
|
||||||
errorMessage = `Could not delete remote release branch.`
|
|
||||||
successMessage = `Successfully deleted remote release branch.`
|
|
||||||
return callGit(['push', 'origin', ':release'], errorMessage, successMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function callGit (args, errorMessage, successMessage) {
|
|
||||||
let gitResult = await GitProcess.exec(args, gitDir)
|
|
||||||
if (gitResult.exitCode === 0) {
|
|
||||||
console.log(`${pass} ${successMessage}`)
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
console.log(`${fail} ${errorMessage} ${gitResult.stderr}`)
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
makeRelease(args.validateRelease)
|
makeRelease(args.validateRelease)
|
||||||
|
|||||||
56
script/serve-node-headers.py
Executable file
56
script/serve-node-headers.py
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import atexit
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import tarfile
|
||||||
|
import time
|
||||||
|
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
from lib.util import execute_stdout
|
||||||
|
|
||||||
|
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
||||||
|
DIST_DIR = os.path.join(SOURCE_ROOT, 'dist')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_args()
|
||||||
|
header_dir = os.path.join(DIST_DIR, args.version)
|
||||||
|
|
||||||
|
# Generate Headers
|
||||||
|
script_path = os.path.join(SOURCE_ROOT, 'script', 'create-node-headers.py')
|
||||||
|
execute_stdout([sys.executable, script_path, '--version', args.version,
|
||||||
|
'--directory', header_dir])
|
||||||
|
|
||||||
|
# Launch server
|
||||||
|
script_path = os.path.join(SOURCE_ROOT, 'node_modules', 'serve', 'bin',
|
||||||
|
'serve.js')
|
||||||
|
server = Popen(['node', script_path, '--port=' + args.port], stdout=PIPE,
|
||||||
|
cwd=DIST_DIR)
|
||||||
|
def cleanup():
|
||||||
|
server.kill()
|
||||||
|
atexit.register(cleanup)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Generate Checksums
|
||||||
|
script_path = os.path.join(SOURCE_ROOT, 'script', 'upload-node-checksums.py')
|
||||||
|
execute_stdout([sys.executable, script_path, '--version', args.version,
|
||||||
|
'--dist-url', 'http://localhost:' + args.port,
|
||||||
|
'--target-dir', header_dir])
|
||||||
|
|
||||||
|
print("Point your npm config at 'http://localhost:" + args.port + "'")
|
||||||
|
server.wait()
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser(description='create node header tarballs')
|
||||||
|
parser.add_argument('-v', '--version', help='Specify the version',
|
||||||
|
required=True)
|
||||||
|
parser.add_argument('-p', '--port', help='Specify port to run local server',
|
||||||
|
default='4321')
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
||||||
@@ -38,6 +38,7 @@ def main():
|
|||||||
|
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
enable_verbose_mode()
|
enable_verbose_mode()
|
||||||
|
os.environ['ELECTRON_ENABLE_LOGGING'] = '1'
|
||||||
|
|
||||||
spec_modules = os.path.join(SOURCE_ROOT, 'spec', 'node_modules')
|
spec_modules = os.path.join(SOURCE_ROOT, 'spec', 'node_modules')
|
||||||
if args.rebuild_native_modules or not os.path.isdir(spec_modules):
|
if args.rebuild_native_modules or not os.path.isdir(spec_modules):
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -49,7 +50,12 @@ CDS_FILE="clang-${PACKAGE_VERSION}.tgz"
|
|||||||
CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX)
|
CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX)
|
||||||
CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}"
|
CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}"
|
||||||
if [ "${OS}" = "Linux" ]; then
|
if [ "${OS}" = "Linux" ]; then
|
||||||
|
ARCH="$(uname -m)"
|
||||||
|
if [ "${ARCH}" = "aarch64" ]; then
|
||||||
|
CDS_FULL_URL="${S3_URL}/arm64/${CDS_FILE}"
|
||||||
|
else
|
||||||
CDS_FULL_URL="${CDS_URL}/Linux_x64/${CDS_FILE}"
|
CDS_FULL_URL="${CDS_URL}/Linux_x64/${CDS_FILE}"
|
||||||
|
fi
|
||||||
elif [ "${OS}" = "Darwin" ]; then
|
elif [ "${OS}" = "Darwin" ]; then
|
||||||
CDS_FULL_URL="${CDS_URL}/Mac/${CDS_FILE}"
|
CDS_FULL_URL="${CDS_URL}/Mac/${CDS_FILE}"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from lib.config import s3_config
|
from lib.config import s3_config
|
||||||
from lib.util import download, rm_rf, s3put
|
from lib.util import download, rm_rf, s3put, safe_mkdir
|
||||||
|
|
||||||
|
|
||||||
DIST_URL = 'https://atom.io/download/electron/'
|
DIST_URL = 'https://atom.io/download/electron/'
|
||||||
@@ -14,17 +15,23 @@ DIST_URL = 'https://atom.io/download/electron/'
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
|
dist_url = args.dist_url
|
||||||
|
if dist_url[-1] != "/":
|
||||||
|
dist_url += "/"
|
||||||
|
|
||||||
url = DIST_URL + args.version + '/'
|
url = dist_url + args.version + '/'
|
||||||
directory, files = download_files(url, get_files_list(args.version))
|
directory, files = download_files(url, get_files_list(args.version))
|
||||||
checksums = [
|
checksums = [
|
||||||
create_checksum('sha1', directory, 'SHASUMS.txt', files),
|
create_checksum('sha1', directory, 'SHASUMS.txt', files),
|
||||||
create_checksum('sha256', directory, 'SHASUMS256.txt', files)
|
create_checksum('sha256', directory, 'SHASUMS256.txt', files)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if args.target_dir is None:
|
||||||
bucket, access_key, secret_key = s3_config()
|
bucket, access_key, secret_key = s3_config()
|
||||||
s3put(bucket, access_key, secret_key, directory,
|
s3put(bucket, access_key, secret_key, directory,
|
||||||
'atom-shell/dist/{0}'.format(args.version), checksums)
|
'atom-shell/dist/{0}'.format(args.version), checksums)
|
||||||
|
else:
|
||||||
|
copy_files(checksums, args.target_dir)
|
||||||
|
|
||||||
rm_rf(directory)
|
rm_rf(directory)
|
||||||
|
|
||||||
@@ -33,27 +40,39 @@ def parse_args():
|
|||||||
parser = argparse.ArgumentParser(description='upload sumsha file')
|
parser = argparse.ArgumentParser(description='upload sumsha file')
|
||||||
parser.add_argument('-v', '--version', help='Specify the version',
|
parser.add_argument('-v', '--version', help='Specify the version',
|
||||||
required=True)
|
required=True)
|
||||||
|
parser.add_argument('-u', '--dist-url',
|
||||||
|
help='Specify the dist url for downloading',
|
||||||
|
required=False, default=DIST_URL)
|
||||||
|
parser.add_argument('-t', '--target-dir',
|
||||||
|
help='Specify target dir of checksums',
|
||||||
|
required=False)
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
def get_files_list(version):
|
def get_files_list(version):
|
||||||
return [
|
return [
|
||||||
'node-{0}.tar.gz'.format(version),
|
{ "filename": 'node-{0}.tar.gz'.format(version), "required": True },
|
||||||
'iojs-{0}.tar.gz'.format(version),
|
{ "filename": 'iojs-{0}.tar.gz'.format(version), "required": True },
|
||||||
'iojs-{0}-headers.tar.gz'.format(version),
|
{ "filename": 'iojs-{0}-headers.tar.gz'.format(version), "required": True },
|
||||||
'node.lib',
|
{ "filename": 'node.lib', "required": False },
|
||||||
'x64/node.lib',
|
{ "filename": 'x64/node.lib', "required": False },
|
||||||
'win-x86/iojs.lib',
|
{ "filename": 'win-x86/iojs.lib', "required": False },
|
||||||
'win-x64/iojs.lib',
|
{ "filename": 'win-x64/iojs.lib', "required": False }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def download_files(url, files):
|
def download_files(url, files):
|
||||||
directory = tempfile.mkdtemp(prefix='electron-tmp')
|
directory = tempfile.mkdtemp(prefix='electron-tmp')
|
||||||
return directory, [
|
result = []
|
||||||
download(f, url + f, os.path.join(directory, f))
|
for optional_f in files:
|
||||||
for f in files
|
required = optional_f.required
|
||||||
]
|
f = optional_f.filename
|
||||||
|
try:
|
||||||
|
result.append(download(f, url + f, os.path.join(directory, f)))
|
||||||
|
except Exception:
|
||||||
|
if required:
|
||||||
|
raise
|
||||||
|
|
||||||
|
return directory, result
|
||||||
|
|
||||||
|
|
||||||
def create_checksum(algorithm, directory, filename, files):
|
def create_checksum(algorithm, directory, filename, files):
|
||||||
@@ -69,6 +88,11 @@ def create_checksum(algorithm, directory, filename, files):
|
|||||||
f.write('\n'.join(lines) + '\n')
|
f.write('\n'.join(lines) + '\n')
|
||||||
return checksum_file
|
return checksum_file
|
||||||
|
|
||||||
|
def copy_files(source_files, output_dir):
|
||||||
|
for source_file in source_files:
|
||||||
|
output_path = os.path.join(output_dir, os.path.basename(source_file))
|
||||||
|
safe_mkdir(os.path.dirname(output_path))
|
||||||
|
shutil.copy2(source_file, output_path)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const path = require('path')
|
|||||||
const {ipcRenderer, remote} = require('electron')
|
const {ipcRenderer, remote} = require('electron')
|
||||||
const {closeWindow} = require('./window-helpers')
|
const {closeWindow} = require('./window-helpers')
|
||||||
|
|
||||||
const {app, BrowserWindow, ipcMain} = remote
|
const {app, BrowserWindow, Menu, ipcMain} = remote
|
||||||
|
|
||||||
const isCI = remote.getGlobal('isCi')
|
const isCI = remote.getGlobal('isCi')
|
||||||
|
|
||||||
@@ -158,24 +158,26 @@ describe('app module', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('exits gracefully on macos', function (done) {
|
it('exits gracefully', function (done) {
|
||||||
if (process.platform !== 'darwin') {
|
if (!['darwin', 'linux'].includes(process.platform)) {
|
||||||
this.skip()
|
this.skip()
|
||||||
}
|
}
|
||||||
const appPath = path.join(__dirname, 'fixtures', 'api', 'singleton')
|
|
||||||
const electronPath = remote.getGlobal('process').execPath
|
const electronPath = remote.getGlobal('process').execPath
|
||||||
|
const appPath = path.join(__dirname, 'fixtures', 'api', 'singleton')
|
||||||
appProcess = ChildProcess.spawn(electronPath, [appPath])
|
appProcess = ChildProcess.spawn(electronPath, [appPath])
|
||||||
appProcess.stdout.once('data', () => {
|
|
||||||
// The apple script will try to terminate the app
|
// Singleton will send us greeting data to let us know it's running.
|
||||||
// If there's an error terminating the app, then it will print to stderr
|
// After that, ask it to exit gracefully and confirm that it does.
|
||||||
ChildProcess.exec('osascript -e \'quit app "Electron"\'', (err, stdout, stderr) => {
|
appProcess.stdout.on('data', (data) => appProcess.kill())
|
||||||
assert(!err)
|
appProcess.on('exit', (code, sig) => {
|
||||||
assert(!stderr.trim())
|
let message = ['code:', code, 'sig:', sig].join('\n')
|
||||||
|
assert.equal(code, 0, message)
|
||||||
|
assert.equal(sig, null, message)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
|
||||||
|
|
||||||
describe('app.makeSingleInstance', () => {
|
describe('app.makeSingleInstance', () => {
|
||||||
it('prevents the second launch of app', function (done) {
|
it('prevents the second launch of app', function (done) {
|
||||||
@@ -491,6 +493,12 @@ describe('app module', () => {
|
|||||||
describe('select-client-certificate event', () => {
|
describe('select-client-certificate event', () => {
|
||||||
let w = null
|
let w = null
|
||||||
|
|
||||||
|
before(function () {
|
||||||
|
if (process.platform === 'linux') {
|
||||||
|
this.skip()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
w = new BrowserWindow({
|
w = new BrowserWindow({
|
||||||
show: false,
|
show: false,
|
||||||
@@ -881,4 +889,18 @@ describe('app module', () => {
|
|||||||
}, /before app is ready/)
|
}, /before app is ready/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('dock.setMenu', () => {
|
||||||
|
before(function () {
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
this.skip()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('keeps references to the menu', () => {
|
||||||
|
app.dock.setMenu(new Menu())
|
||||||
|
const v8Util = process.atomBinding('v8_util')
|
||||||
|
v8Util.requestGarbageCollectionForTesting()
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -733,6 +733,12 @@ describe('BrowserWindow module', () => {
|
|||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('throws when called on itself', () => {
|
||||||
|
assert.throws(() => {
|
||||||
|
w.addTabbedWindow(w)
|
||||||
|
}, /AddTabbedWindow cannot be called by a window on itself./)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('BrowserWindow.setVibrancy(type)', () => {
|
describe('BrowserWindow.setVibrancy(type)', () => {
|
||||||
@@ -2959,7 +2965,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`)
|
||||||
|
|||||||
@@ -259,8 +259,20 @@ describe('crashReporter module', () => {
|
|||||||
describe('getLastCrashReport', () => {
|
describe('getLastCrashReport', () => {
|
||||||
it('correctly returns the most recent report', () => {
|
it('correctly returns the most recent report', () => {
|
||||||
const reports = crashReporter.getUploadedReports()
|
const reports = crashReporter.getUploadedReports()
|
||||||
const lastReport = reports[0]
|
const lastReport = crashReporter.getLastCrashReport()
|
||||||
assert(lastReport != null)
|
|
||||||
|
// Let's find the newest report
|
||||||
|
const newestReport = reports.reduce((acc, cur) => {
|
||||||
|
const timestamp = new Date(cur.date).getTime()
|
||||||
|
return (timestamp > acc.timestamp)
|
||||||
|
? { report: cur, timestamp: timestamp }
|
||||||
|
: acc
|
||||||
|
}, { timestamp: 0 })
|
||||||
|
|
||||||
|
assert(reports.length > 1, 'has more than 1 report')
|
||||||
|
assert(lastReport != null, 'found a last report')
|
||||||
|
assert(lastReport.date.toString() === newestReport.report.date.toString(),
|
||||||
|
'last report is correct')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
122
spec/api-notification-dbus-spec.js
Normal file
122
spec/api-notification-dbus-spec.js
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
// For these tests we use a fake DBus daemon to verify libnotify interaction
|
||||||
|
// with the session bus. This requires python-dbusmock to be installed and
|
||||||
|
// running at $DBUS_SESSION_BUS_ADDRESS.
|
||||||
|
//
|
||||||
|
// script/test.py spawns dbusmock, which sets DBUS_SESSION_BUS_ADDRESS.
|
||||||
|
//
|
||||||
|
// See https://pypi.python.org/pypi/python-dbusmock to read about dbusmock.
|
||||||
|
|
||||||
|
const assert = require('assert')
|
||||||
|
const dbus = require('dbus-native')
|
||||||
|
const Promise = require('bluebird')
|
||||||
|
|
||||||
|
const {remote} = require('electron')
|
||||||
|
const {app} = remote.require('electron')
|
||||||
|
|
||||||
|
const skip = process.platform !== 'linux' ||
|
||||||
|
process.arch === 'ia32' ||
|
||||||
|
!process.env.DBUS_SESSION_BUS_ADDRESS;
|
||||||
|
|
||||||
|
(skip ? describe.skip : describe)('Notification module (dbus)', () => {
|
||||||
|
let mock, Notification, getCalls, reset
|
||||||
|
const realAppName = app.getName()
|
||||||
|
const realAppVersion = app.getVersion()
|
||||||
|
const appName = 'api-notification-dbus-spec'
|
||||||
|
const serviceName = 'org.freedesktop.Notifications'
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
// init app
|
||||||
|
app.setName(appName)
|
||||||
|
app.setDesktopName(appName + '.desktop')
|
||||||
|
// init dbus
|
||||||
|
const path = '/org/freedesktop/Notifications'
|
||||||
|
const iface = 'org.freedesktop.DBus.Mock'
|
||||||
|
const bus = dbus.sessionBus()
|
||||||
|
console.log('session bus: ' + process.env.DBUS_SESSION_BUS_ADDRESS)
|
||||||
|
const service = bus.getService(serviceName)
|
||||||
|
const getInterface = Promise.promisify(service.getInterface, {context: service})
|
||||||
|
mock = await getInterface(path, iface)
|
||||||
|
getCalls = Promise.promisify(mock.GetCalls, {context: mock})
|
||||||
|
reset = Promise.promisify(mock.Reset, {context: mock})
|
||||||
|
})
|
||||||
|
|
||||||
|
after(async () => {
|
||||||
|
// cleanup dbus
|
||||||
|
await reset()
|
||||||
|
// cleanup app
|
||||||
|
app.setName(realAppName)
|
||||||
|
app.setVersion(realAppVersion)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Notification module using ' + serviceName, () => {
|
||||||
|
function onMethodCalled (done) {
|
||||||
|
function cb (name) {
|
||||||
|
console.log('onMethodCalled: ' + name)
|
||||||
|
if (name === 'Notify') {
|
||||||
|
mock.removeListener('MethodCalled', cb)
|
||||||
|
console.log('done')
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cb
|
||||||
|
}
|
||||||
|
|
||||||
|
function unmarshalDBusNotifyHints (dbusHints) {
|
||||||
|
let o = {}
|
||||||
|
for (let hint of dbusHints) {
|
||||||
|
let key = hint[0]
|
||||||
|
let value = hint[1][1][0]
|
||||||
|
o[key] = value
|
||||||
|
}
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
function unmarshalDBusNotifyArgs (dbusArgs) {
|
||||||
|
return {
|
||||||
|
app_name: dbusArgs[0][1][0],
|
||||||
|
replaces_id: dbusArgs[1][1][0],
|
||||||
|
app_icon: dbusArgs[2][1][0],
|
||||||
|
title: dbusArgs[3][1][0],
|
||||||
|
body: dbusArgs[4][1][0],
|
||||||
|
actions: dbusArgs[5][1][0],
|
||||||
|
hints: unmarshalDBusNotifyHints(dbusArgs[6][1][0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
before((done) => {
|
||||||
|
mock.on('MethodCalled', onMethodCalled(done))
|
||||||
|
// lazy load Notification after we listen to MethodCalled mock signal
|
||||||
|
Notification = require('electron').remote.Notification
|
||||||
|
const n = new Notification({
|
||||||
|
title: 'title',
|
||||||
|
subtitle: 'subtitle',
|
||||||
|
body: 'body',
|
||||||
|
replyPlaceholder: 'replyPlaceholder',
|
||||||
|
sound: 'sound',
|
||||||
|
closeButtonText: 'closeButtonText'
|
||||||
|
})
|
||||||
|
n.show()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should call ' + serviceName + ' to show notifications', async () => {
|
||||||
|
const calls = await getCalls()
|
||||||
|
assert(calls.length >= 1)
|
||||||
|
let lastCall = calls[calls.length - 1]
|
||||||
|
let methodName = lastCall[1]
|
||||||
|
assert.equal(methodName, 'Notify')
|
||||||
|
let args = unmarshalDBusNotifyArgs(lastCall[2])
|
||||||
|
assert.deepEqual(args, {
|
||||||
|
app_name: appName,
|
||||||
|
replaces_id: 0,
|
||||||
|
app_icon: '',
|
||||||
|
title: 'title',
|
||||||
|
body: 'body',
|
||||||
|
actions: [],
|
||||||
|
hints: {
|
||||||
|
'append': 'true',
|
||||||
|
'desktop-entry': appName
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -18,17 +18,4 @@ describe('screen module', () => {
|
|||||||
assert(display.size.height > 0)
|
assert(display.size.height > 0)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('screen.getMenuBarHeight()', () => {
|
|
||||||
before(function () {
|
|
||||||
if (process.platform !== 'darwin') {
|
|
||||||
this.skip()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
it('returns an integer', () => {
|
|
||||||
const screenHeight = screen.getMenuBarHeight()
|
|
||||||
assert.equal(typeof screenHeight, 'number')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -116,6 +116,16 @@ describe('webContents module', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('getWebPreferences() API', () => {
|
||||||
|
it('should not crash when called for devTools webContents', (done) => {
|
||||||
|
w.webContents.openDevTools()
|
||||||
|
w.webContents.once('devtools-opened', () => {
|
||||||
|
assert(!w.devToolsWebContents.getWebPreferences())
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('before-input-event event', () => {
|
describe('before-input-event event', () => {
|
||||||
it('can prevent document keyboard events', (done) => {
|
it('can prevent document keyboard events', (done) => {
|
||||||
w.loadURL(`file://${path.join(__dirname, 'fixtures', 'pages', 'key-events.html')}`)
|
w.loadURL(`file://${path.join(__dirname, 'fixtures', 'pages', 'key-events.html')}`)
|
||||||
|
|||||||
@@ -134,7 +134,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()
|
||||||
@@ -142,7 +147,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())
|
||||||
}
|
}
|
||||||
@@ -221,6 +226,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) => {
|
||||||
@@ -241,6 +266,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) => {
|
||||||
@@ -260,7 +305,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()
|
||||||
@@ -482,7 +527,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) => {
|
||||||
@@ -491,7 +536,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) => {
|
||||||
|
|||||||
2
spec/fixtures/api/singleton/main.js
vendored
2
spec/fixtures/api/singleton/main.js
vendored
@@ -1,6 +1,8 @@
|
|||||||
const {app} = require('electron')
|
const {app} = require('electron')
|
||||||
|
|
||||||
|
app.once('ready', () => {
|
||||||
console.log('started') // ping parent
|
console.log('started') // ping parent
|
||||||
|
})
|
||||||
|
|
||||||
const shouldExit = app.makeSingleInstance(() => {
|
const shouldExit = app.makeSingleInstance(() => {
|
||||||
process.nextTick(() => app.exit(0))
|
process.nextTick(() => app.exit(0))
|
||||||
|
|||||||
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>
|
||||||
@@ -30,7 +30,8 @@ describe('modules support', () => {
|
|||||||
|
|
||||||
describe('ffi', () => {
|
describe('ffi', () => {
|
||||||
before(function () {
|
before(function () {
|
||||||
if (!nativeModulesEnabled || process.platform === 'win32') {
|
if (!nativeModulesEnabled || process.platform === 'win32' ||
|
||||||
|
process.arch === 'arm64') {
|
||||||
this.skip()
|
this.skip()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -183,10 +183,17 @@ describe('node feature', () => {
|
|||||||
|
|
||||||
describe('setInterval called under Chromium event loop in browser process', () => {
|
describe('setInterval called under Chromium event loop in browser process', () => {
|
||||||
it('can be scheduled in time', (done) => {
|
it('can be scheduled in time', (done) => {
|
||||||
let clear
|
let interval = null
|
||||||
let interval
|
let clearing = false
|
||||||
clear = () => {
|
const clear = () => {
|
||||||
|
if (interval === null || clearing) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// interval might trigger while clearing (remote is slow sometimes)
|
||||||
|
clearing = true
|
||||||
remote.getGlobal('clearInterval')(interval)
|
remote.getGlobal('clearInterval')(interval)
|
||||||
|
clearing = false
|
||||||
|
interval = null
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
interval = remote.getGlobal('setInterval')(clear, 10)
|
interval = remote.getGlobal('setInterval')(clear, 10)
|
||||||
|
|||||||
@@ -51,7 +51,11 @@
|
|||||||
if (!process.env.MOCHA_REPORTER) {
|
if (!process.env.MOCHA_REPORTER) {
|
||||||
mocha.ui('bdd').reporter(isCi ? 'tap' : 'html')
|
mocha.ui('bdd').reporter(isCi ? 'tap' : 'html')
|
||||||
}
|
}
|
||||||
|
if (process.env.MOCHA_TIMEOUT && process.env.MOCHA_TIMEOUT > 0) {
|
||||||
|
mocha.timeout(process.env.MOCHA_TIMEOUT)
|
||||||
|
} else {
|
||||||
mocha.timeout(isCi ? 30000 : 10000)
|
mocha.timeout(isCi ? 30000 : 10000)
|
||||||
|
}
|
||||||
|
|
||||||
const query = Mocha.utils.parseQuery(window.location.search || '')
|
const query = Mocha.utils.parseQuery(window.location.search || '')
|
||||||
if (query.grep) mocha.grep(query.grep)
|
if (query.grep) mocha.grep(query.grep)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ function getDate () {
|
|||||||
|
|
||||||
function getInfoForCurrentVersion () {
|
function getInfoForCurrentVersion () {
|
||||||
var json = {}
|
var json = {}
|
||||||
json.version = process.versions['atom-shell']
|
json.version = process.versions.electron
|
||||||
json.date = getDate()
|
json.date = getDate()
|
||||||
|
|
||||||
var names = ['node', 'v8', 'uv', 'zlib', 'openssl', 'modules', 'chrome']
|
var names = ['node', 'v8', 'uv', 'zlib', 'openssl', 'modules', 'chrome']
|
||||||
|
|||||||
2
vendor/libchromiumcontent
vendored
2
vendor/libchromiumcontent
vendored
Submodule vendor/libchromiumcontent updated: db1b314c01...5e61586b61
Reference in New Issue
Block a user