mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
29 Commits
v2.0.0-bet
...
v1.3.11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
650867772a | ||
|
|
13d2fc9c81 | ||
|
|
04a846a106 | ||
|
|
cb84d26d20 | ||
|
|
78cf807cf0 | ||
|
|
f3de3334cf | ||
|
|
a9d5a1d771 | ||
|
|
2356577614 | ||
|
|
94a5132b07 | ||
|
|
dca200d918 | ||
|
|
e86e7d699f | ||
|
|
922fcfb3da | ||
|
|
1d35151353 | ||
|
|
cb9fdc45e6 | ||
|
|
2dafd845b9 | ||
|
|
9017f90b57 | ||
|
|
b94638894e | ||
|
|
8a3288d791 | ||
|
|
6f5336c63f | ||
|
|
73c1fab423 | ||
|
|
1e36ee918e | ||
|
|
1f49da7a06 | ||
|
|
037a458e1d | ||
|
|
03a274ee27 | ||
|
|
c4bd516b77 | ||
|
|
4c914c1277 | ||
|
|
e3688a8e9d | ||
|
|
375534cf4a | ||
|
|
397e5ad0ac |
@@ -1,446 +0,0 @@
|
||||
|
||||
version: 2
|
||||
jobs:
|
||||
electron-linux-arm:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.4
|
||||
environment:
|
||||
TARGET_ARCH: arm
|
||||
resource_class: 2xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||
echo 'release build triggered from api'
|
||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
||||
fi
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
||||
echo 'Uploading Electron release distribution to github releases'
|
||||
script/upload.py
|
||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution to s3'
|
||||
script/upload.py --upload_to_s3
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Zip out directory
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
zip -r electron.zip out/D
|
||||
fi
|
||||
- persist_to_workspace:
|
||||
root: /home/builduser
|
||||
paths:
|
||||
- project/out
|
||||
- store_artifacts:
|
||||
path: electron.zip
|
||||
electron-linux-arm-test:
|
||||
machine: true
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- checkout
|
||||
- run:
|
||||
name: Test in ARM docker container
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
docker run -it \
|
||||
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
||||
--rm electronbuilds/electronarm7:0.0.4 > version.txt
|
||||
cat version.txt
|
||||
if grep -q `script/get-version.py` version.txt; then
|
||||
echo "Versions match"
|
||||
else
|
||||
echo "Versions do not match"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Skipping test for release build"
|
||||
fi
|
||||
electron-linux-arm64:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.4
|
||||
environment:
|
||||
TARGET_ARCH: arm64
|
||||
resource_class: 2xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||
echo 'release build triggered from api'
|
||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
||||
fi
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
||||
echo 'Uploading Electron release distribution to github releases'
|
||||
script/upload.py
|
||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution to s3'
|
||||
script/upload.py --upload_to_s3
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Zip out directory
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
zip -r electron.zip out/D
|
||||
fi
|
||||
- persist_to_workspace:
|
||||
root: /home/builduser
|
||||
paths:
|
||||
- project/out
|
||||
- store_artifacts:
|
||||
path: electron.zip
|
||||
electron-linux-arm64-test:
|
||||
machine: true
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- checkout
|
||||
- run:
|
||||
name: Test in ARM64 docker container
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
docker run -it \
|
||||
--mount type=bind,source=/tmp/workspace,target=/tmp/workspace \
|
||||
--rm electronbuilds/electronarm64:0.0.5 > version.txt
|
||||
cat version.txt
|
||||
if grep -q `script/get-version.py` version.txt; then
|
||||
echo "Versions match"
|
||||
else
|
||||
echo "Versions do not match"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Skipping test for release build"
|
||||
fi
|
||||
electron-linux-ia32:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.4
|
||||
environment:
|
||||
TARGET_ARCH: ia32
|
||||
DISPLAY: ':99.0'
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Setup for headless testing
|
||||
command: sh -e /etc/init.d/xvfb start
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||
echo 'release build triggered from api'
|
||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
||||
fi
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
||||
echo 'Uploading Electron release distribution to github releases'
|
||||
script/upload.py
|
||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution to s3'
|
||||
script/upload.py --upload_to_s3
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Test
|
||||
environment:
|
||||
MOCHA_FILE: junit/test-results.xml
|
||||
MOCHA_REPORTER: mocha-junit-reporter
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Testing Electron debug build'
|
||||
out/D/electron --version
|
||||
mkdir junit
|
||||
script/test.py --ci --rebuild_native_modules
|
||||
else
|
||||
echo 'Skipping testing on release build'
|
||||
fi
|
||||
- run:
|
||||
name: Verify FFmpeg
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Verifying ffmpeg on debug build'
|
||||
script/verify-ffmpeg.py
|
||||
else
|
||||
echo 'Skipping verify ffmpeg on release build'
|
||||
fi
|
||||
electron-linux-mips64el:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.4
|
||||
environment:
|
||||
TARGET_ARCH: mips64el
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||
echo 'release build triggered from api'
|
||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
||||
fi
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
||||
echo 'Uploading Electron release distribution to github releases'
|
||||
script/upload.py
|
||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution to s3'
|
||||
script/upload.py --upload_to_s3
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
|
||||
electron-linux-x64:
|
||||
docker:
|
||||
- image: electronbuilds/electron:0.0.4
|
||||
environment:
|
||||
TARGET_ARCH: x64
|
||||
DISPLAY: ':99.0'
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Setup for headless testing
|
||||
command: sh -e /etc/init.d/xvfb start
|
||||
- run:
|
||||
name: Check for release
|
||||
command: |
|
||||
if [ -n "${RUN_RELEASE_BUILD}" ]; then
|
||||
echo 'release build triggered from api'
|
||||
echo 'export ELECTRON_RELEASE=1 TRIGGERED_BY_API=1' >> $BASH_ENV
|
||||
fi
|
||||
- run:
|
||||
name: Bootstrap
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Bootstrapping Electron for release build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH
|
||||
else
|
||||
echo 'Bootstrapping Electron for debug build'
|
||||
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
|
||||
fi
|
||||
- run: npm run lint
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Building Electron for release'
|
||||
script/build.py -c R
|
||||
else
|
||||
echo 'Building Electron for debug'
|
||||
script/build.py -c D
|
||||
fi
|
||||
- run:
|
||||
name: Create distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ]; then
|
||||
echo 'Creating Electron release distribution'
|
||||
script/create-dist.py
|
||||
else
|
||||
echo 'Skipping create distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Upload distribution
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" != "1" ]; then
|
||||
echo 'Uploading Electron release distribution to github releases'
|
||||
script/upload.py
|
||||
elif [ "$ELECTRON_RELEASE" == "1" ] && [ "$TRIGGERED_BY_API" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution to s3'
|
||||
script/upload.py --upload_to_s3
|
||||
else
|
||||
echo 'Skipping upload distribution because build is not for release'
|
||||
fi
|
||||
- run:
|
||||
name: Test
|
||||
environment:
|
||||
MOCHA_FILE: junit/test-results.xml
|
||||
MOCHA_REPORTER: mocha-junit-reporter
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Testing Electron debug build'
|
||||
mkdir junit
|
||||
script/test.py --ci --rebuild_native_modules
|
||||
else
|
||||
echo 'Skipping testing on release build'
|
||||
fi
|
||||
- run:
|
||||
name: Verify FFmpeg
|
||||
command: |
|
||||
if [ "$ELECTRON_RELEASE" != "1" ]; then
|
||||
echo 'Verifying ffmpeg on debug build'
|
||||
script/verify-ffmpeg.py
|
||||
else
|
||||
echo 'Skipping verify ffmpeg on release build'
|
||||
fi
|
||||
- run:
|
||||
name: Generate Typescript Definitions
|
||||
command: npm run create-typescript-definitions
|
||||
- store_test_results:
|
||||
path: junit
|
||||
- store_artifacts:
|
||||
path: junit
|
||||
- store_artifacts:
|
||||
path: out/electron.d.ts
|
||||
- store_artifacts:
|
||||
path: out/electron-api.json
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build-arm:
|
||||
jobs:
|
||||
- electron-linux-arm
|
||||
- electron-linux-arm-test:
|
||||
requires:
|
||||
- electron-linux-arm
|
||||
build-arm64:
|
||||
jobs:
|
||||
- electron-linux-arm64
|
||||
- electron-linux-arm64-test:
|
||||
requires:
|
||||
- electron-linux-arm64
|
||||
build-ia32:
|
||||
jobs:
|
||||
- electron-linux-ia32
|
||||
build-x64:
|
||||
jobs:
|
||||
- electron-linux-x64
|
||||
@@ -1,35 +0,0 @@
|
||||
# Defines the Chromium style for automatic reformatting.
|
||||
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
BasedOnStyle: Chromium
|
||||
# This defaults to 'Auto'. Explicitly set it for a while, so that
|
||||
# 'vector<vector<int> >' in existing files gets formatted to
|
||||
# 'vector<vector<int>>'. ('Auto' means that clang-format will only use
|
||||
# 'int>>' if the file already contains at least one such instance.)
|
||||
Standard: Cpp11
|
||||
# Make sure code like:
|
||||
# IPC_BEGIN_MESSAGE_MAP()
|
||||
# IPC_MESSAGE_HANDLER(WidgetHostViewHost_Update, OnUpdate)
|
||||
# IPC_END_MESSAGE_MAP()
|
||||
# gets correctly indented.
|
||||
MacroBlockBegin: "^\
|
||||
BEGIN_MSG_MAP|\
|
||||
BEGIN_MSG_MAP_EX|\
|
||||
BEGIN_SAFE_MSG_MAP_EX|\
|
||||
CR_BEGIN_MSG_MAP_EX|\
|
||||
IPC_BEGIN_MESSAGE_MAP|\
|
||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM|\
|
||||
IPC_PROTOBUF_MESSAGE_TRAITS_BEGIN|\
|
||||
IPC_STRUCT_BEGIN|\
|
||||
IPC_STRUCT_BEGIN_WITH_PARENT|\
|
||||
IPC_STRUCT_TRAITS_BEGIN|\
|
||||
POLPARAMS_BEGIN|\
|
||||
PPAPI_BEGIN_MESSAGE_MAP$"
|
||||
MacroBlockEnd: "^\
|
||||
CR_END_MSG_MAP|\
|
||||
END_MSG_MAP|\
|
||||
IPC_END_MESSAGE_MAP|\
|
||||
IPC_PROTOBUF_MESSAGE_TRAITS_END|\
|
||||
IPC_STRUCT_END|\
|
||||
IPC_STRUCT_TRAITS_END|\
|
||||
POLPARAMS_END|\
|
||||
PPAPI_END_MESSAGE_MAP$"
|
||||
@@ -1,3 +0,0 @@
|
||||
*
|
||||
!tools/xvfb-init.sh
|
||||
!tools/run-electron.sh
|
||||
21
.github/CODEOWNERS
vendored
21
.github/CODEOWNERS
vendored
@@ -1,21 +0,0 @@
|
||||
# Order is important. The LAST matching pattern has the MOST precedence.
|
||||
# gitignore style patterns are used, not globs.
|
||||
# https://help.github.com/articles/about-codeowners
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
# Everything that falls through the cracks:
|
||||
* @electron/reviewers
|
||||
|
||||
# filename patterns
|
||||
*browser_view* @electron/browserview
|
||||
*notification* @electron/notifications
|
||||
*pdf* @electron/printing
|
||||
*printing* @electron/printing
|
||||
*updater* @electron/updater
|
||||
|
||||
# directories
|
||||
/.github/ @electron/hubbers
|
||||
/default_app/ @electron/docs
|
||||
/docs/ @electron/docs
|
||||
/docs-translations/ @electron/i18n
|
||||
/npm/ @electron/hubbers
|
||||
35
.github/ISSUE_TEMPLATE.md
vendored
35
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,35 +0,0 @@
|
||||
<!--
|
||||
Thanks for opening an issue! A few things to keep in mind:
|
||||
|
||||
- The issue tracker is only for bugs and feature requests.
|
||||
- Before reporting a bug, please try reproducing your issue against
|
||||
the latest version of Electron.
|
||||
- If you need general advice, join our Slack: http://atom-slack.herokuapp.com
|
||||
-->
|
||||
|
||||
* Electron version:
|
||||
* Operating system:
|
||||
|
||||
### Expected behavior
|
||||
|
||||
<!-- What do you think should happen? -->
|
||||
|
||||
### Actual behavior
|
||||
|
||||
<!-- What actually happens? -->
|
||||
|
||||
### How to reproduce
|
||||
|
||||
<!--
|
||||
|
||||
Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run.
|
||||
|
||||
You can fork https://github.com/electron/electron-quick-start and include a link to the branch with your changes.
|
||||
|
||||
If you provide a URL, please list the commands required to clone/setup/run your repo e.g.
|
||||
|
||||
$ git clone $YOUR_URL -b $BRANCH
|
||||
$ npm install
|
||||
$ npm start || electron .
|
||||
|
||||
-->
|
||||
8
.github/PULL_REQUEST_TEMPLATE.md
vendored
8
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,8 +0,0 @@
|
||||
<!--
|
||||
Thank you for your Pull Request. Please provide a description above and review
|
||||
the requirements below.
|
||||
|
||||
Bug fixes and new features should include tests and possibly benchmarks.
|
||||
|
||||
Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md
|
||||
-->
|
||||
31
.github/config.yml
vendored
31
.github/config.yml
vendored
@@ -1,31 +0,0 @@
|
||||
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
|
||||
|
||||
# Comment to be posted to on first time issues
|
||||
newIssueWelcomeComment: |
|
||||
👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
|
||||
|
||||
To help make it easier for us to investigate your issue, please follow the [contributing guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md#submitting-issues).
|
||||
|
||||
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
|
||||
|
||||
# Comment to be posted to on PRs from first time contributors in your repository
|
||||
newPRWelcomeComment: |
|
||||
💖 Thanks for opening this pull request! 💖
|
||||
|
||||

|
||||
|
||||
Here is a list of things that will help get it across the finish line:
|
||||
- Follow the JavaScript, C++, and Python [coding style](https://github.com/electron/electron/blob/master/docs/development/coding-style.md).
|
||||
- Run `npm run lint` locally to catch formatting errors earlier.
|
||||
- Document any user-facing changes you've made following the [documentation styleguide](https://github.com/electron/electron/blob/master/docs/styleguide.md).
|
||||
- Include tests when adding/changing behavior.
|
||||
- Include screenshots and animated GIFs whenever possible.
|
||||
We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.
|
||||
|
||||
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
|
||||
|
||||
# Comment to be posted to on pull requests merged by a first time user
|
||||
firstPRMergeComment: >
|
||||
Congrats on merging your first pull request! 🎉🎉🎉
|
||||
|
||||
# It is recommend to include as many gifs and emojis as possible
|
||||
25
.github/stale.yml
vendored
25
.github/stale.yml
vendored
@@ -1,25 +0,0 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 45
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- fixme/bug
|
||||
- fixme/crash
|
||||
- fixme/regression
|
||||
- fixme/security
|
||||
- blocked
|
||||
- blocking-stable
|
||||
- needs-review
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity and is not currently prioritized. It will be closed
|
||||
in a week if no further activity occurs :)
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
If you still think this issue is relevant, please ping a maintainer or
|
||||
leave a comment!
|
||||
54
.gitignore
vendored
54
.gitignore
vendored
@@ -1,48 +1,30 @@
|
||||
.DS_Store
|
||||
.env
|
||||
.gclient_done
|
||||
**/.npmrc
|
||||
.tags*
|
||||
.vs/
|
||||
.vscode/
|
||||
*.log
|
||||
*.pyc
|
||||
*.sln
|
||||
*.swp
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
*.xcodeproj
|
||||
/.idea/
|
||||
/brightray/brightray.opensdf
|
||||
/brightray/brightray.sdf
|
||||
/brightray/brightray.sln
|
||||
/brightray/brightray.suo
|
||||
/brightray/brightray.v12.suo
|
||||
/brightray/brightray.vcxproj*
|
||||
/brightray/brightray.xcodeproj/
|
||||
/build/
|
||||
/dist/
|
||||
/external_binaries/
|
||||
/out/
|
||||
/vendor/.gclient
|
||||
/vendor/debian_jessie_amd64-sysroot/
|
||||
/vendor/debian_jessie_arm-sysroot/
|
||||
/vendor/debian_jessie_arm64-sysroot/
|
||||
/vendor/debian_jessie_i386-sysroot/
|
||||
/vendor/debian_jessie_mips64-sysroot/
|
||||
/vendor/brightray/vendor/download/
|
||||
/vendor/debian_wheezy_amd64-sysroot/
|
||||
/vendor/debian_wheezy_arm-sysroot/
|
||||
/vendor/debian_wheezy_i386-sysroot/
|
||||
/vendor/gcc-4.8.3-d197-n64-loongson/
|
||||
/vendor/readme-gcc483-loongson.txt
|
||||
/vendor/download/
|
||||
/vendor/llvm-build/
|
||||
/vendor/llvm/
|
||||
/vendor/npm/
|
||||
/vendor/python_26/
|
||||
/vendor/npm/
|
||||
/vendor/llvm/
|
||||
/vendor/llvm-build/
|
||||
/vendor/.gclient
|
||||
node_modules/
|
||||
SHASUMS256.txt
|
||||
**/package-lock.json
|
||||
*.xcodeproj
|
||||
*.swp
|
||||
*.pyc
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
.vs/
|
||||
.vscode/
|
||||
*.vcxproj
|
||||
*.vcxproj.user
|
||||
*.vcxproj.filters
|
||||
*.sln
|
||||
debug.log
|
||||
npm-debug.log
|
||||
14
.gitmodules
vendored
14
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
||||
[submodule "vendor/brightray"]
|
||||
path = vendor/brightray
|
||||
url = https://github.com/electron/brightray.git
|
||||
[submodule "vendor/node"]
|
||||
path = vendor/node
|
||||
url = https://github.com/electron/node.git
|
||||
@@ -9,7 +12,7 @@
|
||||
url = https://github.com/electron/chromium-breakpad.git
|
||||
[submodule "vendor/native_mate"]
|
||||
path = vendor/native_mate
|
||||
url = https://github.com/electron/native-mate.git
|
||||
url = https://github.com/zcbenz/native-mate.git
|
||||
[submodule "vendor/crashpad"]
|
||||
path = vendor/crashpad
|
||||
url = https://github.com/electron/crashpad.git
|
||||
@@ -19,12 +22,3 @@
|
||||
[submodule "vendor/boto"]
|
||||
path = vendor/boto
|
||||
url = https://github.com/boto/boto.git
|
||||
[submodule "vendor/pdf_viewer"]
|
||||
path = vendor/pdf_viewer
|
||||
url = https://github.com/electron/pdf-viewer.git
|
||||
[submodule "vendor/gyp"]
|
||||
path = vendor/gyp
|
||||
url = https://github.com/electron/gyp
|
||||
[submodule "vendor/libchromiumcontent"]
|
||||
path = vendor/libchromiumcontent
|
||||
url = https://github.com/electron/libchromiumcontent
|
||||
|
||||
@@ -1 +1 @@
|
||||
v8.2.1
|
||||
v6.3.0
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"plugins": [
|
||||
["remark-lint-code-block-style", "fenced"],
|
||||
["remark-lint-fenced-code-flag"]
|
||||
]
|
||||
}
|
||||
@@ -3,9 +3,6 @@ git:
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
before_install:
|
||||
- export BOTO_CONFIG=/dev/null
|
||||
|
||||
language: node_js
|
||||
node_js:
|
||||
- "4"
|
||||
@@ -22,8 +19,6 @@ matrix:
|
||||
env: TARGET_ARCH=arm
|
||||
- os: linux
|
||||
env: TARGET_ARCH=ia32
|
||||
- os: linux
|
||||
env: TARGET_ARCH=arm64
|
||||
allow_failures:
|
||||
- os: osx
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Contributor Covenant Code of Conduct:
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
@@ -40,7 +40,7 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor-Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version]
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: https://contributor-covenant.org
|
||||
[version]: https://contributor-covenant.org/version/1/4/
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
|
||||
@@ -1,56 +1,79 @@
|
||||
# Contributing to Electron
|
||||
|
||||
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/CONTRIBUTING.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/CONTRIBUTING.md)
|
||||
|
||||
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
|
||||
|
||||
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
|
||||
behavior to electron@github.com.
|
||||
behavior to atom@github.com.
|
||||
|
||||
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
|
||||
propose changes to this document in a pull request.
|
||||
|
||||
## [Issues](https://electronjs.org/docs/development/issues)
|
||||
## Submitting Issues
|
||||
|
||||
Issues are created [here](https://github.com/electron/electron/issues/new).
|
||||
* You can create an issue [here](https://github.com/electron/electron/issues/new),
|
||||
but before doing that please read the notes below and include as many details as
|
||||
possible with your report. If you can, please include:
|
||||
* The version of Electron you are using
|
||||
* The operating system you are using
|
||||
* If applicable, what you were doing when the issue arose and what you
|
||||
expected to happen
|
||||
* Other things that will help resolve your issue:
|
||||
* Screenshots and animated GIFs
|
||||
* Error output that appears in your terminal, dev tools or as an alert
|
||||
* Perform a [cursory search](https://github.com/electron/electron/issues?utf8=✓&q=is%3Aissue+)
|
||||
to see if a similar issue has already been submitted
|
||||
|
||||
* [How to Contribute in Issues](https://electronjs.org/docs/development/issues#how-to-contribute-in-issues)
|
||||
* [Asking for General Help](https://electronjs.org/docs/development/issues#asking-for-general-help)
|
||||
* [Submitting a Bug Report](https://electronjs.org/docs/development/issues#submitting-a-bug-report)
|
||||
* [Triaging a Bug Report](https://electronjs.org/docs/development/issues#triaging-a-bug-report)
|
||||
* [Resolving a Bug Report](https://electronjs.org/docs/development/issues#resolving-a-bug-report)
|
||||
## Submitting Pull Requests
|
||||
|
||||
### Issue Maintenance and Closure
|
||||
* If an issue is inactive for 45 days (no activity of any kind), it will be
|
||||
marked for closure with `stale`.
|
||||
* If after this label is applied, no further activity occurs in the next 7 days,
|
||||
the issue will be closed.
|
||||
* If an issue has been closed and you still feel it's relevant, feel free to
|
||||
ping a maintainer or add a comment!
|
||||
* Include screenshots and animated GIFs in your pull request whenever possible.
|
||||
* Follow the JavaScript, C++, and Python [coding style defined in docs](/docs/development/coding-style.md).
|
||||
* Write documentation in [Markdown](https://daringfireball.net/projects/markdown).
|
||||
See the [Documentation Styleguide](/docs/styleguide.md).
|
||||
* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages).
|
||||
|
||||
## [Pull Requests](https://electronjs.org/docs/development/pull-requests)
|
||||
## Styleguides
|
||||
|
||||
Pull Requests are the way concrete changes are made to the code, documentation,
|
||||
dependencies, and tools contained in the `electron/electron` repository.
|
||||
### General Code
|
||||
|
||||
* [Setting up your local environment](https://electronjs.org/docs/development/pull-requests#setting-up-your-local-environment)
|
||||
* [Step 1: Fork](https://electronjs.org/docs/development/pull-requests#step-1-fork)
|
||||
* [Step 2: Build](https://electronjs.org/docs/development/pull-requests#step-2-build)
|
||||
* [Step 3: Branch](https://electronjs.org/docs/development/pull-requests#step-3-branch)
|
||||
* [The Process of Making Changes](https://electronjs.org/docs/development/pull-requests#the-process-of-making-changes)
|
||||
* [Step 4: Code](https://electronjs.org/docs/development/pull-requests#step-4-code)
|
||||
* [Step 5: Commit](https://electronjs.org/docs/development/pull-requests#step-5-commit)
|
||||
* [Commit message guidelines](https://electronjs.org/docs/development/pull-requests#commit-message-guidelines)
|
||||
* [Step 6: Rebase](https://electronjs.org/docs/development/pull-requests#step-6-rebase)
|
||||
* [Step 7: Test](https://electronjs.org/docs/development/pull-requests#step-7-test)
|
||||
* [Step 8: Push](https://electronjs.org/docs/development/pull-requests#step-8-push)
|
||||
* [Step 8: Opening the Pull Request](https://electronjs.org/docs/development/pull-requests#step-8-opening-the-pull-request)
|
||||
* [Step 9: Discuss and Update](#step-9-discuss-and-update)
|
||||
* [Approval and Request Changes Workflow](https://electronjs.org/docs/development/pull-requests#approval-and-request-changes-workflow)
|
||||
* [Step 10: Landing](https://electronjs.org/docs/development/pull-requests#step-10-landing)
|
||||
* [Continuous Integration Testing](https://electronjs.org/docs/development/pull-requests#continuous-integration-testing)
|
||||
* End files with a newline.
|
||||
* Place requires in the following order:
|
||||
* Built in Node Modules (such as `path`)
|
||||
* Built in Electron Modules (such as `ipc`, `app`)
|
||||
* Local Modules (using relative paths)
|
||||
* Place class properties in the following order:
|
||||
* Class methods and properties (methods starting with a `@`)
|
||||
* Instance methods and properties
|
||||
* Avoid platform-dependent code:
|
||||
* Use `path.join()` to concatenate filenames.
|
||||
* Use `os.tmpdir()` rather than `/tmp` when you need to reference the
|
||||
temporary directory.
|
||||
* Using a plain `return` when returning explicitly at the end of a function.
|
||||
* Not `return null`, `return undefined`, `null`, or `undefined`
|
||||
|
||||
## Style Guides
|
||||
|
||||
See [Coding Style](https://electronjs.org/docs/development/coding-style) for information about which standards Electron adheres to in different parts of its codebase.
|
||||
### Git Commit Messages
|
||||
|
||||
* Use the present tense ("Add feature" not "Added feature")
|
||||
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
||||
* Limit the first line to 72 characters or less
|
||||
* Reference issues and pull requests liberally
|
||||
* When only changing documentation, include `[ci skip]` in the commit description
|
||||
* Consider starting the commit message with an applicable emoji:
|
||||
* :art: `:art:` when improving the format/structure of the code
|
||||
* :racehorse: `:racehorse:` when improving performance
|
||||
* :non-potable_water: `:non-potable_water:` when plugging memory leaks
|
||||
* :memo: `:memo:` when writing docs
|
||||
* :penguin: `:penguin:` when fixing something on Linux
|
||||
* :apple: `:apple:` when fixing something on macOS
|
||||
* :checkered_flag: `:checkered_flag:` when fixing something on Windows
|
||||
* :bug: `:bug:` when fixing a bug
|
||||
* :fire: `:fire:` when removing code or files
|
||||
* :green_heart: `:green_heart:` when fixing the CI build
|
||||
* :white_check_mark: `:white_check_mark:` when adding tests
|
||||
* :lock: `:lock:` when dealing with security
|
||||
* :arrow_up: `:arrow_up:` when upgrading dependencies
|
||||
* :arrow_down: `:arrow_down:` when downgrading dependencies
|
||||
* :shirt: `:shirt:` when removing linter warnings
|
||||
|
||||
21
Dockerfile
21
Dockerfile
@@ -1,21 +0,0 @@
|
||||
FROM electronbuilds/libchromiumcontent:0.0.4
|
||||
|
||||
USER root
|
||||
|
||||
# Set up HOME directory
|
||||
ENV HOME=/home
|
||||
RUN chmod a+rwx /home
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN apt-get update && apt-get install -y nodejs
|
||||
|
||||
# Install wget used by crash reporter
|
||||
RUN apt-get install -y wget
|
||||
|
||||
# Install python-dbusmock
|
||||
RUN apt-get install -y python-dbusmock
|
||||
|
||||
# Add xvfb init script
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
@@ -1,34 +0,0 @@
|
||||
FROM multiarch/debian-debootstrap:arm64-jessie
|
||||
|
||||
RUN apt-get update && apt-get install -y\
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
curl \
|
||||
gperf \
|
||||
libasound2 \
|
||||
libasound2-dev \
|
||||
libcap-dev \
|
||||
libcups2-dev \
|
||||
libdbus-1-dev \
|
||||
libgconf-2-4 \
|
||||
libgconf2-dev \
|
||||
libgnome-keyring-dev \
|
||||
libgtk-3-0 \
|
||||
libgtk-3-dev \
|
||||
libnotify-dev \
|
||||
libnss3 \
|
||||
libnss3-dev \
|
||||
libx11-xcb-dev \
|
||||
libxss1 \
|
||||
libxtst-dev \
|
||||
libxtst6 \
|
||||
python-dbusmock \
|
||||
wget \
|
||||
xvfb
|
||||
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
ADD tools/run-electron.sh /run-electron.sh
|
||||
RUN chmod a+x /run-electron.sh
|
||||
CMD sh /run-electron.sh
|
||||
@@ -1,40 +0,0 @@
|
||||
FROM multiarch/debian-debootstrap:armhf-jessie
|
||||
|
||||
RUN apt-get update && apt-get install -y\
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
curl \
|
||||
gperf \
|
||||
libasound2 \
|
||||
libasound2-dev \
|
||||
libcap-dev \
|
||||
libcups2-dev \
|
||||
libdbus-1-dev \
|
||||
libgconf-2-4 \
|
||||
libgconf2-dev \
|
||||
libgnome-keyring-dev \
|
||||
libgtk-3-0 \
|
||||
libgtk-3-dev \
|
||||
libnotify-dev \
|
||||
libnss3 \
|
||||
libnss3-dev \
|
||||
libx11-xcb-dev \
|
||||
libxss1 \
|
||||
libxtst-dev \
|
||||
libxtst6 \
|
||||
python-dbusmock \
|
||||
git \
|
||||
wget \
|
||||
xvfb
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN apt-get update && apt-get install -y nodejs
|
||||
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
ADD tools/run-electron.sh /run-electron.sh
|
||||
RUN chmod a+x /run-electron.sh
|
||||
|
||||
CMD sh /run-electron.sh
|
||||
@@ -1,20 +0,0 @@
|
||||
FROM electronbuilds/libchromiumcontent:0.0.4
|
||||
|
||||
USER root
|
||||
|
||||
# Install node.js
|
||||
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
|
||||
RUN apt-get update && apt-get install -y nodejs
|
||||
|
||||
# Install wget used by crash reporter
|
||||
RUN apt-get install -y wget
|
||||
|
||||
# Install python-dbusmock
|
||||
RUN apt-get install -y python-dbusmock
|
||||
|
||||
# Add xvfb init script
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
USER builduser
|
||||
WORKDIR /home/builduser
|
||||
2
ISSUE_TEMPLATE.md
Normal file
2
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,2 @@
|
||||
* Electron version:
|
||||
* Operating system:
|
||||
48
Jenkinsfile
vendored
48
Jenkinsfile
vendored
@@ -1,48 +0,0 @@
|
||||
pipeline {
|
||||
agent none
|
||||
stages {
|
||||
stage('Build') {
|
||||
parallel {
|
||||
stage('electron-osx-x64') {
|
||||
agent {
|
||||
label 'osx'
|
||||
}
|
||||
steps {
|
||||
timeout(60) {
|
||||
sh 'script/bootstrap.py --target_arch=x64 --dev'
|
||||
sh 'npm run lint'
|
||||
sh 'script/build.py -c D'
|
||||
sh 'script/test.py --ci --rebuild_native_modules'
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('electron-mas-x64') {
|
||||
agent {
|
||||
label 'osx'
|
||||
}
|
||||
environment {
|
||||
MAS_BUILD = '1'
|
||||
}
|
||||
steps {
|
||||
timeout(60) {
|
||||
sh 'script/bootstrap.py --target_arch=x64 --dev'
|
||||
sh 'npm run lint'
|
||||
sh 'script/build.py -c D'
|
||||
sh 'script/test.py --ci --rebuild_native_modules'
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013-2018 GitHub Inc.
|
||||
Copyright (c) 2014 GitHub Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
124
README.md
124
README.md
@@ -1,113 +1,81 @@
|
||||
[](https://electronjs.org)
|
||||
[](http://electron.atom.io/)
|
||||
|
||||
[](https://travis-ci.org/electron/electron)
|
||||
[](https://ci.appveyor.com/project/Atom/electron)
|
||||
[](https://david-dm.org/electron/electron#info=devDependencies)
|
||||
[](http://atom-slack.herokuapp.com/)
|
||||
|
||||
[](https://circleci.com/gh/electron/electron/tree/master)
|
||||
[](https://windows-ci.electronjs.org/project/AppVeyor/electron/branch/master)
|
||||
[](https://mac-ci.electronjs.org/blue/organizations/jenkins/Electron%20org%2Felectron/activity?branch=master)
|
||||
[](https://david-dm.org/electron/electron?type=dev)
|
||||
[](https://atom-slack.herokuapp.com/)
|
||||
|
||||
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹.
|
||||
View these docs in other languages at [electron/electron-i18n](https://github.com/electron/electron-i18n/tree/master/content/).
|
||||
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md)
|
||||
|
||||
The Electron framework lets you write cross-platform desktop applications
|
||||
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
|
||||
[Chromium](https://www.chromium.org) and is used by the [Atom
|
||||
editor](https://github.com/atom/atom) and many other [apps](https://electronjs.org/apps).
|
||||
[Chromium](http://www.chromium.org) and is used by the [Atom
|
||||
editor](https://github.com/atom/atom) and many other [apps](http://electron.atom.io/apps).
|
||||
|
||||
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
||||
announcements.
|
||||
|
||||
This project adheres to the Contributor Covenant
|
||||
[code of conduct](https://github.com/electron/electron/tree/master/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
|
||||
behavior to [electron@github.com](mailto:electron@github.com).
|
||||
behavior to electron@github.com.
|
||||
|
||||
## Installation
|
||||
## Downloads
|
||||
|
||||
To install prebuilt Electron binaries, use [`npm`](https://docs.npmjs.com/).
|
||||
The preferred method is to install Electron as a development dependency in your
|
||||
app:
|
||||
Prebuilt binaries and debug symbols of Electron for Linux, Windows and macOS can
|
||||
be found on the [releases](https://github.com/electron/electron/releases) page.
|
||||
|
||||
You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron
|
||||
binaries:
|
||||
|
||||
```sh
|
||||
npm install electron --save-dev --save-exact
|
||||
```
|
||||
# Install the `electron` command globally in your $PATH
|
||||
npm install electron -g
|
||||
|
||||
The `--save-exact` flag is recommended as Electron does not follow semantic
|
||||
versioning. For info on how to manage Electron versions in your apps, see
|
||||
[Electron versioning](docs/tutorial/electron-versioning.md).
|
||||
|
||||
For more installation options and troubleshooting tips, see
|
||||
[installation](docs/tutorial/installation.md).
|
||||
|
||||
## Quick start
|
||||
|
||||
Clone and run the
|
||||
[electron/electron-quick-start](https://github.com/electron/electron-quick-start)
|
||||
repository to see a minimal Electron app in action:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/electron/electron-quick-start
|
||||
cd electron-quick-start
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
## Resources for learning Electron
|
||||
|
||||
- [electronjs.org/docs](https://electronjs.org/docs) - all of Electron's documentation
|
||||
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - a very basic starter Electron app
|
||||
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - sample starter apps created by the community
|
||||
- [electron/simple-samples](https://github.com/electron/simple-samples) - small applications with ideas for taking them further
|
||||
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - an Electron app that teaches you how to use Electron
|
||||
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - small demo apps for the various Electron APIs
|
||||
|
||||
## Programmatic usage
|
||||
|
||||
Most people use Electron from the command line, but if you require `electron` inside
|
||||
your **Node app** (not your Electron app) it will return the file path to the
|
||||
binary. Use this to spawn Electron from Node scripts:
|
||||
|
||||
```javascript
|
||||
const electron = require('electron')
|
||||
const proc = require('child_process')
|
||||
|
||||
// will print something similar to /Users/maf/.../Electron
|
||||
console.log(electron)
|
||||
|
||||
// spawn Electron
|
||||
const child = proc.spawn(electron)
|
||||
# Install as a development dependency
|
||||
npm install electron --save-dev
|
||||
```
|
||||
|
||||
### Mirrors
|
||||
|
||||
- [China](https://npm.taobao.org/mirrors/electron)
|
||||
|
||||
## Documentation
|
||||
|
||||
Guides and the API reference are located in the
|
||||
[docs](https://github.com/electron/electron/tree/master/docs) directory. It also
|
||||
contains documents describing how to build and contribute to Electron.
|
||||
|
||||
## Documentation Translations
|
||||
|
||||
Find documentation translations in [electron/electron-i18n](https://github.com/electron/electron-i18n).
|
||||
- [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR)
|
||||
- [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR)
|
||||
- [Japanese](https://github.com/electron/electron/tree/master/docs-translations/jp)
|
||||
- [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es)
|
||||
- [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN)
|
||||
- [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW)
|
||||
- [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR)
|
||||
- [Ukrainian](https://github.com/electron/electron/tree/master/docs-translations/uk-UA)
|
||||
- [Russian](https://github.com/electron/electron/tree/master/docs-translations/ru-RU)
|
||||
- [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)
|
||||
|
||||
## Quick Start
|
||||
|
||||
Clone and run the [`electron/electron-quick-start`](https://github.com/electron/electron-quick-start)
|
||||
repository to see a minimal Electron app in action.
|
||||
|
||||
## Community
|
||||
|
||||
You can ask questions and interact with the community in the following
|
||||
locations:
|
||||
- [`electron`](https://discuss.atom.io/c/electron) category on the Atom
|
||||
- [`electron`](http://discuss.atom.io/c/electron) category on the Atom
|
||||
forums
|
||||
- `#atom-shell` channel on Freenode
|
||||
- [`Atom`](https://atom-slack.herokuapp.com) channel on Slack
|
||||
- [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*
|
||||
- [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack
|
||||
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
|
||||
- [`electron-kr`](https://electron-kr.github.io/electron-kr) *(Korean)*
|
||||
- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
|
||||
- [`electron-tr`](https://electron-tr.herokuapp.com) *(Turkish)*
|
||||
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)*
|
||||
- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(Japanese)*
|
||||
- [`electron-tr`](http://www.meetup.com/Electron-JS-Istanbul/) *(Turkish)*
|
||||
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
|
||||
- [`electron-pl`](https://electronpl.github.io) *(Poland)*
|
||||
|
||||
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)
|
||||
for a community maintained list of useful example apps, tools and resources.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](https://github.com/electron/electron/blob/master/LICENSE)
|
||||
|
||||
When using the Electron or other GitHub logos, be sure to follow the [GitHub logo guidelines](https://github.com/logos).
|
||||
|
||||
12
SECURITY.md
12
SECURITY.md
@@ -1,12 +0,0 @@
|
||||
# Reporting Security Issues
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Report security bugs in third-party modules to the person or team maintaining the module. You can also report a vulnerability through the [Node Security Project](https://nodesecurity.io/report).
|
||||
|
||||
## Learning More About Security
|
||||
To learn more about securing an Electron application, please see the [security tutorial](docs/tutorial/security.md).
|
||||
25
appveyor.yml
Normal file
25
appveyor.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
# appveyor file
|
||||
# http://www.appveyor.com/docs/appveyor-yml
|
||||
version: "{build}"
|
||||
|
||||
os: Visual Studio 2015
|
||||
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
install:
|
||||
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\14.0\bin\;%PATH%
|
||||
- cmd: SET PATH=C:\python27;%PATH%
|
||||
- cmd: python script/cibuild
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
# disable build and test pahses
|
||||
build: off
|
||||
test: off
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
@@ -19,13 +18,12 @@
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "pdf/pdf.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#include "third_party/widevine/cdm/stub/widevine_cdm_version.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
#include "chrome/common/widevine_cdm_constants.h"
|
||||
#endif
|
||||
|
||||
@@ -44,7 +42,7 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||
|
||||
std::vector<std::string> flash_version_numbers = base::SplitString(
|
||||
version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
if (flash_version_numbers.empty())
|
||||
if (flash_version_numbers.size() < 1)
|
||||
flash_version_numbers.push_back("11");
|
||||
// |SplitString()| puts in an empty string given an empty string. :(
|
||||
else if (flash_version_numbers[0].empty())
|
||||
@@ -73,7 +71,7 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
|
||||
return plugin;
|
||||
}
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
|
||||
const std::string& version) {
|
||||
content::PepperPluginInfo widevine_cdm;
|
||||
@@ -93,9 +91,9 @@ content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
|
||||
std::vector<std::string> codecs;
|
||||
codecs.push_back(kCdmSupportedCodecVp8);
|
||||
codecs.push_back(kCdmSupportedCodecVp9);
|
||||
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
|
||||
#if defined(USE_PROPRIETARY_CODECS)
|
||||
codecs.push_back(kCdmSupportedCodecAvc1);
|
||||
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
|
||||
#endif // defined(USE_PROPRIETARY_CODECS)
|
||||
std::string codec_string = base::JoinString(
|
||||
codecs, std::string(1, kCdmSupportedCodecsValueDelimiter));
|
||||
widevine_cdm_mime_type.additional_param_names.push_back(
|
||||
@@ -110,25 +108,6 @@ content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
|
||||
}
|
||||
#endif
|
||||
|
||||
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
content::PepperPluginInfo pdf_info;
|
||||
pdf_info.is_internal = true;
|
||||
pdf_info.is_out_of_process = true;
|
||||
pdf_info.name = "Chromium PDF Viewer";
|
||||
pdf_info.description = "Portable Document Format";
|
||||
pdf_info.path = base::FilePath::FromUTF8Unsafe(kPdfPluginPath);
|
||||
content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf",
|
||||
"Portable Document Format");
|
||||
pdf_info.mime_types.push_back(pdf_mime_type);
|
||||
pdf_info.internal_entry_points.get_interface = chrome_pdf::PPP_GetInterface;
|
||||
pdf_info.internal_entry_points.initialize_module =
|
||||
chrome_pdf::PPP_InitializeModule;
|
||||
pdf_info.internal_entry_points.shutdown_module =
|
||||
chrome_pdf::PPP_ShutdownModule;
|
||||
pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV;
|
||||
plugins->push_back(pdf_info);
|
||||
}
|
||||
|
||||
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
|
||||
const char* separator,
|
||||
const char* cmd_switch) {
|
||||
@@ -156,7 +135,7 @@ void AddPepperFlashFromCommandLine(
|
||||
plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
|
||||
}
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
void AddWidevineCdmFromCommandLine(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
@@ -198,28 +177,31 @@ base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||
return l10n_util::GetStringUTF16(message_id);
|
||||
}
|
||||
|
||||
void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
||||
schemes->standard_schemes.push_back("chrome-extension");
|
||||
|
||||
std::vector<std::string> splited;
|
||||
ConvertStringWithSeparatorToVector(&splited, ",",
|
||||
switches::kRegisterServiceWorkerSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->service_worker_schemes.push_back(scheme);
|
||||
schemes->service_worker_schemes.push_back(url::kFileScheme);
|
||||
|
||||
ConvertStringWithSeparatorToVector(&splited, ",", switches::kSecureSchemes);
|
||||
for (const std::string& scheme : splited)
|
||||
schemes->secure_schemes.push_back(scheme);
|
||||
void AtomContentClient::AddAdditionalSchemes(
|
||||
std::vector<url::SchemeWithType>* standard_schemes,
|
||||
std::vector<url::SchemeWithType>* referrer_schemes,
|
||||
std::vector<std::string>* savable_schemes) {
|
||||
standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT});
|
||||
}
|
||||
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
AddPepperFlashFromCommandLine(plugins);
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
AddWidevineCdmFromCommandLine(plugins);
|
||||
#endif
|
||||
ComputeBuiltInPlugins(plugins);
|
||||
}
|
||||
|
||||
void AtomContentClient::AddServiceWorkerSchemes(
|
||||
std::set<std::string>* service_worker_schemes) {
|
||||
std::vector<std::string> schemes;
|
||||
ConvertStringWithSeparatorToVector(&schemes, ",",
|
||||
switches::kRegisterServiceWorkerSchemes);
|
||||
if (!schemes.empty()) {
|
||||
for (const std::string& scheme : schemes)
|
||||
service_worker_schemes->insert(scheme);
|
||||
}
|
||||
service_worker_schemes->insert(url::kFileScheme);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -23,9 +23,14 @@ class AtomContentClient : public brightray::ContentClient {
|
||||
std::string GetProduct() const override;
|
||||
std::string GetUserAgent() const override;
|
||||
base::string16 GetLocalizedString(int message_id) const override;
|
||||
void AddAdditionalSchemes(Schemes* schemes) override;
|
||||
void AddAdditionalSchemes(
|
||||
std::vector<url::SchemeWithType>* standard_schemes,
|
||||
std::vector<url::SchemeWithType>* referrer_schemes,
|
||||
std::vector<std::string>* savable_schemes) override;
|
||||
void AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||
void AddServiceWorkerSchemes(
|
||||
std::set<std::string>* service_worker_schemes) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#if defined(OS_MACOSX)
|
||||
extern "C" {
|
||||
__attribute__((visibility("default")))
|
||||
int AtomMain(int argc, char* argv[]);
|
||||
int AtomMain(int argc, const char* argv[]);
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
int AtomInitializeICUandStartNode(int argc, char *argv[]);
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
int AtomMain(int argc, char* argv[]) {
|
||||
int AtomMain(int argc, const char* argv[]) {
|
||||
atom::AtomMainDelegate delegate;
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.argc = argc;
|
||||
params.argv = const_cast<const char**>(argv);
|
||||
params.argv = argv;
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
NSArray* pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents];
|
||||
pathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents count] - 4)];
|
||||
NSString* path = [NSString pathWithComponents:pathComponents];
|
||||
[[NSWorkspace sharedWorkspace] launchApplication:path];
|
||||
[pool drain];
|
||||
return 0;
|
||||
}
|
||||
@@ -4,23 +4,19 @@
|
||||
|
||||
#include "atom/app/atom_main.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h> // windows.h must be included first
|
||||
|
||||
#include <atlbase.h> // ensures that ATL statics like `_AtlWinModule` are initialized (it's an issue in static debug build)
|
||||
#include <shellapi.h>
|
||||
#include <shellscalingapi.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "atom/app/command_line_args.h"
|
||||
#include "atom/common/crash_reporter/win/crash_service_main.h"
|
||||
#include "base/environment.h"
|
||||
#include "base/process/launch.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/win/windows_version.h"
|
||||
#include "content/public/app/sandbox_helper_win.h"
|
||||
#include "sandbox/win/src/sandbox_types.h"
|
||||
@@ -38,9 +34,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef ENABLE_RUN_AS_NODE
|
||||
const auto kRunAsNode = "ELECTRON_RUN_AS_NODE";
|
||||
#endif
|
||||
const char* kRunAsNode = "ELECTRON_RUN_AS_NODE";
|
||||
|
||||
bool IsEnvSet(const char* name) {
|
||||
#if defined(OS_WIN)
|
||||
@@ -57,91 +51,58 @@ bool IsEnvSet(const char* name) {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
struct Arguments {
|
||||
int argc = 0;
|
||||
wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
int argc = 0;
|
||||
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
||||
|
||||
~Arguments() { LocalFree(argv); }
|
||||
} arguments;
|
||||
|
||||
if (!arguments.argv)
|
||||
return -1;
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Don't display assert dialog boxes in CI test runs
|
||||
static const auto kCI = "ELECTRON_CI";
|
||||
bool is_ci = IsEnvSet(kCI);
|
||||
if (!is_ci) {
|
||||
for (int i = 0; i < arguments.argc; ++i) {
|
||||
if (!_wcsicmp(arguments.argv[i], L"--ci")) {
|
||||
is_ci = true;
|
||||
_putenv_s(kCI, "1"); // set flag for child processes
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_ci) {
|
||||
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
|
||||
|
||||
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
|
||||
|
||||
_set_error_mode(_OUT_TO_STDERR);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_RUN_AS_NODE
|
||||
bool run_as_node = IsEnvSet(kRunAsNode);
|
||||
#else
|
||||
bool run_as_node = false;
|
||||
#endif
|
||||
|
||||
// Make sure the output is printed to console.
|
||||
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
|
||||
base::RouteStdioToConsole(false);
|
||||
|
||||
#ifndef DEBUG
|
||||
// Chromium has its own TLS subsystem which supports automatic destruction
|
||||
// of thread-local data, and also depends on memory allocation routines
|
||||
// provided by the CRT. The problem is that the auto-destruction mechanism
|
||||
// uses a hidden feature of the OS loader which calls a callback on thread
|
||||
// exit, but only after all loaded DLLs have been detached. Since the CRT is
|
||||
// also a DLL, it happens that by the time Chromium's `OnThreadExit` function
|
||||
// is called, the heap functions, though still in memory, no longer perform
|
||||
// their duties, and when Chromium calls `free` on its buffer, it triggers
|
||||
// an access violation error.
|
||||
// We work around this problem by invoking Chromium's `OnThreadExit` in time
|
||||
// from within the CRT's atexit facility, ensuring the heap functions are
|
||||
// still active. The second invocation from the OS loader will be a no-op.
|
||||
extern void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved);
|
||||
atexit([]() {
|
||||
OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr);
|
||||
});
|
||||
#endif
|
||||
// Convert argv to to UTF8
|
||||
char** argv = new char*[argc];
|
||||
for (int i = 0; i < argc; i++) {
|
||||
// Compute the size of the required buffer
|
||||
DWORD size = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wargv[i],
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (size == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
// Do the actual conversion
|
||||
argv[i] = new char[size];
|
||||
DWORD result = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wargv[i],
|
||||
-1,
|
||||
argv[i],
|
||||
size,
|
||||
NULL,
|
||||
NULL);
|
||||
if (result == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RUN_AS_NODE
|
||||
if (run_as_node) {
|
||||
std::vector<char*> argv(arguments.argc);
|
||||
std::transform(
|
||||
arguments.argv, arguments.argv + arguments.argc, argv.begin(),
|
||||
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
|
||||
|
||||
// Now that argv conversion is done, we can finally start.
|
||||
base::AtExitManager atexit_manager;
|
||||
base::i18n::InitializeICU();
|
||||
auto ret = atom::NodeMain(argv.size(), argv.data());
|
||||
std::for_each(argv.begin(), argv.end(), free);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
|
||||
return atom::NodeMain(argc, argv);
|
||||
} else if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
|
||||
return crash_service::Main(cmd);
|
||||
}
|
||||
|
||||
if (!atom::CheckCommandLineArguments(arguments.argc, arguments.argv))
|
||||
return -1;
|
||||
|
||||
sandbox::SandboxInterfaceInfo sandbox_info = {0};
|
||||
content::InitializeSandboxInfo(&sandbox_info);
|
||||
atom::AtomMainDelegate delegate;
|
||||
@@ -149,37 +110,34 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.instance = instance;
|
||||
params.sandbox_info = &sandbox_info;
|
||||
atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
atom::AtomCommandLine::InitW(argc, wargv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef ENABLE_RUN_AS_NODE
|
||||
int main(int argc, const char* argv[]) {
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
base::i18n::InitializeICU();
|
||||
base::AtExitManager atexit_manager;
|
||||
return atom::NodeMain(argc, argv);
|
||||
return atom::NodeMain(argc, const_cast<char**>(argv));
|
||||
}
|
||||
#endif
|
||||
|
||||
atom::AtomMainDelegate delegate;
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.argc = argc;
|
||||
params.argv = const_cast<const char**>(argv);
|
||||
params.argv = argv;
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
#else // defined(OS_LINUX)
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef ENABLE_RUN_AS_NODE
|
||||
int main(int argc, const char* argv[]) {
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
return AtomInitializeICUandStartNode(argc, argv);
|
||||
return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
|
||||
}
|
||||
#endif
|
||||
|
||||
return AtomMain(argc, argv);
|
||||
}
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/relauncher.h"
|
||||
#include "atom/common/google_api_key.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "atom/renderer/atom_renderer_client.h"
|
||||
#include "atom/renderer/atom_sandboxed_renderer_client.h"
|
||||
#include "atom/utility/atom_content_utility_client.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/debug/stack_trace.h"
|
||||
@@ -21,18 +19,9 @@
|
||||
#include "base/logging.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "ipc/ipc_features.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
|
||||
#define IPC_MESSAGE_MACROS_LOG_ENABLED
|
||||
#include "content/public/common/content_ipc_logging.h"
|
||||
#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
|
||||
content::RegisterIPCLogger(msg_id, logger)
|
||||
#include "atom/common/common_message_generator.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
@@ -40,7 +29,7 @@ namespace {
|
||||
const char* kRelauncherProcess = "relauncher";
|
||||
|
||||
bool IsBrowserProcess(base::CommandLine* cmd) {
|
||||
std::string process_type = cmd->GetSwitchValueASCII(::switches::kProcessType);
|
||||
std::string process_type = cmd->GetSwitchValueASCII(switches::kProcessType);
|
||||
return process_type.empty();
|
||||
}
|
||||
|
||||
@@ -83,7 +72,7 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
|
||||
// Only enable logging when --enable-logging is specified.
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
if (!command_line->HasSwitch(::switches::kEnableLogging) &&
|
||||
if (!command_line->HasSwitch(switches::kEnableLogging) &&
|
||||
!env->HasVar("ELECTRON_ENABLE_LOGGING")) {
|
||||
settings.logging_dest = logging::LOG_NONE;
|
||||
logging::SetMinLogLevel(logging::LOG_NUM_SEVERITIES);
|
||||
@@ -95,10 +84,9 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
logging::SetLogItems(true, false, true, false);
|
||||
|
||||
// Enable convient stack printing.
|
||||
#if defined(DEBUG) && defined(OS_LINUX)
|
||||
bool enable_stack_dumping = true;
|
||||
#else
|
||||
bool enable_stack_dumping = env->HasVar("ELECTRON_ENABLE_STACK_DUMPING");
|
||||
#if defined(DEBUG) && defined(OS_LINUX)
|
||||
enable_stack_dumping = true;
|
||||
#endif
|
||||
if (enable_stack_dumping)
|
||||
base::debug::EnableInProcessStackDumping();
|
||||
@@ -112,9 +100,6 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
#if defined(OS_WIN)
|
||||
// Ignore invalid parameter errors.
|
||||
_set_invalid_parameter_handler(InvalidParameterHandler);
|
||||
// Disable the ActiveVerifier, which is used by Chrome to track possible
|
||||
// bugs, but no use in Electron.
|
||||
base::win::DisableHandleVerifier();
|
||||
#endif
|
||||
|
||||
return brightray::MainDelegate::BasicStartupComplete(exit_code);
|
||||
@@ -130,25 +115,17 @@ void AtomMainDelegate::PreSandboxStartup() {
|
||||
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
std::string process_type = command_line->GetSwitchValueASCII(
|
||||
::switches::kProcessType);
|
||||
switches::kProcessType);
|
||||
|
||||
// Only append arguments for browser process.
|
||||
if (!IsBrowserProcess(command_line))
|
||||
return;
|
||||
|
||||
if (!command_line->HasSwitch(switches::kEnableMixedSandbox)) {
|
||||
if (command_line->HasSwitch(switches::kEnableSandbox)) {
|
||||
// Disable setuid sandbox since it is not longer required on
|
||||
// linux(namespace sandbox is available on most distros).
|
||||
command_line->AppendSwitch(::switches::kDisableSetuidSandbox);
|
||||
} else {
|
||||
// Disable renderer sandbox for most of node's functions.
|
||||
command_line->AppendSwitch(::switches::kNoSandbox);
|
||||
}
|
||||
}
|
||||
// Disable renderer sandbox for most of node's functions.
|
||||
command_line->AppendSwitch(switches::kNoSandbox);
|
||||
|
||||
// Allow file:// URIs to read other file:// URIs by default.
|
||||
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
|
||||
command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Enable AVFoundation.
|
||||
@@ -163,15 +140,7 @@ content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
|
||||
|
||||
content::ContentRendererClient*
|
||||
AtomMainDelegate::CreateContentRendererClient() {
|
||||
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kEnableSandbox) ||
|
||||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
::switches::kNoSandbox)) {
|
||||
renderer_client_.reset(new AtomSandboxedRendererClient);
|
||||
} else {
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
}
|
||||
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
return renderer_client_.get();
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ class AtomMainDelegate : public brightray::MainDelegate {
|
||||
void SetUpBundleOverrides();
|
||||
#endif
|
||||
|
||||
brightray::ContentClient content_client_;
|
||||
std::unique_ptr<content::ContentBrowserClient> browser_client_;
|
||||
std::unique_ptr<content::ContentRendererClient> renderer_client_;
|
||||
std::unique_ptr<content::ContentUtilityClient> utility_client_;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
#define ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
|
||||
#include "base/command_line.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
|
||||
@@ -2,24 +2,17 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifdef ENABLE_RUN_AS_NODE
|
||||
|
||||
#include "atom/app/node_main.h"
|
||||
|
||||
#include "atom/app/uv_task_runner.h"
|
||||
#include "atom/browser/javascript_environment.h"
|
||||
#include "atom/browser/node_debugger.h"
|
||||
#include "atom/common/api/atom_bindings.h"
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/task_scheduler/task_scheduler.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
#include "gin/v8_initializer.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
@@ -43,36 +36,20 @@ int NodeMain(int argc, char *argv[]) {
|
||||
|
||||
gin::V8Initializer::LoadV8Snapshot();
|
||||
gin::V8Initializer::LoadV8Natives();
|
||||
|
||||
// V8 requires a task scheduler apparently
|
||||
base::TaskScheduler::CreateAndStartWithDefaultParams("Electron");
|
||||
|
||||
// Initialize gin::IsolateHolder.
|
||||
JavascriptEnvironment gin_env;
|
||||
|
||||
int exec_argc;
|
||||
const char** exec_argv;
|
||||
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
||||
|
||||
node::IsolateData isolate_data(gin_env.isolate(), loop);
|
||||
node::Environment* env = node::CreateEnvironment(
|
||||
&isolate_data, gin_env.context(), argc, argv,
|
||||
gin_env.isolate(), loop, gin_env.context(), argc, argv,
|
||||
exec_argc, exec_argv);
|
||||
|
||||
// Enable support for v8 inspector.
|
||||
NodeDebugger node_debugger(env);
|
||||
node_debugger.Start(gin_env.platform());
|
||||
|
||||
mate::Dictionary process(gin_env.isolate(), env->process_object());
|
||||
#if defined(OS_WIN)
|
||||
process.SetMethod("log", &AtomBindings::Log);
|
||||
#endif
|
||||
process.SetMethod("crash", &AtomBindings::Crash);
|
||||
|
||||
// Setup process.crashReporter.start in child node processes
|
||||
auto reporter = mate::Dictionary::CreateEmpty(gin_env.isolate());
|
||||
reporter.SetMethod("start", &crash_reporter::CrashReporter::StartInstance);
|
||||
process.Set("crashReporter", reporter);
|
||||
// Start our custom debugger implementation.
|
||||
NodeDebugger node_debugger(gin_env.isolate());
|
||||
if (node_debugger.IsRunning())
|
||||
env->AssignToContext(v8::Debug::GetDebugContext());
|
||||
|
||||
node::LoadEnvironment(env);
|
||||
|
||||
@@ -96,18 +73,9 @@ int NodeMain(int argc, char *argv[]) {
|
||||
node::FreeEnvironment(env);
|
||||
}
|
||||
|
||||
// According to "src/gin/shell/gin_main.cc":
|
||||
//
|
||||
// gin::IsolateHolder waits for tasks running in TaskScheduler in its
|
||||
// destructor and thus must be destroyed before TaskScheduler starts skipping
|
||||
// CONTINUE_ON_SHUTDOWN tasks.
|
||||
base::TaskScheduler::GetInstance()->Shutdown();
|
||||
|
||||
v8::V8::Dispose();
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ENABLE_RUN_AS_NODE
|
||||
|
||||
@@ -5,14 +5,10 @@
|
||||
#ifndef ATOM_APP_NODE_MAIN_H_
|
||||
#define ATOM_APP_NODE_MAIN_H_
|
||||
|
||||
#ifdef ENABLE_RUN_AS_NODE
|
||||
|
||||
namespace atom {
|
||||
|
||||
int NodeMain(int argc, char *argv[]);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ENABLE_RUN_AS_NODE
|
||||
|
||||
#endif // ATOM_APP_NODE_MAIN_H_
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${ATOM_BUNDLE_ID}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>LSBackgroundOnly</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/app/uv_task_runner.h"
|
||||
|
||||
#include "base/stl_util.h"
|
||||
@@ -21,25 +19,25 @@ UvTaskRunner::~UvTaskRunner() {
|
||||
}
|
||||
|
||||
bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
auto* timer = new uv_timer_t;
|
||||
timer->data = this;
|
||||
uv_timer_init(loop_, timer);
|
||||
uv_timer_start(timer, UvTaskRunner::OnTimeout, delay.InMilliseconds(), 0);
|
||||
tasks_[timer] = std::move(task);
|
||||
tasks_[timer] = task;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UvTaskRunner::RunsTasksInCurrentSequence() const {
|
||||
bool UvTaskRunner::RunsTasksOnCurrentThread() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UvTaskRunner::PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) {
|
||||
return PostDelayedTask(from_here, std::move(task), delay);
|
||||
return PostDelayedTask(from_here, task, delay);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -48,7 +46,7 @@ void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
|
||||
if (!ContainsKey(self->tasks_, timer))
|
||||
return;
|
||||
|
||||
std::move(self->tasks_[timer]).Run();
|
||||
self->tasks_[timer].Run();
|
||||
self->tasks_.erase(timer);
|
||||
uv_timer_stop(timer);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(timer), UvTaskRunner::OnClose);
|
||||
|
||||
@@ -21,12 +21,12 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
|
||||
// base::SingleThreadTaskRunner:
|
||||
bool PostDelayedTask(const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) override;
|
||||
bool RunsTasksInCurrentSequence() const override;
|
||||
bool RunsTasksOnCurrentThread() const override;
|
||||
bool PostNonNestableDelayedTask(
|
||||
const tracked_objects::Location& from_here,
|
||||
base::OnceClosure task,
|
||||
const base::Closure& task,
|
||||
base::TimeDelta delay) override;
|
||||
|
||||
private:
|
||||
@@ -35,7 +35,7 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
|
||||
uv_loop_t* loop_;
|
||||
|
||||
std::map<uv_timer_t*, base::OnceClosure> tasks_;
|
||||
std::map<uv_timer_t*, base::Closure> tasks_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(UvTaskRunner);
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/login_handler.h"
|
||||
#include "atom/browser/relauncher.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
@@ -29,23 +30,15 @@
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/sys_info.h"
|
||||
#include "brightray/browser/brightray_paths.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/icon_manager.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/browser/gpu/compositor_util.h"
|
||||
#include "content/browser/gpu/gpu_data_manager_impl.h"
|
||||
#include "content/public/browser/browser_accessibility_state.h"
|
||||
#include "content/public/browser/browser_child_process_host.h"
|
||||
#include "content/public/browser/child_process_data.h"
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
#include "content/public/browser/gpu_data_manager.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "media/audio/audio_manager.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/ssl/client_cert_identity.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
@@ -55,10 +48,6 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "atom/browser/ui/cocoa/atom_bundle_mover.h"
|
||||
#endif
|
||||
|
||||
using atom::Browser;
|
||||
|
||||
namespace mate {
|
||||
@@ -308,8 +297,6 @@ struct Converter<Browser::LoginItemSettings> {
|
||||
|
||||
dict.Get("openAtLogin", &(out->open_at_login));
|
||||
dict.Get("openAsHidden", &(out->open_as_hidden));
|
||||
dict.Get("path", &(out->path));
|
||||
dict.Get("args", &(out->args));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -324,48 +311,15 @@ struct Converter<Browser::LoginItemSettings> {
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<content::CertificateRequestResultType> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
content::CertificateRequestResultType* out) {
|
||||
bool b;
|
||||
if (!ConvertFromV8(isolate, val, &b))
|
||||
return false;
|
||||
*out = b ? content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE :
|
||||
content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
class AppIdProcessIterator : public base::ProcessIterator {
|
||||
public:
|
||||
AppIdProcessIterator() : base::ProcessIterator(nullptr) {}
|
||||
|
||||
protected:
|
||||
bool IncludeEntry() override {
|
||||
return (entry().parent_pid() == base::GetCurrentProcId() ||
|
||||
entry().pid() == base::GetCurrentProcId());
|
||||
}
|
||||
};
|
||||
|
||||
IconLoader::IconSize GetIconSizeByString(const std::string& size) {
|
||||
if (size == "small") {
|
||||
return IconLoader::IconSize::SMALL;
|
||||
} else if (size == "large") {
|
||||
return IconLoader::IconSize::LARGE;
|
||||
}
|
||||
return IconLoader::IconSize::NORMAL;
|
||||
}
|
||||
|
||||
// Return the path constant from string.
|
||||
int GetPathConstant(const std::string& name) {
|
||||
if (name == "appData")
|
||||
@@ -376,8 +330,6 @@ int GetPathConstant(const std::string& name) {
|
||||
return brightray::DIR_CACHE;
|
||||
else if (name == "userCache")
|
||||
return brightray::DIR_USER_CACHE;
|
||||
else if (name == "logs")
|
||||
return brightray::DIR_APP_LOGS;
|
||||
else if (name == "home")
|
||||
return base::DIR_HOME;
|
||||
else if (name == "temp")
|
||||
@@ -421,32 +373,13 @@ bool NotificationCallbackWrapper(
|
||||
return !Browser::Get()->is_shutting_down();
|
||||
}
|
||||
|
||||
void GotPrivateKey(std::shared_ptr<content::ClientCertificateDelegate> delegate,
|
||||
scoped_refptr<net::X509Certificate> cert,
|
||||
scoped_refptr<net::SSLPrivateKey> private_key) {
|
||||
delegate->ContinueWithCertificate(cert, private_key);
|
||||
}
|
||||
|
||||
void OnClientCertificateSelected(
|
||||
v8::Isolate* isolate,
|
||||
std::shared_ptr<content::ClientCertificateDelegate> delegate,
|
||||
std::shared_ptr<net::ClientCertIdentityList> identities,
|
||||
mate::Arguments* args) {
|
||||
if (args->Length() == 2) {
|
||||
delegate->ContinueWithCertificate(nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> val;
|
||||
args->GetNext(&val);
|
||||
if (val->IsNull()) {
|
||||
delegate->ContinueWithCertificate(nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
mate::Dictionary cert_data;
|
||||
if (!mate::ConvertFromV8(isolate, val, &cert_data)) {
|
||||
args->ThrowError("Must pass valid certificate object.");
|
||||
if (!args->GetNext(&cert_data)) {
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -456,17 +389,8 @@ void OnClientCertificateSelected(
|
||||
|
||||
auto certs = net::X509Certificate::CreateCertificateListFromBytes(
|
||||
data.c_str(), data.length(), net::X509Certificate::FORMAT_AUTO);
|
||||
if (!certs.empty()) {
|
||||
scoped_refptr<net::X509Certificate> cert(certs[0].get());
|
||||
for (size_t i = 0; i < identities->size(); ++i) {
|
||||
if (cert->Equals((*identities)[i]->certificate())) {
|
||||
net::ClientCertIdentity::SelfOwningAcquirePrivateKey(
|
||||
std::move((*identities)[i]),
|
||||
base::Bind(&GotPrivateKey, delegate, std::move(cert)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (certs.size() > 0)
|
||||
delegate->ContinueWithCertificate(certs[0].get());
|
||||
}
|
||||
|
||||
void PassLoginInformation(scoped_refptr<LoginHandler> login_handler,
|
||||
@@ -491,8 +415,8 @@ int ImportIntoCertStore(
|
||||
|
||||
if (!cert_path.empty()) {
|
||||
if (base::ReadFileToString(base::FilePath(cert_path), &file_data)) {
|
||||
auto module = model->cert_db()->GetPrivateSlot();
|
||||
rv = model->ImportFromPKCS12(module.get(),
|
||||
auto module = model->cert_db()->GetPublicModule();
|
||||
rv = model->ImportFromPKCS12(module,
|
||||
file_data,
|
||||
password,
|
||||
true,
|
||||
@@ -511,34 +435,12 @@ int ImportIntoCertStore(
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnIconDataAvailable(v8::Isolate* isolate,
|
||||
const App::FileIconCallback& callback,
|
||||
gfx::Image* icon) {
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
if (icon && !icon->IsEmpty()) {
|
||||
callback.Run(v8::Null(isolate), *icon);
|
||||
} else {
|
||||
v8::Local<v8::String> error_message =
|
||||
v8::String::NewFromUtf8(isolate, "Failed to get file icon.");
|
||||
callback.Run(v8::Exception::Error(error_message), gfx::Image());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
App::App(v8::Isolate* isolate) {
|
||||
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())->set_delegate(this);
|
||||
Browser::Get()->AddObserver(this);
|
||||
content::GpuDataManager::GetInstance()->AddObserver(this);
|
||||
base::ProcessId pid = base::GetCurrentProcId();
|
||||
std::unique_ptr<atom::ProcessMetric> process_metric(
|
||||
new atom::ProcessMetric(
|
||||
content::PROCESS_TYPE_BROWSER,
|
||||
pid,
|
||||
base::ProcessMetrics::CreateCurrentProcessMetrics()));
|
||||
app_metrics_[pid] = std::move(process_metric);
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
@@ -547,7 +449,6 @@ App::~App() {
|
||||
nullptr);
|
||||
Browser::Get()->RemoveObserver(this);
|
||||
content::GpuDataManager::GetInstance()->RemoveObserver(this);
|
||||
content::BrowserChildProcessObserver::Remove(this);
|
||||
}
|
||||
|
||||
void App::OnBeforeQuit(bool* prevent_default) {
|
||||
@@ -566,7 +467,7 @@ void App::OnQuit() {
|
||||
int exitCode = AtomBrowserMainParts::Get()->GetExitCode();
|
||||
Emit("quit", exitCode);
|
||||
|
||||
if (process_singleton_) {
|
||||
if (process_singleton_.get()) {
|
||||
process_singleton_->Cleanup();
|
||||
process_singleton_.reset();
|
||||
}
|
||||
@@ -589,111 +490,53 @@ void App::OnWillFinishLaunching() {
|
||||
}
|
||||
|
||||
void App::OnFinishLaunching(const base::DictionaryValue& launch_info) {
|
||||
#if defined(OS_LINUX)
|
||||
// Set the application name for audio streams shown in external
|
||||
// applications. Only affects pulseaudio currently.
|
||||
media::AudioManager::SetGlobalAppName(Browser::Get()->GetName());
|
||||
#endif
|
||||
Emit("ready", launch_info);
|
||||
}
|
||||
|
||||
void App::OnPreMainMessageLoopRun() {
|
||||
content::BrowserChildProcessObserver::Add(this);
|
||||
if (process_singleton_) {
|
||||
process_singleton_->OnBrowserReady();
|
||||
}
|
||||
}
|
||||
|
||||
void App::OnAccessibilitySupportChanged() {
|
||||
Emit("accessibility-support-changed", IsAccessibilitySupportEnabled());
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void App::OnWillContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type) {
|
||||
*prevent_default = Emit("will-continue-activity", type);
|
||||
}
|
||||
|
||||
void App::OnDidFailToContinueUserActivity(
|
||||
const std::string& type,
|
||||
const std::string& error) {
|
||||
Emit("continue-activity-error", type, error);
|
||||
}
|
||||
|
||||
void App::OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
*prevent_default = Emit("continue-activity", type, user_info);
|
||||
}
|
||||
|
||||
void App::OnUserActivityWasContinued(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
Emit("activity-was-continued", type, user_info);
|
||||
}
|
||||
|
||||
void App::OnUpdateUserActivityState(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) {
|
||||
*prevent_default = Emit("update-activity-state", type, user_info);
|
||||
}
|
||||
|
||||
void App::OnNewWindowForTab() {
|
||||
Emit("new-window-for-tab");
|
||||
}
|
||||
#endif
|
||||
|
||||
void App::OnLogin(LoginHandler* login_handler,
|
||||
const base::DictionaryValue& request_details) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
bool prevent_default = false;
|
||||
content::WebContents* web_contents = login_handler->GetWebContents();
|
||||
if (web_contents) {
|
||||
prevent_default =
|
||||
Emit("login",
|
||||
WebContents::CreateFrom(isolate(), web_contents),
|
||||
request_details,
|
||||
login_handler->auth_info(),
|
||||
base::Bind(&PassLoginInformation,
|
||||
make_scoped_refptr(login_handler)));
|
||||
}
|
||||
bool prevent_default = Emit(
|
||||
"login",
|
||||
WebContents::CreateFrom(isolate(), login_handler->GetWebContents()),
|
||||
request_details,
|
||||
login_handler->auth_info(),
|
||||
base::Bind(&PassLoginInformation, make_scoped_refptr(login_handler)));
|
||||
|
||||
// Default behavior is to always cancel the auth.
|
||||
if (!prevent_default)
|
||||
login_handler->CancelAuth();
|
||||
}
|
||||
|
||||
bool App::CanCreateWindow(
|
||||
content::RenderFrameHost* opener,
|
||||
const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const GURL& source_origin,
|
||||
content::mojom::WindowContainerType container_type,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::mojom::WindowFeatures& features,
|
||||
const std::vector<std::string>& additional_features,
|
||||
const scoped_refptr<content::ResourceRequestBody>& body,
|
||||
bool user_gesture,
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access) {
|
||||
void App::OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
int render_process_id,
|
||||
int render_frame_id) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
content::RenderFrameHost* rfh =
|
||||
content::RenderFrameHost::FromID(render_process_id, render_frame_id);
|
||||
content::WebContents* web_contents =
|
||||
content::WebContents::FromRenderFrameHost(opener);
|
||||
content::WebContents::FromRenderFrameHost(rfh);
|
||||
if (web_contents) {
|
||||
auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents);
|
||||
api_web_contents->OnCreateWindow(target_url, frame_name, disposition,
|
||||
additional_features, body);
|
||||
api_web_contents->OnCreateWindow(target_url, frame_name, disposition);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void App::AllowCertificateError(
|
||||
@@ -705,8 +548,8 @@ void App::AllowCertificateError(
|
||||
bool overridable,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||
callback) {
|
||||
const base::Callback<void(bool)>& callback,
|
||||
content::CertificateRequestResultType* request) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
bool prevent_default = Emit("certificate-error",
|
||||
@@ -718,102 +561,32 @@ void App::AllowCertificateError(
|
||||
|
||||
// Deny the certificate by default.
|
||||
if (!prevent_default)
|
||||
callback.Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY);
|
||||
*request = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
|
||||
}
|
||||
|
||||
void App::SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
net::ClientCertIdentityList identities,
|
||||
std::unique_ptr<content::ClientCertificateDelegate> delegate) {
|
||||
std::shared_ptr<content::ClientCertificateDelegate>
|
||||
shared_delegate(delegate.release());
|
||||
|
||||
// Convert the ClientCertIdentityList to a CertificateList
|
||||
// to avoid changes in the API.
|
||||
auto client_certs = net::CertificateList();
|
||||
for (const std::unique_ptr<net::ClientCertIdentity>& identity : identities)
|
||||
client_certs.push_back(identity->certificate());
|
||||
|
||||
auto shared_identities =
|
||||
std::make_shared<net::ClientCertIdentityList>(std::move(identities));
|
||||
|
||||
bool prevent_default =
|
||||
Emit("select-client-certificate",
|
||||
WebContents::CreateFrom(isolate(), web_contents),
|
||||
cert_request_info->host_and_port.ToString(), std::move(client_certs),
|
||||
base::Bind(&OnClientCertificateSelected, isolate(), shared_delegate,
|
||||
shared_identities));
|
||||
cert_request_info->host_and_port.ToString(),
|
||||
cert_request_info->client_certs,
|
||||
base::Bind(&OnClientCertificateSelected,
|
||||
isolate(),
|
||||
shared_delegate));
|
||||
|
||||
// Default to first certificate from the platform store.
|
||||
if (!prevent_default) {
|
||||
scoped_refptr<net::X509Certificate> cert =
|
||||
(*shared_identities)[0]->certificate();
|
||||
net::ClientCertIdentity::SelfOwningAcquirePrivateKey(
|
||||
std::move((*shared_identities)[0]),
|
||||
base::Bind(&GotPrivateKey, shared_delegate, std::move(cert)));
|
||||
}
|
||||
if (!prevent_default)
|
||||
shared_delegate->ContinueWithCertificate(
|
||||
cert_request_info->client_certs[0].get());
|
||||
}
|
||||
|
||||
void App::OnGpuProcessCrashed(base::TerminationStatus status) {
|
||||
Emit("gpu-process-crashed",
|
||||
status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
|
||||
}
|
||||
|
||||
void App::BrowserChildProcessLaunchedAndConnected(
|
||||
const content::ChildProcessData& data) {
|
||||
ChildProcessLaunched(data.process_type, data.handle);
|
||||
}
|
||||
|
||||
void App::BrowserChildProcessHostDisconnected(
|
||||
const content::ChildProcessData& data) {
|
||||
ChildProcessDisconnected(base::GetProcId(data.handle));
|
||||
}
|
||||
|
||||
void App::BrowserChildProcessCrashed(const content::ChildProcessData& data,
|
||||
int exit_code) {
|
||||
ChildProcessDisconnected(base::GetProcId(data.handle));
|
||||
}
|
||||
|
||||
void App::BrowserChildProcessKilled(const content::ChildProcessData& data,
|
||||
int exit_code) {
|
||||
ChildProcessDisconnected(base::GetProcId(data.handle));
|
||||
}
|
||||
|
||||
void App::RenderProcessReady(content::RenderProcessHost* host) {
|
||||
ChildProcessLaunched(content::PROCESS_TYPE_RENDERER, host->GetHandle());
|
||||
}
|
||||
|
||||
void App::RenderProcessDisconnected(base::ProcessId host_pid) {
|
||||
ChildProcessDisconnected(host_pid);
|
||||
}
|
||||
|
||||
void App::ChildProcessLaunched(int process_type, base::ProcessHandle handle) {
|
||||
auto pid = base::GetProcId(handle);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
std::unique_ptr<base::ProcessMetrics> metrics(
|
||||
base::ProcessMetrics::CreateProcessMetrics(
|
||||
handle, content::BrowserChildProcessHost::GetPortProvider()));
|
||||
#else
|
||||
std::unique_ptr<base::ProcessMetrics> metrics(
|
||||
base::ProcessMetrics::CreateProcessMetrics(handle));
|
||||
#endif
|
||||
std::unique_ptr<atom::ProcessMetric> process_metric(
|
||||
new atom::ProcessMetric(process_type, pid, std::move(metrics)));
|
||||
app_metrics_[pid] = std::move(process_metric);
|
||||
}
|
||||
|
||||
void App::ChildProcessDisconnected(base::ProcessId pid) {
|
||||
app_metrics_.erase(pid);
|
||||
}
|
||||
|
||||
base::FilePath App::GetAppPath() const {
|
||||
return app_path_;
|
||||
}
|
||||
|
||||
void App::SetAppPath(const base::FilePath& app_path) {
|
||||
app_path_ = app_path;
|
||||
void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) {
|
||||
Emit("gpu-process-crashed");
|
||||
}
|
||||
|
||||
base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||
@@ -823,7 +596,7 @@ base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||
if (key >= 0)
|
||||
succeed = PathService::Get(key, &path);
|
||||
if (!succeed)
|
||||
args->ThrowError("Failed to get '" + name + "' path");
|
||||
args->ThrowError("Failed to get path");
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -831,7 +604,7 @@ void App::SetPath(mate::Arguments* args,
|
||||
const std::string& name,
|
||||
const base::FilePath& path) {
|
||||
if (!path.IsAbsolute()) {
|
||||
args->ThrowError("Path must be absolute");
|
||||
args->ThrowError("path must be absolute");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -851,12 +624,12 @@ void App::SetDesktopName(const std::string& desktop_name) {
|
||||
}
|
||||
|
||||
std::string App::GetLocale() {
|
||||
return g_browser_process->GetApplicationLocale();
|
||||
return l10n_util::GetApplicationLocale("");
|
||||
}
|
||||
|
||||
bool App::MakeSingleInstance(
|
||||
const ProcessSingleton::NotificationCallback& callback) {
|
||||
if (process_singleton_)
|
||||
if (process_singleton_.get())
|
||||
return false;
|
||||
|
||||
base::FilePath user_dir;
|
||||
@@ -867,10 +640,9 @@ bool App::MakeSingleInstance(
|
||||
switch (process_singleton_->NotifyOtherProcessOrCreate()) {
|
||||
case ProcessSingleton::NotifyResult::LOCK_ERROR:
|
||||
case ProcessSingleton::NotifyResult::PROFILE_IN_USE:
|
||||
case ProcessSingleton::NotifyResult::PROCESS_NOTIFIED: {
|
||||
case ProcessSingleton::NotifyResult::PROCESS_NOTIFIED:
|
||||
process_singleton_.reset();
|
||||
return true;
|
||||
}
|
||||
case ProcessSingleton::NotifyResult::PROCESS_NONE:
|
||||
default: // Shouldn't be needed, but VS warns if it is not there.
|
||||
return false;
|
||||
@@ -878,7 +650,7 @@ bool App::MakeSingleInstance(
|
||||
}
|
||||
|
||||
void App::ReleaseSingleInstance() {
|
||||
if (process_singleton_) {
|
||||
if (process_singleton_.get()) {
|
||||
process_singleton_->Cleanup();
|
||||
process_singleton_.reset();
|
||||
}
|
||||
@@ -897,7 +669,11 @@ bool App::Relaunch(mate::Arguments* js_args) {
|
||||
}
|
||||
|
||||
if (!override_argv) {
|
||||
#if defined(OS_WIN)
|
||||
const relauncher::StringVector& argv = atom::AtomCommandLine::wargv();
|
||||
#else
|
||||
const relauncher::StringVector& argv = atom::AtomCommandLine::argv();
|
||||
#endif
|
||||
return relauncher::RelaunchApp(argv);
|
||||
}
|
||||
|
||||
@@ -926,38 +702,11 @@ void App::DisableHardwareAcceleration(mate::Arguments* args) {
|
||||
content::GpuDataManager::GetInstance()->DisableHardwareAcceleration();
|
||||
}
|
||||
|
||||
void App::DisableDomainBlockingFor3DAPIs(mate::Arguments* args) {
|
||||
if (Browser::Get()->is_ready()) {
|
||||
args->ThrowError(
|
||||
"app.disableDomainBlockingFor3DAPIs() can only be called "
|
||||
"before app is ready");
|
||||
return;
|
||||
}
|
||||
content::GpuDataManagerImpl::GetInstance()
|
||||
->DisableDomainBlockingFor3DAPIsForTesting();
|
||||
}
|
||||
|
||||
bool App::IsAccessibilitySupportEnabled() {
|
||||
auto ax_state = content::BrowserAccessibilityState::GetInstance();
|
||||
return ax_state->IsAccessibleBrowser();
|
||||
}
|
||||
|
||||
void App::SetAccessibilitySupportEnabled(bool enabled) {
|
||||
auto ax_state = content::BrowserAccessibilityState::GetInstance();
|
||||
if (enabled) {
|
||||
ax_state->OnScreenReaderDetected();
|
||||
} else {
|
||||
ax_state->DisableAccessibility();
|
||||
}
|
||||
Browser::Get()->OnAccessibilitySupportChanged();
|
||||
}
|
||||
|
||||
Browser::LoginItemSettings App::GetLoginItemSettings(mate::Arguments* args) {
|
||||
Browser::LoginItemSettings options;
|
||||
args->GetNext(&options);
|
||||
return Browser::Get()->GetLoginItemSettings(options);
|
||||
}
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void App::ImportCertificate(
|
||||
const base::DictionaryValue& options,
|
||||
@@ -1046,134 +795,6 @@ JumpListResult App::SetJumpList(v8::Local<v8::Value> val,
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
void App::GetFileIcon(const base::FilePath& path,
|
||||
mate::Arguments* args) {
|
||||
mate::Dictionary options;
|
||||
IconLoader::IconSize icon_size;
|
||||
FileIconCallback callback;
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
base::FilePath normalized_path = path.NormalizePathSeparators();
|
||||
|
||||
if (!args->GetNext(&options)) {
|
||||
icon_size = IconLoader::IconSize::NORMAL;
|
||||
} else {
|
||||
std::string icon_size_string;
|
||||
options.Get("size", &icon_size_string);
|
||||
icon_size = GetIconSizeByString(icon_size_string);
|
||||
}
|
||||
|
||||
if (!args->GetNext(&callback)) {
|
||||
args->ThrowError("Missing required callback function");
|
||||
return;
|
||||
}
|
||||
|
||||
auto icon_manager = g_browser_process->GetIconManager();
|
||||
gfx::Image* icon =
|
||||
icon_manager->LookupIconFromFilepath(normalized_path, icon_size);
|
||||
if (icon) {
|
||||
callback.Run(v8::Null(isolate()), *icon);
|
||||
} else {
|
||||
icon_manager->LoadIcon(
|
||||
normalized_path, icon_size,
|
||||
base::Bind(&OnIconDataAvailable, isolate(), callback),
|
||||
&cancelable_task_tracker_);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<mate::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
|
||||
std::vector<mate::Dictionary> result;
|
||||
int processor_count = base::SysInfo::NumberOfProcessors();
|
||||
|
||||
for (const auto& process_metric : app_metrics_) {
|
||||
mate::Dictionary pid_dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
mate::Dictionary memory_dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
mate::Dictionary cpu_dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
|
||||
memory_dict.Set("workingSetSize",
|
||||
static_cast<double>(
|
||||
process_metric.second->metrics->GetWorkingSetSize() >> 10));
|
||||
memory_dict.Set("peakWorkingSetSize",
|
||||
static_cast<double>(
|
||||
process_metric.second->metrics->GetPeakWorkingSetSize() >> 10));
|
||||
|
||||
size_t private_bytes, shared_bytes;
|
||||
if (process_metric.second->metrics->GetMemoryBytes(&private_bytes,
|
||||
&shared_bytes)) {
|
||||
memory_dict.Set("privateBytes", static_cast<double>(private_bytes >> 10));
|
||||
memory_dict.Set("sharedBytes", static_cast<double>(shared_bytes >> 10));
|
||||
}
|
||||
|
||||
pid_dict.Set("memory", memory_dict);
|
||||
cpu_dict.Set("percentCPUUsage",
|
||||
process_metric.second->metrics->GetPlatformIndependentCPUUsage()
|
||||
/ processor_count);
|
||||
|
||||
#if !defined(OS_WIN)
|
||||
cpu_dict.Set("idleWakeupsPerSecond",
|
||||
process_metric.second->metrics->GetIdleWakeupsPerSecond());
|
||||
#else
|
||||
// Chrome's underlying process_metrics.cc will throw a non-fatal warning
|
||||
// that this method isn't implemented on Windows, so set it to 0 instead
|
||||
// of calling it
|
||||
cpu_dict.Set("idleWakeupsPerSecond", 0);
|
||||
#endif
|
||||
|
||||
pid_dict.Set("cpu", cpu_dict);
|
||||
pid_dict.Set("pid", process_metric.second->pid);
|
||||
pid_dict.Set("type",
|
||||
content::GetProcessTypeNameInEnglish(process_metric.second->type));
|
||||
result.push_back(pid_dict);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> App::GetGPUFeatureStatus(v8::Isolate* isolate) {
|
||||
auto status = content::GetFeatureStatus();
|
||||
return mate::ConvertToV8(isolate,
|
||||
status ? *status : base::DictionaryValue());
|
||||
}
|
||||
|
||||
void App::EnableMixedSandbox(mate::Arguments* args) {
|
||||
if (Browser::Get()->is_ready()) {
|
||||
args->ThrowError("app.enableMixedSandbox() can only be called "
|
||||
"before app is ready");
|
||||
return;
|
||||
}
|
||||
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
if (command_line->HasSwitch(::switches::kNoSandbox)) {
|
||||
#if defined(OS_WIN)
|
||||
const base::CommandLine::CharType* noSandboxArg = L"--no-sandbox";
|
||||
#else
|
||||
const base::CommandLine::CharType* noSandboxArg = "--no-sandbox";
|
||||
#endif
|
||||
|
||||
// Remove the --no-sandbox switch
|
||||
base::CommandLine::StringVector modified_command_line;
|
||||
for (auto& arg : command_line->argv()) {
|
||||
if (arg.compare(noSandboxArg) != 0) {
|
||||
modified_command_line.push_back(arg);
|
||||
}
|
||||
}
|
||||
command_line->InitFromArgv(modified_command_line);
|
||||
}
|
||||
command_line->AppendSwitch(switches::kEnableMixedSandbox);
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool App::MoveToApplicationsFolder(mate::Arguments* args) {
|
||||
return ui::cocoa::AtomBundleMover::Move(args);
|
||||
}
|
||||
|
||||
bool App::IsInApplicationsFolder() {
|
||||
return ui::cocoa::AtomBundleMover::IsCurrentAppInApplicationsFolder();
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
mate::Handle<App> App::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new App(isolate));
|
||||
@@ -1207,7 +828,8 @@ void App::BuildPrototype(
|
||||
base::Bind(&Browser::RemoveAsDefaultProtocolClient, browser))
|
||||
.SetMethod("setBadgeCount", base::Bind(&Browser::SetBadgeCount, browser))
|
||||
.SetMethod("getBadgeCount", base::Bind(&Browser::GetBadgeCount, browser))
|
||||
.SetMethod("getLoginItemSettings", &App::GetLoginItemSettings)
|
||||
.SetMethod("getLoginItemSettings",
|
||||
base::Bind(&Browser::GetLoginItemSettings, browser))
|
||||
.SetMethod("setLoginItemSettings",
|
||||
base::Bind(&Browser::SetLoginItemSettings, browser))
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -1217,12 +839,6 @@ void App::BuildPrototype(
|
||||
base::Bind(&Browser::SetUserActivity, browser))
|
||||
.SetMethod("getCurrentActivityType",
|
||||
base::Bind(&Browser::GetCurrentActivityType, browser))
|
||||
.SetMethod("invalidateCurrentActivity",
|
||||
base::Bind(&Browser::InvalidateCurrentActivity, browser))
|
||||
.SetMethod("updateCurrentActivity",
|
||||
base::Bind(&Browser::UpdateCurrentActivity, browser))
|
||||
.SetMethod("setAboutPanelOptions",
|
||||
base::Bind(&Browser::SetAboutPanelOptions, browser))
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser))
|
||||
@@ -1233,8 +849,6 @@ void App::BuildPrototype(
|
||||
.SetMethod("isUnityRunning",
|
||||
base::Bind(&Browser::IsUnityRunning, browser))
|
||||
#endif
|
||||
.SetMethod("setAppPath", &App::SetAppPath)
|
||||
.SetMethod("getAppPath", &App::GetAppPath)
|
||||
.SetMethod("setPath", &App::SetPath)
|
||||
.SetMethod("getPath", &App::GetPath)
|
||||
.SetMethod("setDesktopName", &App::SetDesktopName)
|
||||
@@ -1247,25 +861,8 @@ void App::BuildPrototype(
|
||||
.SetMethod("relaunch", &App::Relaunch)
|
||||
.SetMethod("isAccessibilitySupportEnabled",
|
||||
&App::IsAccessibilitySupportEnabled)
|
||||
.SetMethod("setAccessibilitySupportEnabled",
|
||||
&App::SetAccessibilitySupportEnabled)
|
||||
.SetMethod("disableHardwareAcceleration",
|
||||
&App::DisableHardwareAcceleration)
|
||||
.SetMethod("disableDomainBlockingFor3DAPIs",
|
||||
&App::DisableDomainBlockingFor3DAPIs)
|
||||
.SetMethod("getFileIcon", &App::GetFileIcon)
|
||||
.SetMethod("getAppMetrics", &App::GetAppMetrics)
|
||||
.SetMethod("getGPUFeatureStatus", &App::GetGPUFeatureStatus)
|
||||
// TODO(juturu): Remove in 2.0, deprecate before then with warnings
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("moveToApplicationsFolder", &App::MoveToApplicationsFolder)
|
||||
.SetMethod("isInApplicationsFolder", &App::IsInApplicationsFolder)
|
||||
#endif
|
||||
#if defined(MAS_BUILD)
|
||||
.SetMethod("startAccessingSecurityScopedResource",
|
||||
&App::StartAccessingSecurityScopedResource)
|
||||
#endif
|
||||
.SetMethod("enableMixedSandbox", &App::EnableMixedSandbox);
|
||||
&App::DisableHardwareAcceleration);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -5,27 +5,16 @@
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/browser_observer.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "base/process/process_iterator.h"
|
||||
#include "base/task/cancelable_task_tracker.h"
|
||||
#include "chrome/browser/icon_manager.h"
|
||||
#include "chrome/browser/process_singleton.h"
|
||||
#include "content/public/browser/browser_child_process_observer.h"
|
||||
#include "content/public/browser/gpu_data_manager_observer.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/base/completion_callback.h"
|
||||
#include "net/ssl/client_cert_identity.h"
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
#include "chrome/browser/certificate_manager_model.h"
|
||||
@@ -45,36 +34,25 @@ namespace atom {
|
||||
enum class JumpListResult : int;
|
||||
#endif
|
||||
|
||||
struct ProcessMetric {
|
||||
int type;
|
||||
base::ProcessId pid;
|
||||
std::unique_ptr<base::ProcessMetrics> metrics;
|
||||
|
||||
ProcessMetric(int type,
|
||||
base::ProcessId pid,
|
||||
std::unique_ptr<base::ProcessMetrics> metrics) {
|
||||
this->type = type;
|
||||
this->pid = pid;
|
||||
this->metrics = std::move(metrics);
|
||||
}
|
||||
};
|
||||
|
||||
namespace api {
|
||||
|
||||
class App : public AtomBrowserClient::Delegate,
|
||||
public mate::EventEmitter<App>,
|
||||
public BrowserObserver,
|
||||
public content::GpuDataManagerObserver,
|
||||
public content::BrowserChildProcessObserver {
|
||||
public content::GpuDataManagerObserver {
|
||||
public:
|
||||
using FileIconCallback = base::Callback<void(v8::Local<v8::Value>,
|
||||
const gfx::Image&)>;
|
||||
|
||||
static mate::Handle<App> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// Called when window with disposition needs to be created.
|
||||
void OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
int render_process_id,
|
||||
int render_frame_id);
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void OnCertificateManagerModelCreated(
|
||||
std::unique_ptr<base::DictionaryValue> options,
|
||||
@@ -82,11 +60,6 @@ class App : public AtomBrowserClient::Delegate,
|
||||
std::unique_ptr<CertificateManagerModel> model);
|
||||
#endif
|
||||
|
||||
base::FilePath GetAppPath() const;
|
||||
void RenderProcessReady(content::RenderProcessHost* host);
|
||||
void RenderProcessDisconnected(base::ProcessId host_pid);
|
||||
void PreMainMessageLoopRun();
|
||||
|
||||
protected:
|
||||
explicit App(v8::Isolate* isolate);
|
||||
~App() override;
|
||||
@@ -104,26 +77,11 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void OnLogin(LoginHandler* login_handler,
|
||||
const base::DictionaryValue& request_details) override;
|
||||
void OnAccessibilitySupportChanged() override;
|
||||
void OnPreMainMessageLoopRun() override;
|
||||
#if defined(OS_MACOSX)
|
||||
void OnWillContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type) override;
|
||||
void OnDidFailToContinueUserActivity(
|
||||
const std::string& type,
|
||||
const std::string& error) override;
|
||||
void OnContinueUserActivity(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
void OnUserActivityWasContinued(
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
void OnUpdateUserActivityState(
|
||||
bool* prevent_default,
|
||||
const std::string& type,
|
||||
const base::DictionaryValue& user_info) override;
|
||||
void OnNewWindowForTab() override;
|
||||
#endif
|
||||
|
||||
// content::ContentBrowserClient:
|
||||
@@ -136,47 +94,17 @@ class App : public AtomBrowserClient::Delegate,
|
||||
bool overridable,
|
||||
bool strict_enforcement,
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||
callback) override;
|
||||
const base::Callback<void(bool)>& callback,
|
||||
content::CertificateRequestResultType* request) override;
|
||||
void SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
net::ClientCertIdentityList client_certs,
|
||||
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||
bool CanCreateWindow(content::RenderFrameHost* opener,
|
||||
const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const GURL& source_origin,
|
||||
content::mojom::WindowContainerType container_type,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::mojom::WindowFeatures& features,
|
||||
const std::vector<std::string>& additional_features,
|
||||
const scoped_refptr<content::ResourceRequestBody>& body,
|
||||
bool user_gesture,
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access) override;
|
||||
|
||||
// content::GpuDataManagerObserver:
|
||||
void OnGpuProcessCrashed(base::TerminationStatus status) override;
|
||||
|
||||
// content::BrowserChildProcessObserver:
|
||||
void BrowserChildProcessLaunchedAndConnected(
|
||||
const content::ChildProcessData& data) override;
|
||||
void BrowserChildProcessHostDisconnected(
|
||||
const content::ChildProcessData& data) override;
|
||||
void BrowserChildProcessCrashed(
|
||||
const content::ChildProcessData& data, int exit_code) override;
|
||||
void BrowserChildProcessKilled(
|
||||
const content::ChildProcessData& data, int exit_code) override;
|
||||
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
|
||||
|
||||
private:
|
||||
void SetAppPath(const base::FilePath& app_path);
|
||||
void ChildProcessLaunched(int process_type, base::ProcessHandle handle);
|
||||
void ChildProcessDisconnected(base::ProcessId pid);
|
||||
|
||||
// Get/Set the pre-defined path in PathService.
|
||||
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
|
||||
void SetPath(mate::Arguments* args,
|
||||
@@ -190,29 +118,11 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void ReleaseSingleInstance();
|
||||
bool Relaunch(mate::Arguments* args);
|
||||
void DisableHardwareAcceleration(mate::Arguments* args);
|
||||
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
|
||||
bool IsAccessibilitySupportEnabled();
|
||||
void SetAccessibilitySupportEnabled(bool enabled);
|
||||
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void ImportCertificate(const base::DictionaryValue& options,
|
||||
const net::CompletionCallback& callback);
|
||||
#endif
|
||||
void GetFileIcon(const base::FilePath& path,
|
||||
mate::Arguments* args);
|
||||
|
||||
std::vector<mate::Dictionary> GetAppMetrics(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> GetGPUFeatureStatus(v8::Isolate* isolate);
|
||||
void EnableMixedSandbox(mate::Arguments* args);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
bool IsInApplicationsFolder();
|
||||
#endif
|
||||
#if defined(MAS_BUILD)
|
||||
base::Callback<void()> StartAccessingSecurityScopedResource(
|
||||
mate::Arguments* args);
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Get the current Jump List settings.
|
||||
@@ -228,16 +138,6 @@ class App : public AtomBrowserClient::Delegate,
|
||||
std::unique_ptr<CertificateManagerModel> certificate_manager_model_;
|
||||
#endif
|
||||
|
||||
// Tracks tasks requesting file icons.
|
||||
base::CancelableTaskTracker cancelable_task_tracker_;
|
||||
|
||||
base::FilePath app_path_;
|
||||
|
||||
using ProcessMetricMap =
|
||||
std::unordered_map<base::ProcessId,
|
||||
std::unique_ptr<atom::ProcessMetric>>;
|
||||
ProcessMetricMap app_metrics_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(App);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_app.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
// Callback passed to js which will stop accessing the given bookmark.
|
||||
void OnStopAccessingSecurityScopedResource(NSURL* bookmarkUrl) {
|
||||
[bookmarkUrl stopAccessingSecurityScopedResource];
|
||||
[bookmarkUrl release];
|
||||
}
|
||||
|
||||
// Get base64 encoded NSData, create a bookmark for it and start accessing it.
|
||||
base::Callback<void ()> App::StartAccessingSecurityScopedResource(mate::Arguments* args) {
|
||||
std::string data;
|
||||
args->GetNext(&data);
|
||||
NSString *base64str = base::SysUTF8ToNSString(data);
|
||||
NSData *bookmarkData = [[NSData alloc] initWithBase64EncodedString: base64str options: 0];
|
||||
|
||||
// Create bookmarkUrl from NSData.
|
||||
BOOL isStale = false;
|
||||
NSError *error = nil;
|
||||
NSURL *bookmarkUrl = [NSURL URLByResolvingBookmarkData: bookmarkData
|
||||
options: NSURLBookmarkResolutionWithSecurityScope
|
||||
relativeToURL: nil
|
||||
bookmarkDataIsStale: &isStale
|
||||
error: &error];
|
||||
|
||||
if (error != nil) {
|
||||
NSString *err = [NSString stringWithFormat: @"NSError: %@ %@", error, [error userInfo]];
|
||||
args->ThrowError(base::SysNSStringToUTF8(err));
|
||||
}
|
||||
|
||||
if (isStale) {
|
||||
args->ThrowError("bookmarkDataIsStale - try recreating the bookmark");
|
||||
}
|
||||
|
||||
if (error == nil && isStale == false) {
|
||||
[bookmarkUrl startAccessingSecurityScopedResource];
|
||||
}
|
||||
|
||||
// Stop the NSURL from being GC'd.
|
||||
[bookmarkUrl retain];
|
||||
|
||||
// Return a js callback which will close the bookmark.
|
||||
return base::Bind(&OnStopAccessingSecurityScopedResource, bookmarkUrl);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
} // namespace api
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/time/time.h"
|
||||
@@ -48,32 +47,13 @@ void AutoUpdater::OnError(const std::string& message) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||
mate::EmitEvent(
|
||||
isolate(),
|
||||
GetWrapper(),
|
||||
EmitCustomEvent(
|
||||
"error",
|
||||
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
|
||||
// Message is also emitted to keep compatibility with old code.
|
||||
message);
|
||||
}
|
||||
|
||||
void AutoUpdater::OnError(const std::string& message,
|
||||
const int code, const std::string& domain) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||
auto errorObject = error->ToObject(
|
||||
isolate()->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
// add two new params for better error handling
|
||||
errorObject->Set(mate::StringToV8(isolate(), "code"),
|
||||
v8::Integer::New(isolate(), code));
|
||||
errorObject->Set(mate::StringToV8(isolate(), "domain"),
|
||||
mate::StringToV8(isolate(), domain));
|
||||
|
||||
mate::EmitEvent(isolate(), GetWrapper(), "error", errorObject, message);
|
||||
}
|
||||
|
||||
void AutoUpdater::OnCheckingForUpdate() {
|
||||
Emit("checking-for-update");
|
||||
}
|
||||
@@ -99,20 +79,24 @@ void AutoUpdater::OnWindowAllClosed() {
|
||||
QuitAndInstall();
|
||||
}
|
||||
|
||||
void AutoUpdater::SetFeedURL(mate::Arguments* args) {
|
||||
auto_updater::AutoUpdater::SetFeedURL(args);
|
||||
void AutoUpdater::SetFeedURL(const std::string& url, mate::Arguments* args) {
|
||||
auto_updater::AutoUpdater::HeaderMap headers;
|
||||
args->GetNext(&headers);
|
||||
auto_updater::AutoUpdater::SetFeedURL(url, headers);
|
||||
}
|
||||
|
||||
void AutoUpdater::QuitAndInstall() {
|
||||
// If we don't have any window then quitAndInstall immediately.
|
||||
if (WindowList::IsEmpty()) {
|
||||
WindowList* window_list = WindowList::GetInstance();
|
||||
if (window_list->size() == 0) {
|
||||
auto_updater::AutoUpdater::QuitAndInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise do the restart after all windows have been closed.
|
||||
WindowList::AddObserver(this);
|
||||
WindowList::CloseAllWindows();
|
||||
window_list->AddObserver(this);
|
||||
for (NativeWindow* window : *window_list)
|
||||
window->Close();
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -32,8 +32,6 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
|
||||
|
||||
// Delegate implementations.
|
||||
void OnError(const std::string& error) override;
|
||||
void OnError(const std::string& message, const int code,
|
||||
const std::string& domain);
|
||||
void OnCheckingForUpdate() override;
|
||||
void OnUpdateAvailable() override;
|
||||
void OnUpdateNotAvailable() override;
|
||||
@@ -47,7 +45,7 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
|
||||
|
||||
private:
|
||||
std::string GetFeedURL();
|
||||
void SetFeedURL(mate::Arguments* args);
|
||||
void SetFeedURL(const std::string& url, mate::Arguments* args);
|
||||
void QuitAndInstall();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_browser_view.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<atom::AutoResizeFlags> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
atom::AutoResizeFlags* auto_resize_flags) {
|
||||
mate::Dictionary params;
|
||||
if (!ConvertFromV8(isolate, val, ¶ms)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t flags = 0;
|
||||
bool width = false;
|
||||
if (params.Get("width", &width) && width) {
|
||||
flags |= atom::kAutoResizeWidth;
|
||||
}
|
||||
bool height = false;
|
||||
if (params.Get("height", &height) && height) {
|
||||
flags |= atom::kAutoResizeHeight;
|
||||
}
|
||||
|
||||
*auto_resize_flags = static_cast<atom::AutoResizeFlags>(flags);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
BrowserView::BrowserView(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options)
|
||||
: api_web_contents_(nullptr) {
|
||||
Init(isolate, wrapper, options);
|
||||
}
|
||||
|
||||
void BrowserView::Init(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options) {
|
||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
web_preferences.Set("isBrowserView", true);
|
||||
mate::Handle<class WebContents> web_contents =
|
||||
WebContents::Create(isolate, web_preferences);
|
||||
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents.get();
|
||||
|
||||
view_.reset(NativeBrowserView::Create(
|
||||
api_web_contents_->managed_web_contents()->GetView()));
|
||||
|
||||
InitWith(isolate, wrapper);
|
||||
}
|
||||
|
||||
BrowserView::~BrowserView() {
|
||||
api_web_contents_->DestroyWebContents(true /* async */);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::WrappableBase* BrowserView::New(mate::Arguments* args) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
args->ThrowError("Cannot create BrowserView before app is ready");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (args->Length() > 1) {
|
||||
args->ThrowError("Too many arguments");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mate::Dictionary options;
|
||||
if (!(args->Length() == 1 && args->GetNext(&options))) {
|
||||
options = mate::Dictionary::CreateEmpty(args->isolate());
|
||||
}
|
||||
|
||||
return new BrowserView(args->isolate(), args->GetThis(), options);
|
||||
}
|
||||
|
||||
int32_t BrowserView::ID() const {
|
||||
return weak_map_id();
|
||||
}
|
||||
|
||||
void BrowserView::SetAutoResize(AutoResizeFlags flags) {
|
||||
view_->SetAutoResizeFlags(flags);
|
||||
}
|
||||
|
||||
void BrowserView::SetBounds(const gfx::Rect& bounds) {
|
||||
view_->SetBounds(bounds);
|
||||
}
|
||||
|
||||
void BrowserView::SetBackgroundColor(const std::string& color_name) {
|
||||
view_->SetBackgroundColor(ParseHexColor(color_name));
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> BrowserView::GetWebContents() {
|
||||
if (web_contents_.IsEmpty()) {
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
|
||||
return v8::Local<v8::Value>::New(isolate(), web_contents_);
|
||||
}
|
||||
|
||||
// static
|
||||
void BrowserView::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "BrowserView"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("setAutoResize", &BrowserView::SetAutoResize)
|
||||
.SetMethod("setBounds", &BrowserView::SetBounds)
|
||||
.SetMethod("setBackgroundColor", &BrowserView::SetBackgroundColor)
|
||||
.SetProperty("webContents", &BrowserView::GetWebContents)
|
||||
.SetProperty("id", &BrowserView::ID);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::BrowserView;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
BrowserView::SetConstructor(isolate, base::Bind(&BrowserView::New));
|
||||
|
||||
mate::Dictionary browser_view(
|
||||
isolate, BrowserView::GetConstructor(isolate)->GetFunction());
|
||||
browser_view.SetMethod("fromId",
|
||||
&mate::TrackableObject<BrowserView>::FromWeakMapID);
|
||||
browser_view.SetMethod("getAllViews",
|
||||
&mate::TrackableObject<BrowserView>::GetAll);
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("BrowserView", browser_view);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_browser_view, Initialize)
|
||||
@@ -1,73 +0,0 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NativeBrowserView;
|
||||
|
||||
namespace api {
|
||||
|
||||
class WebContents;
|
||||
|
||||
class BrowserView : public mate::TrackableObject<BrowserView> {
|
||||
public:
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
WebContents* web_contents() const { return api_web_contents_; }
|
||||
NativeBrowserView* view() const { return view_.get(); }
|
||||
|
||||
int32_t ID() const;
|
||||
|
||||
protected:
|
||||
BrowserView(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options);
|
||||
~BrowserView() override;
|
||||
|
||||
private:
|
||||
void Init(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
void SetAutoResize(AutoResizeFlags flags);
|
||||
void SetBounds(const gfx::Rect& bounds);
|
||||
void SetBackgroundColor(const std::string& color_name);
|
||||
|
||||
v8::Local<v8::Value> GetWebContents();
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
class WebContents* api_web_contents_;
|
||||
|
||||
std::unique_ptr<NativeBrowserView> view_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserView);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
|
||||
@@ -7,13 +7,12 @@
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "content/public/browser/tracing_controller.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::TracingController;
|
||||
|
||||
namespace mate {
|
||||
@@ -69,6 +68,10 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
dict.SetMethod("stopRecording", &StopRecording);
|
||||
dict.SetMethod("getTraceBufferUsage", base::Bind(
|
||||
&TracingController::GetTraceBufferUsage, controller));
|
||||
dict.SetMethod("setWatchEvent", base::Bind(
|
||||
&TracingController::SetWatchEvent, controller));
|
||||
dict.SetMethod("cancelWatchEvent", base::Bind(
|
||||
&TracingController::CancelWatchEvent, controller));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
using atom::AtomCookieDelegate;
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
@@ -55,32 +54,6 @@ struct Converter<net::CanonicalCookie> {
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<net::CookieStore::ChangeCause> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const net::CookieStore::ChangeCause& val) {
|
||||
switch (val) {
|
||||
case net::CookieStore::ChangeCause::INSERTED:
|
||||
case net::CookieStore::ChangeCause::EXPLICIT:
|
||||
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_BETWEEN:
|
||||
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_PREDICATE:
|
||||
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_SINGLE:
|
||||
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_CANONICAL:
|
||||
return mate::StringToV8(isolate, "explicit");
|
||||
case net::CookieStore::ChangeCause::OVERWRITE:
|
||||
return mate::StringToV8(isolate, "overwrite");
|
||||
case net::CookieStore::ChangeCause::EXPIRED:
|
||||
return mate::StringToV8(isolate, "expired");
|
||||
case net::CookieStore::ChangeCause::EVICTED:
|
||||
return mate::StringToV8(isolate, "evicted");
|
||||
case net::CookieStore::ChangeCause::EXPIRED_OVERWRITE:
|
||||
return mate::StringToV8(isolate, "expired-overwrite");
|
||||
default:
|
||||
return mate::StringToV8(isolate, "unknown");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
@@ -183,13 +156,6 @@ void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
|
||||
base::Bind(callback, success ? Cookies::SUCCESS : Cookies::FAILED));
|
||||
}
|
||||
|
||||
// Flushes cookie store in IO thread.
|
||||
void FlushCookieStoreOnIOThread(
|
||||
scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const base::Closure& callback) {
|
||||
GetCookieStore(getter)->FlushStore(base::Bind(RunCallbackInUI, callback));
|
||||
}
|
||||
|
||||
// Sets cookie with |details| in IO thread.
|
||||
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::unique_ptr<base::DictionaryValue> details,
|
||||
@@ -232,22 +198,19 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
GetCookieStore(getter)->SetCookieWithDetailsAsync(
|
||||
GURL(url), name, value, domain, path, creation_time,
|
||||
expiration_time, last_access_time, secure, http_only,
|
||||
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT,
|
||||
base::Bind(OnSetCookie, callback));
|
||||
net::CookieSameSite::DEFAULT_MODE, false,
|
||||
net::COOKIE_PRIORITY_DEFAULT, base::Bind(OnSetCookie, callback));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Cookies::Cookies(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context)
|
||||
: request_context_getter_(browser_context->url_request_context_getter()),
|
||||
cookie_delegate_(browser_context->cookie_delegate()) {
|
||||
: request_context_getter_(browser_context->url_request_context_getter()) {
|
||||
Init(isolate);
|
||||
cookie_delegate_->AddObserver(this);
|
||||
}
|
||||
|
||||
Cookies::~Cookies() {
|
||||
cookie_delegate_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void Cookies::Get(const base::DictionaryValue& filter,
|
||||
@@ -276,20 +239,6 @@ void Cookies::Set(const base::DictionaryValue& details,
|
||||
base::Bind(SetCookieOnIO, getter, Passed(&copied), callback));
|
||||
}
|
||||
|
||||
void Cookies::FlushStore(const base::Closure& callback) {
|
||||
auto getter = make_scoped_refptr(request_context_getter_);
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(FlushCookieStoreOnIOThread, getter, callback));
|
||||
}
|
||||
|
||||
void Cookies::OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
bool removed,
|
||||
net::CookieStore::ChangeCause cause) {
|
||||
Emit("changed", cookie, cause, removed);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
mate::Handle<Cookies> Cookies::Create(
|
||||
v8::Isolate* isolate,
|
||||
@@ -304,8 +253,7 @@ void Cookies::BuildPrototype(v8::Isolate* isolate,
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("get", &Cookies::Get)
|
||||
.SetMethod("remove", &Cookies::Remove)
|
||||
.SetMethod("set", &Cookies::Set)
|
||||
.SetMethod("flushStore", &Cookies::FlushStore);
|
||||
.SetMethod("set", &Cookies::Set);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/net/atom_cookie_delegate.h"
|
||||
#include "base/callback.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
@@ -27,8 +26,7 @@ class AtomBrowserContext;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Cookies : public mate::TrackableObject<Cookies>,
|
||||
public AtomCookieDelegate::Observer {
|
||||
class Cookies : public mate::TrackableObject<Cookies> {
|
||||
public:
|
||||
enum Error {
|
||||
SUCCESS,
|
||||
@@ -53,16 +51,9 @@ class Cookies : public mate::TrackableObject<Cookies>,
|
||||
void Remove(const GURL& url, const std::string& name,
|
||||
const base::Closure& callback);
|
||||
void Set(const base::DictionaryValue& details, const SetCallback& callback);
|
||||
void FlushStore(const base::Closure& callback);
|
||||
|
||||
// AtomCookieDelegate::Observer:
|
||||
void OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
bool removed,
|
||||
net::CookieStore::ChangeCause cause) override;
|
||||
|
||||
private:
|
||||
net::URLRequestContextGetter* request_context_getter_;
|
||||
scoped_refptr<AtomCookieDelegate> cookie_delegate_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
||||
};
|
||||
|
||||
@@ -9,16 +9,14 @@
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::DevToolsAgentHost;
|
||||
|
||||
namespace atom {
|
||||
@@ -46,12 +44,10 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||
const std::string& message) {
|
||||
DCHECK(agent_host == agent_host_.get());
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
std::unique_ptr<base::Value> parsed_message = base::JSONReader::Read(message);
|
||||
if (!parsed_message || !parsed_message->is_dict())
|
||||
std::unique_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
|
||||
if (!parsed_message->IsType(base::Value::TYPE_DICTIONARY))
|
||||
return;
|
||||
|
||||
base::DictionaryValue* dict =
|
||||
static_cast<base::DictionaryValue*>(parsed_message.get());
|
||||
int id;
|
||||
@@ -111,7 +107,7 @@ bool Debugger::IsAttached() {
|
||||
void Debugger::Detach() {
|
||||
if (!agent_host_.get())
|
||||
return;
|
||||
agent_host_->DetachClient(this);
|
||||
agent_host_->DetachClient();
|
||||
AgentHostClosed(agent_host_.get(), false);
|
||||
agent_host_ = nullptr;
|
||||
}
|
||||
@@ -136,11 +132,11 @@ void Debugger::SendCommand(mate::Arguments* args) {
|
||||
request.SetInteger("id", request_id);
|
||||
request.SetString("method", method);
|
||||
if (!command_params.empty())
|
||||
request.Set("params", base::WrapUnique(command_params.DeepCopy()));
|
||||
request.Set("params", command_params.DeepCopy());
|
||||
|
||||
std::string json_args;
|
||||
base::JSONWriter::Write(request, &json_args);
|
||||
agent_host_->DispatchProtocolMessage(this, json_args);
|
||||
agent_host_->DispatchProtocolMessage(json_args);
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -4,16 +4,14 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_desktop_capturer.h"
|
||||
|
||||
using base::PlatformThreadRef;
|
||||
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/browser/media/desktop_media_list.h"
|
||||
#include "content/public/browser/desktop_capture.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
|
||||
#include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
@@ -51,14 +49,22 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size) {
|
||||
webrtc::DesktopCaptureOptions options =
|
||||
content::CreateDesktopCaptureOptions();
|
||||
webrtc::DesktopCaptureOptions::CreateDefault();
|
||||
|
||||
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
|
||||
capture_screen ? webrtc::DesktopCapturer::CreateScreenCapturer(options)
|
||||
: nullptr);
|
||||
std::unique_ptr<webrtc::DesktopCapturer> window_capturer(
|
||||
capture_window ? webrtc::DesktopCapturer::CreateWindowCapturer(options)
|
||||
: nullptr);
|
||||
#if defined(OS_WIN)
|
||||
// On windows, desktop effects (e.g. Aero) will be disabled when the Desktop
|
||||
// capture API is active by default.
|
||||
// We keep the desktop effects in most times. Howerver, the screen still
|
||||
// fickers when the API is capturing the window due to limitation of current
|
||||
// implemetation. This is a known and wontFix issue in webrtc (see:
|
||||
// http://code.google.com/p/webrtc/issues/detail?id=3373)
|
||||
options.set_disable_effects(false);
|
||||
#endif
|
||||
|
||||
std::unique_ptr<webrtc::ScreenCapturer> screen_capturer(
|
||||
capture_screen ? webrtc::ScreenCapturer::Create(options) : nullptr);
|
||||
std::unique_ptr<webrtc::WindowCapturer> window_capturer(
|
||||
capture_window ? webrtc::WindowCapturer::Create(options) : nullptr);
|
||||
media_list_.reset(new NativeDesktopMediaList(
|
||||
std::move(screen_capturer), std::move(window_capturer)));
|
||||
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/ui/certificate_trust.h"
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
#include "atom/browser/ui/message_box.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
@@ -37,30 +35,6 @@ struct Converter<file_dialog::Filter> {
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<file_dialog::DialogSettings> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::DialogSettings* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
dict.Get("window", &(out->parent_window));
|
||||
dict.Get("title", &(out->title));
|
||||
dict.Get("message", &(out->message));
|
||||
dict.Get("buttonLabel", &(out->button_label));
|
||||
dict.Get("nameFieldLabel", &(out->name_field_label));
|
||||
dict.Get("defaultPath", &(out->default_path));
|
||||
dict.Get("filters", &(out->filters));
|
||||
dict.Get("properties", &(out->properties));
|
||||
dict.Get("showsTagField", &(out->shows_tag_field));
|
||||
#if defined(MAS_BUILD)
|
||||
dict.Get("securityScopedBookmarks", &(out->security_scoped_bookmarks));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
@@ -73,8 +47,6 @@ void ShowMessageBox(int type,
|
||||
const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& detail,
|
||||
const std::string& checkbox_label,
|
||||
bool checkbox_checked,
|
||||
const gfx::ImageSkia& icon,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
@@ -83,44 +55,56 @@ void ShowMessageBox(int type,
|
||||
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
atom::ShowMessageBox(window, static_cast<atom::MessageBoxType>(type),
|
||||
buttons, default_id, cancel_id, options, title,
|
||||
message, detail, checkbox_label, checkbox_checked,
|
||||
icon, callback);
|
||||
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons,
|
||||
default_id, cancel_id, options, title,
|
||||
message, detail, icon, callback);
|
||||
} else {
|
||||
int chosen = atom::ShowMessageBox(
|
||||
window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
|
||||
cancel_id, options, title, message, detail, icon);
|
||||
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
|
||||
buttons, default_id, cancel_id,
|
||||
options, title, message, detail, icon);
|
||||
args->Return(chosen);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowOpenDialog(const file_dialog::DialogSettings& settings,
|
||||
void ShowOpenDialog(const std::string& title,
|
||||
const std::string& button_label,
|
||||
const base::FilePath& default_path,
|
||||
const file_dialog::Filters& filters,
|
||||
int properties,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Value> peek = args->PeekNext();
|
||||
file_dialog::OpenDialogCallback callback;
|
||||
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
file_dialog::ShowOpenDialog(settings, callback);
|
||||
file_dialog::ShowOpenDialog(window, title, button_label, default_path,
|
||||
filters, properties, callback);
|
||||
} else {
|
||||
std::vector<base::FilePath> paths;
|
||||
if (file_dialog::ShowOpenDialog(settings, &paths))
|
||||
if (file_dialog::ShowOpenDialog(window, title, button_label, default_path,
|
||||
filters, properties, &paths))
|
||||
args->Return(paths);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowSaveDialog(const file_dialog::DialogSettings& settings,
|
||||
void ShowSaveDialog(const std::string& title,
|
||||
const std::string& button_label,
|
||||
const base::FilePath& default_path,
|
||||
const file_dialog::Filters& filters,
|
||||
atom::NativeWindow* window,
|
||||
mate::Arguments* args) {
|
||||
v8::Local<v8::Value> peek = args->PeekNext();
|
||||
file_dialog::SaveDialogCallback callback;
|
||||
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
|
||||
peek,
|
||||
&callback)) {
|
||||
file_dialog::ShowSaveDialog(settings, callback);
|
||||
file_dialog::ShowSaveDialog(window, title, button_label, default_path,
|
||||
filters, callback);
|
||||
} else {
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialog(settings, &path))
|
||||
if (file_dialog::ShowSaveDialog(window, title, button_label, default_path,
|
||||
filters, &path))
|
||||
args->Return(path);
|
||||
}
|
||||
}
|
||||
@@ -132,10 +116,6 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
|
||||
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
|
||||
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
dict.SetMethod("showCertificateTrustDialog",
|
||||
&certificate_trust::ShowCertificateTrust);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -10,13 +10,12 @@
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/filename_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
@@ -78,9 +77,9 @@ DownloadItem::~DownloadItem() {
|
||||
void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) {
|
||||
if (download_item_->IsDone()) {
|
||||
Emit("done", item->GetState());
|
||||
|
||||
// Destroy the item once item is downloaded.
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, GetDestroyClosure());
|
||||
base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure());
|
||||
} else {
|
||||
Emit("updated", item->GetState());
|
||||
}
|
||||
@@ -110,6 +109,7 @@ bool DownloadItem::CanResume() const {
|
||||
|
||||
void DownloadItem::Cancel() {
|
||||
download_item_->Cancel(true);
|
||||
download_item_->Remove();
|
||||
}
|
||||
|
||||
int64_t DownloadItem::GetReceivedBytes() const {
|
||||
@@ -134,7 +134,7 @@ std::string DownloadItem::GetFilename() const {
|
||||
std::string(),
|
||||
download_item_->GetSuggestedFilename(),
|
||||
GetMimeType(),
|
||||
"download").LossyDisplayName());
|
||||
std::string()).LossyDisplayName());
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetContentDisposition() const {
|
||||
@@ -145,10 +145,6 @@ const GURL& DownloadItem::GetURL() const {
|
||||
return download_item_->GetURL();
|
||||
}
|
||||
|
||||
const std::vector<GURL>& DownloadItem::GetURLChain() const {
|
||||
return download_item_->GetUrlChain();
|
||||
}
|
||||
|
||||
content::DownloadItem::DownloadState DownloadItem::GetState() const {
|
||||
return download_item_->GetState();
|
||||
}
|
||||
@@ -165,18 +161,6 @@ base::FilePath DownloadItem::GetSavePath() const {
|
||||
return save_path_;
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetLastModifiedTime() const {
|
||||
return download_item_->GetLastModifiedTime();
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetETag() const {
|
||||
return download_item_->GetETag();
|
||||
}
|
||||
|
||||
double DownloadItem::GetStartTime() const {
|
||||
return download_item_->GetStartTime().ToDoubleT();
|
||||
}
|
||||
|
||||
// static
|
||||
void DownloadItem::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
@@ -195,14 +179,10 @@ void DownloadItem::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getFilename", &DownloadItem::GetFilename)
|
||||
.SetMethod("getContentDisposition", &DownloadItem::GetContentDisposition)
|
||||
.SetMethod("getURL", &DownloadItem::GetURL)
|
||||
.SetMethod("getURLChain", &DownloadItem::GetURLChain)
|
||||
.SetMethod("getState", &DownloadItem::GetState)
|
||||
.SetMethod("isDone", &DownloadItem::IsDone)
|
||||
.SetMethod("setSavePath", &DownloadItem::SetSavePath)
|
||||
.SetMethod("getSavePath", &DownloadItem::GetSavePath)
|
||||
.SetMethod("getLastModifiedTime", &DownloadItem::GetLastModifiedTime)
|
||||
.SetMethod("getETag", &DownloadItem::GetETag)
|
||||
.SetMethod("getStartTime", &DownloadItem::GetStartTime);
|
||||
.SetMethod("getSavePath", &DownloadItem::GetSavePath);
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#define ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/files/file_path.h"
|
||||
@@ -39,14 +38,10 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
std::string GetFilename() const;
|
||||
std::string GetContentDisposition() const;
|
||||
const GURL& GetURL() const;
|
||||
const std::vector<GURL>& GetURLChain() const;
|
||||
content::DownloadItem::DownloadState GetState() const;
|
||||
bool IsDone() const;
|
||||
void SetSavePath(const base::FilePath& path);
|
||||
base::FilePath GetSavePath() const;
|
||||
std::string GetLastModifiedTime() const;
|
||||
std::string GetETag() const;
|
||||
double GetStartTime() const;
|
||||
|
||||
protected:
|
||||
DownloadItem(v8::Isolate* isolate, content::DownloadItem* download_item);
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
// Copyright (c) 2017 Amaplex Software, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_in_app_purchase.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<in_app_purchase::Payment> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const in_app_purchase::Payment& payment) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("productIdentifier", payment.productIdentifier);
|
||||
dict.Set("quantity", payment.quantity);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<in_app_purchase::Transaction> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const in_app_purchase::Transaction& val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("transactionIdentifier", val.transactionIdentifier);
|
||||
dict.Set("transactionDate", val.transactionDate);
|
||||
dict.Set("originalTransactionIdentifier",
|
||||
val.originalTransactionIdentifier);
|
||||
dict.Set("transactionState", val.transactionState);
|
||||
dict.Set("errorCode", val.errorCode);
|
||||
dict.Set("errorMessage", val.errorMessage);
|
||||
dict.Set("payment", val.payment);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// static
|
||||
mate::Handle<InAppPurchase> InAppPurchase::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new InAppPurchase(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "InAppPurchase"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("canMakePayments", &in_app_purchase::CanMakePayments)
|
||||
.SetMethod("getReceiptURL", &in_app_purchase::GetReceiptURL)
|
||||
.SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct);
|
||||
}
|
||||
|
||||
InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
InAppPurchase::~InAppPurchase() {
|
||||
}
|
||||
|
||||
void InAppPurchase::PurchaseProduct(const std::string& product_id,
|
||||
mate::Arguments* args) {
|
||||
int quantity = 1;
|
||||
in_app_purchase::InAppPurchaseCallback callback;
|
||||
args->GetNext(&quantity);
|
||||
args->GetNext(&callback);
|
||||
in_app_purchase::PurchaseProduct(product_id, quantity, callback);
|
||||
}
|
||||
|
||||
void InAppPurchase::OnTransactionsUpdated(
|
||||
const std::vector<in_app_purchase::Transaction>& transactions) {
|
||||
Emit("transactions-updated", transactions);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::InAppPurchase;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
#if defined(OS_MACOSX)
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("inAppPurchase", InAppPurchase::Create(isolate));
|
||||
dict.Set("InAppPurchase",
|
||||
InAppPurchase::GetConstructor(isolate)->GetFunction());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_in_app_purchase, Initialize)
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright (c) 2017 Amaplex Software, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/mac/in_app_purchase.h"
|
||||
#include "atom/browser/mac/in_app_purchase_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class InAppPurchase: public mate::EventEmitter<InAppPurchase>,
|
||||
public in_app_purchase::TransactionObserver {
|
||||
public:
|
||||
static mate::Handle<InAppPurchase> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit InAppPurchase(v8::Isolate* isolate);
|
||||
~InAppPurchase() override;
|
||||
|
||||
void PurchaseProduct(const std::string& product_id, mate::Arguments* args);
|
||||
|
||||
// TransactionObserver:
|
||||
void OnTransactionsUpdated(
|
||||
const std::vector<in_app_purchase::Transaction>& transactions) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(InAppPurchase);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
|
||||
@@ -23,13 +23,9 @@ Menu::Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||
: model_(new AtomMenuModel(this)),
|
||||
parent_(nullptr) {
|
||||
InitWith(isolate, wrapper);
|
||||
model_->AddObserver(this);
|
||||
}
|
||||
|
||||
Menu::~Menu() {
|
||||
if (model_) {
|
||||
model_->RemoveObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::AfterInit(v8::Isolate* isolate) {
|
||||
@@ -47,21 +43,15 @@ void Menu::AfterInit(v8::Isolate* isolate) {
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdChecked(int command_id) const {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return is_checked_.Run(GetWrapper(), command_id);
|
||||
return is_checked_.Run(command_id);
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdEnabled(int command_id) const {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return is_enabled_.Run(GetWrapper(), command_id);
|
||||
return is_enabled_.Run(command_id);
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdVisible(int command_id) const {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return is_visible_.Run(GetWrapper(), command_id);
|
||||
return is_visible_.Run(command_id);
|
||||
}
|
||||
|
||||
bool Menu::GetAcceleratorForCommandIdWithParams(
|
||||
@@ -71,23 +61,18 @@ bool Menu::GetAcceleratorForCommandIdWithParams(
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
v8::Local<v8::Value> val = get_accelerator_.Run(
|
||||
GetWrapper(), command_id, use_default_accelerator);
|
||||
command_id, use_default_accelerator);
|
||||
return mate::ConvertFromV8(isolate(), val, accelerator);
|
||||
}
|
||||
|
||||
void Menu::ExecuteCommand(int command_id, int flags) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
execute_command_.Run(
|
||||
GetWrapper(),
|
||||
mate::internal::CreateEventFromFlags(isolate(), flags),
|
||||
command_id);
|
||||
}
|
||||
|
||||
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
menu_will_show_.Run(GetWrapper());
|
||||
menu_will_show_.Run();
|
||||
}
|
||||
|
||||
void Menu::InsertItemAt(
|
||||
@@ -168,14 +153,6 @@ bool Menu::IsVisibleAt(int index) const {
|
||||
return model_->IsVisibleAt(index);
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillClose() {
|
||||
Emit("menu-will-close");
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillShow() {
|
||||
Emit("menu-will-show");
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
@@ -199,8 +176,7 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
|
||||
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
|
||||
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
|
||||
.SetMethod("popupAt", &Menu::PopupAt)
|
||||
.SetMethod("closePopupAt", &Menu::ClosePopupAt);
|
||||
.SetMethod("popupAt", &Menu::PopupAt);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -18,8 +18,7 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
class Menu : public mate::TrackableObject<Menu>,
|
||||
public AtomMenuModel::Delegate,
|
||||
public AtomMenuModel::Observer {
|
||||
public AtomMenuModel::Delegate {
|
||||
public:
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
|
||||
@@ -54,17 +53,13 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
void ExecuteCommand(int command_id, int event_flags) override;
|
||||
void MenuWillShow(ui::SimpleMenuModel* source) override;
|
||||
|
||||
virtual void PopupAt(Window* window, int x, int y, int positioning_item,
|
||||
const base::Closure& callback) = 0;
|
||||
virtual void ClosePopupAt(int32_t window_id) = 0;
|
||||
virtual void PopupAt(Window* window,
|
||||
int x = -1, int y = -1,
|
||||
int positioning_item = 0) = 0;
|
||||
|
||||
std::unique_ptr<AtomMenuModel> model_;
|
||||
Menu* parent_;
|
||||
|
||||
// Observable:
|
||||
void OnMenuWillClose() override;
|
||||
void OnMenuWillShow() override;
|
||||
|
||||
private:
|
||||
void InsertItemAt(int index, int command_id, const base::string16& label);
|
||||
void InsertSeparatorAt(int index);
|
||||
@@ -93,14 +88,12 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
bool IsVisibleAt(int index) const;
|
||||
|
||||
// Stored delegate methods.
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_checked_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_enabled_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_visible_;
|
||||
base::Callback<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)>
|
||||
get_accelerator_;
|
||||
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)>
|
||||
execute_command_;
|
||||
base::Callback<void(v8::Local<v8::Value>)> menu_will_show_;
|
||||
base::Callback<bool(int)> is_checked_;
|
||||
base::Callback<bool(int)> is_enabled_;
|
||||
base::Callback<bool(int)> is_visible_;
|
||||
base::Callback<v8::Local<v8::Value>(int, bool)> get_accelerator_;
|
||||
base::Callback<void(v8::Local<v8::Value>, int)> execute_command_;
|
||||
base::Callback<void()> menu_will_show_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Menu);
|
||||
};
|
||||
|
||||
@@ -7,13 +7,10 @@
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#import "atom/browser/ui/cocoa/atom_menu_controller.h"
|
||||
|
||||
using base::scoped_nsobject;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -22,27 +19,14 @@ class MenuMac : public Menu {
|
||||
protected:
|
||||
MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
|
||||
void PopupAt(Window* window, int x, int y, int positioning_item,
|
||||
const base::Closure& callback) override;
|
||||
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
int32_t window_id,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::Closure callback);
|
||||
void ClosePopupAt(int32_t window_id) override;
|
||||
void PopupAt(Window* window, int x, int y, int positioning_item) override;
|
||||
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller_;
|
||||
|
||||
private:
|
||||
friend class Menu;
|
||||
|
||||
void OnClosed(int32_t window_id, base::Closure callback);
|
||||
|
||||
scoped_nsobject<AtomMenuController> menu_controller_;
|
||||
|
||||
// window ID -> open context menu
|
||||
std::map<int32_t, scoped_nsobject<AtomMenuController>> popup_controllers_;
|
||||
|
||||
base::WeakPtrFactory<MenuMac> weak_factory_;
|
||||
static void SendActionToFirstResponder(const std::string& action);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuMac);
|
||||
};
|
||||
|
||||
@@ -6,58 +6,35 @@
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "base/mac/scoped_sending_event.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuMac::MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||
: Menu(isolate, wrapper),
|
||||
weak_factory_(this) {
|
||||
: Menu(isolate, wrapper) {
|
||||
}
|
||||
|
||||
void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item,
|
||||
const base::Closure& callback) {
|
||||
void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
return;
|
||||
|
||||
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
|
||||
native_window->GetWeakPtr(), window->ID(), x, y,
|
||||
positioning_item, callback);
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
|
||||
}
|
||||
|
||||
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
int32_t window_id,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::Closure callback) {
|
||||
if (!native_window)
|
||||
return;
|
||||
brightray::InspectableWebContents* web_contents =
|
||||
native_window->inspectable_web_contents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
auto close_callback = base::Bind(
|
||||
&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||
popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>(
|
||||
[[AtomMenuController alloc] initWithModel:model()
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:model_.get()
|
||||
useDefaultAccelerator:NO]);
|
||||
NSMenu* menu = [popup_controllers_[window_id] menu];
|
||||
NSMenu* menu = [menu_controller menu];
|
||||
NSView* view = web_contents->GetView()->GetNativeView();
|
||||
|
||||
// Which menu item to show.
|
||||
@@ -92,43 +69,13 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
if (rightmostMenuPoint > screenRight)
|
||||
position.x = position.x - [menu size].width;
|
||||
|
||||
[popup_controllers_[window_id] setCloseCallback:close_callback];
|
||||
// Make sure events can be pumped while the menu is up.
|
||||
base::MessageLoop::ScopedNestableTaskAllower allow(
|
||||
base::MessageLoop::current());
|
||||
|
||||
// One of the events that could be pumped is |window.close()|.
|
||||
// User-initiated event-tracking loops protect against this by
|
||||
// setting flags in -[CrApplication sendEvent:], but since
|
||||
// web-content menus are initiated by IPC message the setup has to
|
||||
// be done manually.
|
||||
base::mac::ScopedSendingEvent sendingEventScoper;
|
||||
|
||||
// Don't emit unresponsive event when showing menu.
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
|
||||
// Show the menu.
|
||||
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
|
||||
}
|
||||
|
||||
void MenuMac::ClosePopupAt(int32_t window_id) {
|
||||
auto controller = popup_controllers_.find(window_id);
|
||||
if (controller != popup_controllers_.end()) {
|
||||
// Close the controller for the window.
|
||||
[controller->second cancel];
|
||||
} else if (window_id == -1) {
|
||||
// Or just close all opened controllers.
|
||||
for (auto it = popup_controllers_.begin();
|
||||
it != popup_controllers_.end();) {
|
||||
// The iterator is invalidated after the call.
|
||||
[(it++)->second cancel];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MenuMac::OnClosed(int32_t window_id, base::Closure callback) {
|
||||
popup_controllers_.erase(window_id);
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::SetApplicationMenu(Menu* base_menu) {
|
||||
MenuMac* menu = static_cast<MenuMac*>(base_menu);
|
||||
|
||||
@@ -6,76 +6,51 @@
|
||||
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "brightray/browser/inspectable_web_contents.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
using views::MenuRunner;
|
||||
#include "ui/views/controls/menu/menu_runner.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||
: Menu(isolate, wrapper),
|
||||
weak_factory_(this) {
|
||||
: Menu(isolate, wrapper) {
|
||||
}
|
||||
|
||||
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item,
|
||||
const base::Closure& callback) {
|
||||
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
|
||||
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
|
||||
if (!native_window)
|
||||
return;
|
||||
auto* web_contents = native_window->inspectable_web_contents();
|
||||
content::WebContents* web_contents = native_window->web_contents();
|
||||
if (!web_contents)
|
||||
return;
|
||||
content::RenderWidgetHostView* view = web_contents->GetRenderWidgetHostView();
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
// (-1, -1) means showing on mouse location.
|
||||
gfx::Point location;
|
||||
if (x == -1 || y == -1) {
|
||||
location = display::Screen::GetScreen()->GetCursorScreenPoint();
|
||||
} else {
|
||||
auto* view = web_contents->GetView()->GetWebView();
|
||||
gfx::Point origin = view->bounds().origin();
|
||||
gfx::Point origin = view->GetViewBounds().origin();
|
||||
location = gfx::Point(origin.x() + x, origin.y() + y);
|
||||
}
|
||||
|
||||
int flags = MenuRunner::CONTEXT_MENU | MenuRunner::HAS_MNEMONICS;
|
||||
|
||||
// Don't emit unresponsive event when showing menu.
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
|
||||
// Show the menu.
|
||||
int32_t window_id = window->ID();
|
||||
auto close_callback = base::Bind(
|
||||
&MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||
menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner(
|
||||
model(), flags, close_callback));
|
||||
menu_runners_[window_id]->RunMenuAt(
|
||||
views::MenuRunner menu_runner(
|
||||
model(),
|
||||
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
|
||||
ignore_result(menu_runner.RunMenuAt(
|
||||
static_cast<NativeWindowViews*>(window->window())->widget(),
|
||||
NULL,
|
||||
gfx::Rect(location, gfx::Size()),
|
||||
views::MENU_ANCHOR_TOPLEFT,
|
||||
ui::MENU_SOURCE_MOUSE);
|
||||
}
|
||||
|
||||
void MenuViews::ClosePopupAt(int32_t window_id) {
|
||||
auto runner = menu_runners_.find(window_id);
|
||||
if (runner != menu_runners_.end()) {
|
||||
// Close the runner for the window.
|
||||
runner->second->Cancel();
|
||||
} else if (window_id == -1) {
|
||||
// Or just close all opened runners.
|
||||
for (auto it = menu_runners_.begin(); it != menu_runners_.end();) {
|
||||
// The iterator is invalidated after the call.
|
||||
(it++)->second->Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MenuViews::OnClosed(int32_t window_id, base::Closure callback) {
|
||||
menu_runners_.erase(window_id);
|
||||
callback.Run();
|
||||
ui::MENU_SOURCE_MOUSE));
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -5,12 +5,8 @@
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/views/controls/menu/menu_runner.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -21,18 +17,9 @@ class MenuViews : public Menu {
|
||||
MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
|
||||
protected:
|
||||
void PopupAt(Window* window, int x, int y, int positioning_item,
|
||||
const base::Closure& callback) override;
|
||||
void ClosePopupAt(int32_t window_id) override;
|
||||
void PopupAt(Window* window, int x, int y, int positioning_item) override;
|
||||
|
||||
private:
|
||||
void OnClosed(int32_t window_id, base::Closure callback);
|
||||
|
||||
// window ID -> open context menu
|
||||
std::map<int32_t, std::unique_ptr<views::MenuRunner>> menu_runners_;
|
||||
|
||||
base::WeakPtrFactory<MenuViews> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuViews);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_net.h"
|
||||
#include "atom/browser/api/atom_api_url_request.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Net::Net(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
Net::~Net() {}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Net::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new Net(isolate)).ToV8();
|
||||
}
|
||||
|
||||
// static
|
||||
void Net::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Net"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetProperty("URLRequest", &Net::URLRequest);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Net::URLRequest(v8::Isolate* isolate) {
|
||||
return URLRequest::GetConstructor(isolate)->GetFunction();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::Net;
|
||||
using atom::api::URLRequest;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
|
||||
URLRequest::SetConstructor(isolate, base::Bind(URLRequest::New));
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("net", Net::Create(isolate));
|
||||
dict.Set("Net", Net::GetConstructor(isolate)->GetFunction());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_net, Initialize)
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_NET_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_NET_H_
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Net : public mate::EventEmitter<Net> {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
v8::Local<v8::Value> URLRequest(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
explicit Net(v8::Isolate* isolate);
|
||||
~Net() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Net);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_NET_H_
|
||||
@@ -1,273 +0,0 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_notification.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/browser_client.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "url/gurl.h"
|
||||
// Must be the last in the includes list.
|
||||
// See https://github.com/electron/electron/issues/10363
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
template<>
|
||||
struct Converter<brightray::NotificationAction> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
brightray::NotificationAction* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
|
||||
if (!dict.Get("type", &(out->type))) {
|
||||
return false;
|
||||
}
|
||||
dict.Get("text", &(out->text));
|
||||
return true;
|
||||
}
|
||||
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
brightray::NotificationAction val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("text", val.text);
|
||||
dict.Set("type", val.type);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Notification::Notification(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
mate::Arguments* args) {
|
||||
InitWith(isolate, wrapper);
|
||||
|
||||
presenter_ = brightray::BrowserClient::Get()->GetNotificationPresenter();
|
||||
|
||||
mate::Dictionary opts;
|
||||
if (args->GetNext(&opts)) {
|
||||
opts.Get("title", &title_);
|
||||
opts.Get("subtitle", &subtitle_);
|
||||
opts.Get("body", &body_);
|
||||
has_icon_ = opts.Get("icon", &icon_);
|
||||
if (has_icon_) {
|
||||
opts.Get("icon", &icon_path_);
|
||||
}
|
||||
opts.Get("silent", &silent_);
|
||||
opts.Get("replyPlaceholder", &reply_placeholder_);
|
||||
opts.Get("hasReply", &has_reply_);
|
||||
opts.Get("actions", &actions_);
|
||||
opts.Get("sound", &sound_);
|
||||
opts.Get("closeButtonText", &close_button_text_);
|
||||
}
|
||||
}
|
||||
|
||||
Notification::~Notification() {
|
||||
if (notification_)
|
||||
notification_->set_delegate(nullptr);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::WrappableBase* Notification::New(mate::Arguments* args) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
args->ThrowError("Cannot create Notification before app is ready");
|
||||
return nullptr;
|
||||
}
|
||||
return new Notification(args->isolate(), args->GetThis(), args);
|
||||
}
|
||||
|
||||
// Getters
|
||||
base::string16 Notification::GetTitle() const {
|
||||
return title_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetSubtitle() const {
|
||||
return subtitle_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetBody() const {
|
||||
return body_;
|
||||
}
|
||||
|
||||
bool Notification::GetSilent() const {
|
||||
return silent_;
|
||||
}
|
||||
|
||||
bool Notification::GetHasReply() const {
|
||||
return has_reply_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetReplyPlaceholder() const {
|
||||
return reply_placeholder_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetSound() const {
|
||||
return sound_;
|
||||
}
|
||||
|
||||
std::vector<brightray::NotificationAction> Notification::GetActions() const {
|
||||
return actions_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetCloseButtonText() const {
|
||||
return close_button_text_;
|
||||
}
|
||||
|
||||
// Setters
|
||||
void Notification::SetTitle(const base::string16& new_title) {
|
||||
title_ = new_title;
|
||||
}
|
||||
|
||||
void Notification::SetSubtitle(const base::string16& new_subtitle) {
|
||||
subtitle_ = new_subtitle;
|
||||
}
|
||||
|
||||
void Notification::SetBody(const base::string16& new_body) {
|
||||
body_ = new_body;
|
||||
}
|
||||
|
||||
void Notification::SetSilent(bool new_silent) {
|
||||
silent_ = new_silent;
|
||||
}
|
||||
|
||||
void Notification::SetHasReply(bool new_has_reply) {
|
||||
has_reply_ = new_has_reply;
|
||||
}
|
||||
|
||||
void Notification::SetReplyPlaceholder(const base::string16& new_placeholder) {
|
||||
reply_placeholder_ = new_placeholder;
|
||||
}
|
||||
|
||||
void Notification::SetSound(const base::string16& new_sound) {
|
||||
sound_ = new_sound;
|
||||
}
|
||||
|
||||
void Notification::SetActions(
|
||||
const std::vector<brightray::NotificationAction>& actions) {
|
||||
actions_ = actions;
|
||||
}
|
||||
|
||||
void Notification::SetCloseButtonText(const base::string16& text) {
|
||||
close_button_text_ = text;
|
||||
}
|
||||
|
||||
void Notification::NotificationAction(int index) {
|
||||
Emit("action", index);
|
||||
}
|
||||
|
||||
void Notification::NotificationClick() {
|
||||
Emit("click");
|
||||
}
|
||||
|
||||
void Notification::NotificationReplied(const std::string& reply) {
|
||||
Emit("reply", reply);
|
||||
}
|
||||
|
||||
void Notification::NotificationDisplayed() {
|
||||
Emit("show");
|
||||
}
|
||||
|
||||
void Notification::NotificationDestroyed() {
|
||||
}
|
||||
|
||||
void Notification::NotificationClosed() {
|
||||
Emit("close");
|
||||
}
|
||||
|
||||
void Notification::Close() {
|
||||
if (notification_) {
|
||||
notification_->Dismiss();
|
||||
notification_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Showing notifications
|
||||
void Notification::Show() {
|
||||
Close();
|
||||
if (presenter_) {
|
||||
notification_ = presenter_->CreateNotification(this);
|
||||
if (notification_) {
|
||||
brightray::NotificationOptions options;
|
||||
options.title = title_;
|
||||
options.subtitle = subtitle_;
|
||||
options.msg = body_;
|
||||
options.icon_url = GURL();
|
||||
options.icon = icon_.AsBitmap();
|
||||
options.silent = silent_;
|
||||
options.has_reply = has_reply_;
|
||||
options.reply_placeholder = reply_placeholder_;
|
||||
options.actions = actions_;
|
||||
options.sound = sound_;
|
||||
options.close_button_text = close_button_text_;
|
||||
notification_->Show(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Notification::IsSupported() {
|
||||
return !!brightray::BrowserClient::Get()->GetNotificationPresenter();
|
||||
}
|
||||
|
||||
// static
|
||||
void Notification::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Notification"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("show", &Notification::Show)
|
||||
.SetMethod("close", &Notification::Close)
|
||||
.SetProperty("title", &Notification::GetTitle, &Notification::SetTitle)
|
||||
.SetProperty("subtitle", &Notification::GetSubtitle,
|
||||
&Notification::SetSubtitle)
|
||||
.SetProperty("body", &Notification::GetBody, &Notification::SetBody)
|
||||
.SetProperty("silent", &Notification::GetSilent,
|
||||
&Notification::SetSilent)
|
||||
.SetProperty("hasReply", &Notification::GetHasReply,
|
||||
&Notification::SetHasReply)
|
||||
.SetProperty("replyPlaceholder", &Notification::GetReplyPlaceholder,
|
||||
&Notification::SetReplyPlaceholder)
|
||||
.SetProperty("sound", &Notification::GetSound,
|
||||
&Notification::SetSound)
|
||||
.SetProperty("actions", &Notification::GetActions,
|
||||
&Notification::SetActions)
|
||||
.SetProperty("closeButtonText", &Notification::GetCloseButtonText,
|
||||
&Notification::SetCloseButtonText);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::Notification;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
Notification::SetConstructor(isolate, base::Bind(&Notification::New));
|
||||
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Notification",
|
||||
Notification::GetConstructor(isolate)->GetFunction());
|
||||
|
||||
dict.SetMethod("isSupported", &Notification::IsSupported);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_notification, Initialize)
|
||||
@@ -1,97 +0,0 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/notification.h"
|
||||
#include "brightray/browser/notification_delegate.h"
|
||||
#include "brightray/browser/notification_presenter.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Notification : public mate::TrackableObject<Notification>,
|
||||
public brightray::NotificationDelegate {
|
||||
public:
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
static bool IsSupported();
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// NotificationDelegate:
|
||||
void NotificationAction(int index) override;
|
||||
void NotificationClick() override;
|
||||
void NotificationReplied(const std::string& reply) override;
|
||||
void NotificationDisplayed() override;
|
||||
void NotificationDestroyed() override;
|
||||
void NotificationClosed() override;
|
||||
|
||||
protected:
|
||||
Notification(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
mate::Arguments* args);
|
||||
~Notification() override;
|
||||
|
||||
void Show();
|
||||
void Close();
|
||||
|
||||
// Prop Getters
|
||||
base::string16 GetTitle() const;
|
||||
base::string16 GetSubtitle() const;
|
||||
base::string16 GetBody() const;
|
||||
bool GetSilent() const;
|
||||
bool GetHasReply() const;
|
||||
base::string16 GetReplyPlaceholder() const;
|
||||
base::string16 GetSound() const;
|
||||
std::vector<brightray::NotificationAction> GetActions() const;
|
||||
base::string16 GetCloseButtonText() const;
|
||||
|
||||
// Prop Setters
|
||||
void SetTitle(const base::string16& new_title);
|
||||
void SetSubtitle(const base::string16& new_subtitle);
|
||||
void SetBody(const base::string16& new_body);
|
||||
void SetSilent(bool new_silent);
|
||||
void SetHasReply(bool new_has_reply);
|
||||
void SetReplyPlaceholder(const base::string16& new_reply_placeholder);
|
||||
void SetSound(const base::string16& sound);
|
||||
void SetActions(const std::vector<brightray::NotificationAction>& actions);
|
||||
void SetCloseButtonText(const base::string16& text);
|
||||
|
||||
private:
|
||||
base::string16 title_;
|
||||
base::string16 subtitle_;
|
||||
base::string16 body_;
|
||||
gfx::Image icon_;
|
||||
base::string16 icon_path_;
|
||||
bool has_icon_ = false;
|
||||
bool silent_ = false;
|
||||
bool has_reply_ = false;
|
||||
base::string16 reply_placeholder_;
|
||||
base::string16 sound_;
|
||||
std::vector<brightray::NotificationAction> actions_;
|
||||
base::string16 close_button_text_;
|
||||
|
||||
brightray::NotificationPresenter* presenter_;
|
||||
|
||||
base::WeakPtr<brightray::Notification> notification_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Notification);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_
|
||||
@@ -5,24 +5,16 @@
|
||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/power_monitor/power_monitor.h"
|
||||
#include "base/power_monitor/power_monitor_device_source.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
|
||||
#if defined(OS_LINUX)
|
||||
SetShutdownHandler(base::Bind(&PowerMonitor::ShouldShutdown,
|
||||
base::Unretained(this)));
|
||||
#elif defined(OS_MACOSX)
|
||||
Browser::Get()->SetShutdownHandler(base::Bind(&PowerMonitor::ShouldShutdown,
|
||||
base::Unretained(this)));
|
||||
#endif
|
||||
base::PowerMonitor::Get()->AddObserver(this);
|
||||
Init(isolate);
|
||||
}
|
||||
@@ -31,20 +23,6 @@ PowerMonitor::~PowerMonitor() {
|
||||
base::PowerMonitor::Get()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
bool PowerMonitor::ShouldShutdown() {
|
||||
return !Emit("shutdown");
|
||||
}
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
void PowerMonitor::BlockShutdown() {
|
||||
PowerObserverLinux::BlockShutdown();
|
||||
}
|
||||
|
||||
void PowerMonitor::UnblockShutdown() {
|
||||
PowerObserverLinux::UnblockShutdown();
|
||||
}
|
||||
#endif
|
||||
|
||||
void PowerMonitor::OnPowerStateChange(bool on_battery_power) {
|
||||
if (on_battery_power)
|
||||
Emit("on-battery");
|
||||
@@ -65,7 +43,7 @@ v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate,
|
||||
"Cannot require \"powerMonitor\" module before app is ready")));
|
||||
"Cannot initialize \"power-monitor\" module before app is ready")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
@@ -76,11 +54,6 @@ v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
void PowerMonitor::BuildPrototype(
|
||||
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "PowerMonitor"));
|
||||
#if defined(OS_LINUX)
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("blockShutdown", &PowerMonitor::BlockShutdown)
|
||||
.SetMethod("unblockShutdown", &PowerMonitor::UnblockShutdown);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
@@ -94,6 +67,10 @@ using atom::api::PowerMonitor;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context, void* priv) {
|
||||
#if defined(OS_MACOSX)
|
||||
base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
|
||||
#endif
|
||||
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/lib/power_observer.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/power_monitor/power_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -15,7 +15,7 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
||||
public PowerObserver {
|
||||
public base::PowerObserver {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
@@ -26,15 +26,6 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
||||
explicit PowerMonitor(v8::Isolate* isolate);
|
||||
~PowerMonitor() override;
|
||||
|
||||
// Called by native calles.
|
||||
bool ShouldShutdown();
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// Private JS APIs.
|
||||
void BlockShutdown();
|
||||
void UnblockShutdown();
|
||||
#endif
|
||||
|
||||
// base::PowerObserver implementations:
|
||||
void OnPowerStateChange(bool on_battery_power) override;
|
||||
void OnSuspend() override;
|
||||
|
||||
@@ -6,21 +6,18 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
#include "content/public/browser/power_save_blocker.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<device::PowerSaveBlocker::PowerSaveBlockerType> {
|
||||
struct Converter<content::PowerSaveBlocker::PowerSaveBlockerType> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
device::PowerSaveBlocker::PowerSaveBlockerType* out) {
|
||||
using device::PowerSaveBlocker;
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType* out) {
|
||||
using content::PowerSaveBlocker;
|
||||
std::string type;
|
||||
if (!ConvertFromV8(isolate, val, &type))
|
||||
return false;
|
||||
@@ -42,7 +39,7 @@ namespace api {
|
||||
|
||||
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
|
||||
: current_blocker_type_(
|
||||
device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
@@ -61,32 +58,30 @@ void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||
// higher precedence level than |kPowerSaveBlockPreventAppSuspension|.
|
||||
//
|
||||
// Only the highest-precedence blocker type takes effect.
|
||||
device::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
|
||||
device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
|
||||
for (const auto& element : power_save_blocker_types_) {
|
||||
if (element.second ==
|
||||
device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
|
||||
new_blocker_type =
|
||||
device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
|
||||
std::unique_ptr<device::PowerSaveBlocker> new_blocker(
|
||||
new device::PowerSaveBlocker(
|
||||
std::unique_ptr<content::PowerSaveBlocker> new_blocker =
|
||||
content::PowerSaveBlocker::Create(
|
||||
new_blocker_type,
|
||||
device::PowerSaveBlocker::kReasonOther,
|
||||
ATOM_PRODUCT_NAME,
|
||||
BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
|
||||
BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)));
|
||||
content::PowerSaveBlocker::kReasonOther,
|
||||
ATOM_PRODUCT_NAME);
|
||||
power_save_blocker_.swap(new_blocker);
|
||||
current_blocker_type_ = new_blocker_type;
|
||||
}
|
||||
}
|
||||
|
||||
int PowerSaveBlocker::Start(
|
||||
device::PowerSaveBlocker::PowerSaveBlockerType type) {
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType type) {
|
||||
static int count = 0;
|
||||
power_save_blocker_types_[count] = type;
|
||||
UpdatePowerSaveBlocker();
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "content/public/browser/power_save_blocker.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "services/device/wake_lock/power_save_blocker/power_save_blocker.h"
|
||||
|
||||
namespace mate {
|
||||
class Dictionary;
|
||||
@@ -33,18 +33,18 @@ class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
|
||||
|
||||
private:
|
||||
void UpdatePowerSaveBlocker();
|
||||
int Start(device::PowerSaveBlocker::PowerSaveBlockerType type);
|
||||
int Start(content::PowerSaveBlocker::PowerSaveBlockerType type);
|
||||
bool Stop(int id);
|
||||
bool IsStarted(int id);
|
||||
|
||||
std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_;
|
||||
std::unique_ptr<content::PowerSaveBlocker> power_save_blocker_;
|
||||
|
||||
// Currnet blocker type used by |power_save_blocker_|
|
||||
device::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_;
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_;
|
||||
|
||||
// Map from id to the corresponding blocker type for each request.
|
||||
using PowerSaveBlockerTypeMap =
|
||||
std::map<int, device::PowerSaveBlocker::PowerSaveBlockerType>;
|
||||
std::map<int, content::PowerSaveBlocker::PowerSaveBlockerType>;
|
||||
PowerSaveBlockerTypeMap power_save_blocker_types_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "atom/browser/net/url_request_async_asar_job.h"
|
||||
#include "atom/browser/net/url_request_buffer_job.h"
|
||||
#include "atom/browser/net/url_request_fetch_job.h"
|
||||
#include "atom/browser/net/url_request_stream_job.h"
|
||||
#include "atom/browser/net/url_request_string_job.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
@@ -47,32 +46,17 @@ std::vector<std::string> GetStandardSchemes() {
|
||||
return g_standard_schemes;
|
||||
}
|
||||
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args) {
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes) {
|
||||
g_standard_schemes = schemes;
|
||||
|
||||
mate::Dictionary opts;
|
||||
bool secure = false;
|
||||
args->GetNext(&opts) && opts.Get("secure", &secure);
|
||||
|
||||
// Dynamically register the schemes.
|
||||
auto* policy = content::ChildProcessSecurityPolicy::GetInstance();
|
||||
for (const std::string& scheme : schemes) {
|
||||
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
|
||||
if (secure) {
|
||||
url::AddSecureScheme(scheme.c_str());
|
||||
}
|
||||
policy->RegisterWebSafeScheme(scheme);
|
||||
}
|
||||
|
||||
// Add the schemes to command line switches, so child processes can also
|
||||
// register them.
|
||||
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||
atom::switches::kStandardSchemes, base::JoinString(schemes, ","));
|
||||
if (secure) {
|
||||
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||
atom::switches::kSecureSchemes, base::JoinString(schemes, ","));
|
||||
}
|
||||
}
|
||||
|
||||
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
@@ -209,8 +193,6 @@ void Protocol::BuildPrototype(
|
||||
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("registerHttpProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("registerStreamProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStreamJob>)
|
||||
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
|
||||
.SetMethod("interceptStringProtocol",
|
||||
@@ -221,8 +203,6 @@ void Protocol::BuildPrototype(
|
||||
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("interceptHttpProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("interceptStreamProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestStreamJob>)
|
||||
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
}
|
||||
|
||||
@@ -240,7 +220,7 @@ void RegisterStandardSchemes(
|
||||
return;
|
||||
}
|
||||
|
||||
atom::api::RegisterStandardSchemes(schemes, args);
|
||||
atom::api::RegisterStandardSchemes(schemes);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
|
||||
@@ -29,8 +29,7 @@ namespace atom {
|
||||
namespace api {
|
||||
|
||||
std::vector<std::string> GetStandardSchemes();
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args);
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
class Protocol : public mate::TrackableObject<Protocol> {
|
||||
public:
|
||||
|
||||
@@ -7,12 +7,11 @@
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -97,7 +97,7 @@ v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate,
|
||||
"Cannot require \"screen\" module before app is ready")));
|
||||
"Cannot initialize \"screen\" module before app is ready")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
@@ -120,9 +120,6 @@ void Screen::BuildPrototype(
|
||||
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
|
||||
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
|
||||
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("getMenuBarHeight", &Screen::getMenuBarHeight)
|
||||
#endif
|
||||
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,10 +40,6 @@ class Screen : public mate::EventEmitter<Screen>,
|
||||
display::Display GetDisplayNearestPoint(const gfx::Point& point);
|
||||
display::Display GetDisplayMatching(const gfx::Rect& match_rect);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
int getMenuBarHeight();
|
||||
#endif
|
||||
|
||||
// display::DisplayObserver:
|
||||
void OnDisplayAdded(const display::Display& new_display) override;
|
||||
void OnDisplayRemoved(const display::Display& old_display) override;
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "atom/browser/api/atom_api_screen.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
int Screen::getMenuBarHeight() {
|
||||
return [[NSApp mainMenu] menuBarHeight];
|
||||
}
|
||||
|
||||
}// namespace api
|
||||
|
||||
}// namespace atom
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
#include "atom/browser/session_preferences.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/content_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
@@ -30,14 +29,11 @@
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "brightray/browser/media/media_device_id_salt.h"
|
||||
#include "brightray/browser/net/devtools_network_conditions.h"
|
||||
#include "brightray/browser/net/devtools_network_controller_handle.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/download_manager_delegate.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
@@ -53,7 +49,6 @@
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
using atom::api::Cookies;
|
||||
using content::BrowserThread;
|
||||
using content::StoragePartition;
|
||||
|
||||
@@ -65,15 +60,6 @@ struct ClearStorageDataOptions {
|
||||
uint32_t quota_types = StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL;
|
||||
};
|
||||
|
||||
struct ClearAuthCacheOptions {
|
||||
std::string type;
|
||||
GURL origin;
|
||||
std::string realm;
|
||||
base::string16 username;
|
||||
base::string16 password;
|
||||
net::HttpAuth::Scheme auth_scheme;
|
||||
};
|
||||
|
||||
uint32_t GetStorageMask(const std::vector<std::string>& storage_types) {
|
||||
uint32_t storage_mask = 0;
|
||||
for (const auto& it : storage_types) {
|
||||
@@ -112,18 +98,6 @@ uint32_t GetQuotaMask(const std::vector<std::string>& quota_types) {
|
||||
return quota_mask;
|
||||
}
|
||||
|
||||
net::HttpAuth::Scheme GetAuthSchemeFromString(const std::string& scheme) {
|
||||
if (scheme == "basic")
|
||||
return net::HttpAuth::AUTH_SCHEME_BASIC;
|
||||
if (scheme == "digest")
|
||||
return net::HttpAuth::AUTH_SCHEME_DIGEST;
|
||||
if (scheme == "ntlm")
|
||||
return net::HttpAuth::AUTH_SCHEME_NTLM;
|
||||
if (scheme == "negotiate")
|
||||
return net::HttpAuth::AUTH_SCHEME_NEGOTIATE;
|
||||
return net::HttpAuth::AUTH_SCHEME_MAX;
|
||||
}
|
||||
|
||||
void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const std::string& accept_lang,
|
||||
const std::string& user_agent) {
|
||||
@@ -155,27 +129,7 @@ struct Converter<ClearStorageDataOptions> {
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<ClearAuthCacheOptions> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
ClearAuthCacheOptions* out) {
|
||||
mate::Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
options.Get("type", &out->type);
|
||||
options.Get("origin", &out->origin);
|
||||
options.Get("realm", &out->realm);
|
||||
options.Get("username", &out->username);
|
||||
options.Get("password", &out->password);
|
||||
std::string scheme;
|
||||
if (options.Get("scheme", &scheme))
|
||||
out->auth_scheme = GetAuthSchemeFromString(scheme);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
template<>
|
||||
struct Converter<net::ProxyConfig> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
@@ -206,19 +160,6 @@ struct Converter<net::ProxyConfig> {
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<atom::VerifyRequestParams> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
atom::VerifyRequestParams val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("hostname", val.hostname);
|
||||
dict.Set("certificate", val.certificate);
|
||||
dict.Set("verificationResult", val.default_result);
|
||||
dict.Set("errorCode", val.error_code);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
@@ -236,7 +177,7 @@ class ResolveProxyHelper {
|
||||
public:
|
||||
ResolveProxyHelper(AtomBrowserContext* browser_context,
|
||||
const GURL& url,
|
||||
const Session::ResolveProxyCallback& callback)
|
||||
Session::ResolveProxyCallback callback)
|
||||
: callback_(callback),
|
||||
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
|
||||
scoped_refptr<net::URLRequestContextGetter> context_getter =
|
||||
@@ -269,8 +210,8 @@ class ResolveProxyHelper {
|
||||
|
||||
// Start the request.
|
||||
int result = proxy_service->ResolveProxy(
|
||||
url, "GET", &proxy_info_, completion_callback, &pac_req_, nullptr,
|
||||
net::NetLogWithSource());
|
||||
url, "GET", net::LOAD_NORMAL, &proxy_info_, completion_callback,
|
||||
&pac_req_, nullptr, net::BoundNetLog());
|
||||
|
||||
// Completed synchronously.
|
||||
if (result != net::ERR_IO_PENDING)
|
||||
@@ -286,9 +227,6 @@ class ResolveProxyHelper {
|
||||
};
|
||||
|
||||
// Runs the callback in UI thread.
|
||||
void RunCallbackInUI(const base::Callback<void()>& callback) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
|
||||
}
|
||||
template<typename ...T>
|
||||
void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
|
||||
BrowserThread::PostTask(
|
||||
@@ -374,33 +312,6 @@ void ClearHostResolverCacheInIO(
|
||||
}
|
||||
}
|
||||
|
||||
void ClearAuthCacheInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const ClearAuthCacheOptions& options,
|
||||
const base::Closure& callback) {
|
||||
auto request_context = context_getter->GetURLRequestContext();
|
||||
auto network_session =
|
||||
request_context->http_transaction_factory()->GetSession();
|
||||
if (network_session) {
|
||||
if (options.type == "password") {
|
||||
auto auth_cache = network_session->http_auth_cache();
|
||||
if (!options.origin.is_empty()) {
|
||||
auth_cache->Remove(
|
||||
options.origin, options.realm, options.auth_scheme,
|
||||
net::AuthCredentials(options.username, options.password));
|
||||
} else {
|
||||
auth_cache->ClearEntriesAddedWithin(base::TimeDelta::Max());
|
||||
}
|
||||
} else if (options.type == "clientCertificate") {
|
||||
auto client_auth_cache = network_session->ssl_client_auth_cache();
|
||||
client_auth_cache->Remove(net::HostPortPair::FromURL(options.origin));
|
||||
}
|
||||
network_session->CloseAllConnections();
|
||||
}
|
||||
if (!callback.is_null())
|
||||
RunCallbackInUI(callback);
|
||||
}
|
||||
|
||||
void AllowNTLMCredentialsForDomainsInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const std::string& domains) {
|
||||
@@ -419,50 +330,15 @@ void OnClearStorageDataDone(const base::Closure& callback) {
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
void DownloadIdCallback(content::DownloadManager* download_manager,
|
||||
const base::FilePath& path,
|
||||
const std::vector<GURL>& url_chain,
|
||||
const std::string& mime_type,
|
||||
int64_t offset,
|
||||
int64_t length,
|
||||
const std::string& last_modified,
|
||||
const std::string& etag,
|
||||
const base::Time& start_time,
|
||||
uint32_t id) {
|
||||
download_manager->CreateDownloadItem(
|
||||
base::GenerateGUID(), id, path, path, url_chain, GURL(), GURL(), GURL(),
|
||||
GURL(), mime_type, mime_type, start_time, base::Time(), etag,
|
||||
last_modified, offset, length, std::string(),
|
||||
content::DownloadItem::INTERRUPTED,
|
||||
content::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false,
|
||||
base::Time(), false,
|
||||
std::vector<content::DownloadItem::ReceivedSlice>());
|
||||
}
|
||||
|
||||
void SetDevToolsNetworkEmulationClientIdInIO(
|
||||
brightray::URLRequestContextGetter* url_request_context_getter,
|
||||
const std::string& client_id) {
|
||||
if (!url_request_context_getter)
|
||||
return;
|
||||
net::URLRequestContext* context =
|
||||
url_request_context_getter->GetURLRequestContext();
|
||||
AtomNetworkDelegate* network_delegate =
|
||||
static_cast<AtomNetworkDelegate*>(context->network_delegate());
|
||||
network_delegate->SetDevToolsNetworkEmulationClientId(client_id);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: devtools_network_emulation_client_id_(base::GenerateGUID()),
|
||||
browser_context_(browser_context) {
|
||||
// Observe DownloadManager to get download notifications.
|
||||
// Observe DownloadManger to get download notifications.
|
||||
content::BrowserContext::GetDownloadManager(browser_context)->
|
||||
AddObserver(this);
|
||||
|
||||
new SessionPreferences(browser_context);
|
||||
|
||||
Init(isolate);
|
||||
AttachAsUserData(browser_context);
|
||||
}
|
||||
@@ -480,10 +356,10 @@ void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto handle = DownloadItem::Create(isolate(), item);
|
||||
if (item->GetState() == content::DownloadItem::INTERRUPTED)
|
||||
handle->SetSavePath(item->GetTargetFilePath());
|
||||
bool prevent_default = Emit("will-download", handle, item->GetWebContents());
|
||||
bool prevent_default = Emit(
|
||||
"will-download",
|
||||
DownloadItem::Create(isolate(), item),
|
||||
item->GetWebContents());
|
||||
if (prevent_default) {
|
||||
item->Cancel(true);
|
||||
item->Remove();
|
||||
@@ -512,11 +388,6 @@ void Session::ClearStorageData(mate::Arguments* args) {
|
||||
|
||||
auto storage_partition =
|
||||
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
||||
if (options.storage_types & StoragePartition::REMOVE_DATA_MASK_COOKIES) {
|
||||
// Reset media device id salt when cookies are cleared.
|
||||
// https://w3c.github.io/mediacapture-main/#dom-mediadeviceinfo-deviceid
|
||||
brightray::MediaDeviceIDSalt::Reset(browser_context()->prefs());
|
||||
}
|
||||
storage_partition->ClearData(
|
||||
options.storage_types, options.quota_types, options.origin,
|
||||
content::StoragePartition::OriginMatcherFunction(),
|
||||
@@ -561,24 +432,16 @@ void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
|
||||
|
||||
browser_context_->network_controller_handle()->SetNetworkState(
|
||||
devtools_network_emulation_client_id_, std::move(conditions));
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(
|
||||
&SetDevToolsNetworkEmulationClientIdInIO,
|
||||
base::RetainedRef(browser_context_->url_request_context_getter()),
|
||||
devtools_network_emulation_client_id_));
|
||||
browser_context_->network_delegate()->SetDevToolsNetworkEmulationClientId(
|
||||
devtools_network_emulation_client_id_);
|
||||
}
|
||||
|
||||
void Session::DisableNetworkEmulation() {
|
||||
std::unique_ptr<brightray::DevToolsNetworkConditions> conditions;
|
||||
browser_context_->network_controller_handle()->SetNetworkState(
|
||||
devtools_network_emulation_client_id_, std::move(conditions));
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(
|
||||
&SetDevToolsNetworkEmulationClientIdInIO,
|
||||
base::RetainedRef(browser_context_->url_request_context_getter()),
|
||||
std::string()));
|
||||
browser_context_->network_delegate()->SetDevToolsNetworkEmulationClientId(
|
||||
std::string());
|
||||
}
|
||||
|
||||
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
@@ -617,22 +480,6 @@ void Session::ClearHostResolverCache(mate::Arguments* args) {
|
||||
callback));
|
||||
}
|
||||
|
||||
void Session::ClearAuthCache(mate::Arguments* args) {
|
||||
ClearAuthCacheOptions options;
|
||||
if (!args->GetNext(&options)) {
|
||||
args->ThrowError("Must specify options object");
|
||||
return;
|
||||
}
|
||||
base::Closure callback;
|
||||
args->GetNext(&callback);
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&ClearAuthCacheInIO,
|
||||
make_scoped_refptr(browser_context_->GetRequestContext()),
|
||||
options, callback));
|
||||
}
|
||||
|
||||
void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&AllowNTLMCredentialsForDomainsInIO,
|
||||
@@ -644,11 +491,10 @@ void Session::SetUserAgent(const std::string& user_agent,
|
||||
mate::Arguments* args) {
|
||||
browser_context_->SetUserAgent(user_agent);
|
||||
|
||||
std::string accept_lang = g_browser_process->GetApplicationLocale();
|
||||
std::string accept_lang = l10n_util::GetApplicationLocale("");
|
||||
args->GetNext(&accept_lang);
|
||||
|
||||
scoped_refptr<brightray::URLRequestContextGetter> getter(
|
||||
browser_context_->GetRequestContext());
|
||||
auto getter = browser_context_->GetRequestContext();
|
||||
getter->GetNetworkTaskRunner()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&SetUserAgentInIO, getter, accept_lang, user_agent));
|
||||
@@ -658,68 +504,9 @@ std::string Session::GetUserAgent() {
|
||||
return browser_context_->GetUserAgent();
|
||||
}
|
||||
|
||||
void Session::GetBlobData(
|
||||
const std::string& uuid,
|
||||
const AtomBlobReader::CompletionCallback& callback) {
|
||||
if (callback.is_null())
|
||||
return;
|
||||
|
||||
AtomBlobReader* blob_reader =
|
||||
browser_context()->GetBlobReader();
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&AtomBlobReader::StartReading,
|
||||
base::Unretained(blob_reader),
|
||||
uuid,
|
||||
callback));
|
||||
}
|
||||
|
||||
void Session::CreateInterruptedDownload(const mate::Dictionary& options) {
|
||||
int64_t offset = 0, length = 0;
|
||||
double start_time = 0.0;
|
||||
std::string mime_type, last_modified, etag;
|
||||
base::FilePath path;
|
||||
std::vector<GURL> url_chain;
|
||||
options.Get("path", &path);
|
||||
options.Get("urlChain", &url_chain);
|
||||
options.Get("mimeType", &mime_type);
|
||||
options.Get("offset", &offset);
|
||||
options.Get("length", &length);
|
||||
options.Get("lastModified", &last_modified);
|
||||
options.Get("eTag", &etag);
|
||||
options.Get("startTime", &start_time);
|
||||
if (path.empty() || url_chain.empty() || length == 0) {
|
||||
isolate()->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate(), "Must pass non-empty path, urlChain and length.")));
|
||||
return;
|
||||
}
|
||||
if (offset >= length) {
|
||||
isolate()->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate(), "Must pass an offset value less than length.")));
|
||||
return;
|
||||
}
|
||||
auto download_manager =
|
||||
content::BrowserContext::GetDownloadManager(browser_context());
|
||||
download_manager->GetDelegate()->GetNextId(base::Bind(
|
||||
&DownloadIdCallback, download_manager, path, url_chain, mime_type, offset,
|
||||
length, last_modified, etag, base::Time::FromDoubleT(start_time)));
|
||||
}
|
||||
|
||||
void Session::SetPreloads(
|
||||
const std::vector<base::FilePath::StringType>& preloads) {
|
||||
auto* prefs = SessionPreferences::FromBrowserContext(browser_context());
|
||||
DCHECK(prefs);
|
||||
prefs->set_preloads(preloads);
|
||||
}
|
||||
|
||||
std::vector<base::FilePath::StringType> Session::GetPreloads() const {
|
||||
auto* prefs = SessionPreferences::FromBrowserContext(browser_context());
|
||||
DCHECK(prefs);
|
||||
return prefs->preloads();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
if (cookies_.IsEmpty()) {
|
||||
auto handle = Cookies::Create(isolate, browser_context());
|
||||
auto handle = atom::api::Cookies::Create(isolate, browser_context());
|
||||
cookies_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, cookies_);
|
||||
@@ -791,20 +578,14 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
|
||||
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
|
||||
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
|
||||
.SetMethod("_setCertificateVerifyProc", &Session::SetCertVerifyProc)
|
||||
.SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc)
|
||||
.SetMethod("setPermissionRequestHandler",
|
||||
&Session::SetPermissionRequestHandler)
|
||||
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
||||
.SetMethod("clearAuthCache", &Session::ClearAuthCache)
|
||||
.SetMethod("allowNTLMCredentialsForDomains",
|
||||
&Session::AllowNTLMCredentialsForDomains)
|
||||
.SetMethod("setUserAgent", &Session::SetUserAgent)
|
||||
.SetMethod("getUserAgent", &Session::GetUserAgent)
|
||||
.SetMethod("getBlobData", &Session::GetBlobData)
|
||||
.SetMethod("createInterruptedDownload",
|
||||
&Session::CreateInterruptedDownload)
|
||||
.SetMethod("setPreloads", &Session::SetPreloads)
|
||||
.SetMethod("getPreloads", &Session::GetPreloads)
|
||||
.SetProperty("cookies", &Session::Cookies)
|
||||
.SetProperty("protocol", &Session::Protocol)
|
||||
.SetProperty("webRequest", &Session::WebRequest);
|
||||
@@ -834,7 +615,6 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Session", Session::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set("Cookies", Cookies::GetConstructor(isolate)->GetFunction());
|
||||
dict.SetMethod("fromPartition", &FromPartition);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
#define ATOM_BROWSER_API_ATOM_API_SESSION_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "native_mate/handle.h"
|
||||
@@ -75,15 +73,9 @@ class Session: public mate::TrackableObject<Session>,
|
||||
void SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args);
|
||||
void ClearHostResolverCache(mate::Arguments* args);
|
||||
void ClearAuthCache(mate::Arguments* args);
|
||||
void AllowNTLMCredentialsForDomains(const std::string& domains);
|
||||
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
|
||||
std::string GetUserAgent();
|
||||
void GetBlobData(const std::string& uuid,
|
||||
const AtomBlobReader::CompletionCallback& callback);
|
||||
void CreateInterruptedDownload(const mate::Dictionary& options);
|
||||
void SetPreloads(const std::vector<base::FilePath::StringType>& preloads);
|
||||
std::vector<base::FilePath::StringType> GetPreloads() const;
|
||||
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/base/win/shell.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -16,27 +19,23 @@ namespace api {
|
||||
|
||||
SystemPreferences::SystemPreferences(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
#if defined(OS_WIN)
|
||||
InitializeWindow();
|
||||
#endif
|
||||
}
|
||||
|
||||
SystemPreferences::~SystemPreferences() {
|
||||
#if defined(OS_WIN)
|
||||
Browser::Get()->RemoveObserver(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool SystemPreferences::IsAeroGlassEnabled() {
|
||||
return ui::win::IsAeroGlassEnabled();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool SystemPreferences::IsInvertedColorScheme() {
|
||||
return color_utils::IsInvertedColorScheme();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<SystemPreferences> SystemPreferences::Create(
|
||||
v8::Isolate* isolate) {
|
||||
@@ -49,9 +48,7 @@ void SystemPreferences::BuildPrototype(
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "SystemPreferences"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("getAccentColor", &SystemPreferences::GetAccentColor)
|
||||
.SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled)
|
||||
.SetMethod("getColor", &SystemPreferences::GetColor)
|
||||
#elif defined(OS_MACOSX)
|
||||
.SetMethod("postNotification",
|
||||
&SystemPreferences::PostNotification)
|
||||
@@ -65,15 +62,10 @@ void SystemPreferences::BuildPrototype(
|
||||
&SystemPreferences::SubscribeLocalNotification)
|
||||
.SetMethod("unsubscribeLocalNotification",
|
||||
&SystemPreferences::UnsubscribeLocalNotification)
|
||||
.SetMethod("registerDefaults", &SystemPreferences::RegisterDefaults)
|
||||
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
|
||||
.SetMethod("setUserDefault", &SystemPreferences::SetUserDefault)
|
||||
.SetMethod("removeUserDefault", &SystemPreferences::RemoveUserDefault)
|
||||
.SetMethod("isSwipeTrackingFromScrollEventsEnabled",
|
||||
&SystemPreferences::IsSwipeTrackingFromScrollEventsEnabled)
|
||||
#endif
|
||||
.SetMethod("isInvertedColorScheme",
|
||||
&SystemPreferences::IsInvertedColorScheme)
|
||||
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,6 @@
|
||||
#include "base/values.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/browser_observer.h"
|
||||
#include "ui/gfx/sys_color_change_listener.h"
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
@@ -26,12 +20,7 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
#if defined(OS_WIN)
|
||||
, public BrowserObserver
|
||||
, public gfx::SysColorChangeListener
|
||||
#endif
|
||||
{
|
||||
class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
|
||||
public:
|
||||
static mate::Handle<SystemPreferences> Create(v8::Isolate* isolate);
|
||||
|
||||
@@ -40,23 +29,6 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
|
||||
typedef HRESULT (STDAPICALLTYPE *DwmGetColorizationColor)(DWORD *, BOOL *);
|
||||
DwmGetColorizationColor dwmGetColorizationColor =
|
||||
(DwmGetColorizationColor) GetProcAddress(LoadLibraryW(L"dwmapi.dll"),
|
||||
"DwmGetColorizationColor");
|
||||
|
||||
std::string GetAccentColor();
|
||||
std::string GetColor(const std::string& color, mate::Arguments* args);
|
||||
|
||||
void InitializeWindow();
|
||||
|
||||
// gfx::SysColorChangeListener:
|
||||
void OnSysColorChange() override;
|
||||
|
||||
// BrowserObserver:
|
||||
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
|
||||
|
||||
#elif defined(OS_MACOSX)
|
||||
using NotificationCallback = base::Callback<
|
||||
void(const std::string&, const base::DictionaryValue&)>;
|
||||
@@ -73,15 +45,9 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
void UnsubscribeLocalNotification(int request_id);
|
||||
v8::Local<v8::Value> GetUserDefault(const std::string& name,
|
||||
const std::string& type);
|
||||
void RegisterDefaults(mate::Arguments* args);
|
||||
void SetUserDefault(const std::string& name,
|
||||
const std::string& type,
|
||||
mate::Arguments* args);
|
||||
void RemoveUserDefault(const std::string& name);
|
||||
bool IsSwipeTrackingFromScrollEventsEnabled();
|
||||
#endif
|
||||
bool IsDarkMode();
|
||||
bool IsInvertedColorScheme();
|
||||
|
||||
protected:
|
||||
explicit SystemPreferences(v8::Isolate* isolate);
|
||||
@@ -98,29 +64,6 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if defined(OS_WIN)
|
||||
// Static callback invoked when a message comes in to our messaging window.
|
||||
static LRESULT CALLBACK
|
||||
WndProcStatic(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
LRESULT CALLBACK
|
||||
WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
// The window class of |window_|.
|
||||
ATOM atom_;
|
||||
|
||||
// The handle of the module that contains the window procedure of |window_|.
|
||||
HMODULE instance_;
|
||||
|
||||
// The window used for processing events.
|
||||
HWND window_;
|
||||
|
||||
std::string current_color_;
|
||||
|
||||
bool invertered_color_scheme_;
|
||||
|
||||
std::unique_ptr<gfx::ScopedSysColorChangeListener> color_change_listener_;
|
||||
#endif
|
||||
DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
|
||||
};
|
||||
|
||||
|
||||
@@ -28,17 +28,17 @@ std::map<int, id> g_id_map;
|
||||
|
||||
} // namespace
|
||||
|
||||
void SystemPreferences::PostNotification(const std::string& name,
|
||||
void SystemPreferences::PostNotification(const std::string& name,
|
||||
const base::DictionaryValue& user_info) {
|
||||
DoPostNotification(name, user_info, false);
|
||||
}
|
||||
|
||||
void SystemPreferences::PostLocalNotification(const std::string& name,
|
||||
void SystemPreferences::PostLocalNotification(const std::string& name,
|
||||
const base::DictionaryValue& user_info) {
|
||||
DoPostNotification(name, user_info, true);
|
||||
}
|
||||
|
||||
void SystemPreferences::DoPostNotification(const std::string& name,
|
||||
void SystemPreferences::DoPostNotification(const std::string& name,
|
||||
const base::DictionaryValue& user_info, bool is_local) {
|
||||
NSNotificationCenter* center = is_local ?
|
||||
[NSNotificationCenter defaultCenter] :
|
||||
@@ -128,134 +128,16 @@ v8::Local<v8::Value> SystemPreferences::GetUserDefault(
|
||||
return mate::ConvertToV8(isolate(),
|
||||
net::GURLWithNSURL([defaults URLForKey:key]));
|
||||
} else if (type == "array") {
|
||||
std::unique_ptr<base::ListValue> list =
|
||||
NSArrayToListValue([defaults arrayForKey:key]);
|
||||
if (list == nullptr)
|
||||
list.reset(new base::ListValue());
|
||||
return mate::ConvertToV8(isolate(), *list);
|
||||
return mate::ConvertToV8(isolate(),
|
||||
*NSArrayToListValue([defaults arrayForKey:key]));
|
||||
} else if (type == "dictionary") {
|
||||
std::unique_ptr<base::DictionaryValue> dictionary =
|
||||
NSDictionaryToDictionaryValue([defaults dictionaryForKey:key]);
|
||||
if (dictionary == nullptr)
|
||||
dictionary.reset(new base::DictionaryValue());
|
||||
return mate::ConvertToV8(isolate(), *dictionary);
|
||||
return mate::ConvertToV8(isolate(),
|
||||
*NSDictionaryToDictionaryValue([defaults dictionaryForKey:key]));
|
||||
} else {
|
||||
return v8::Undefined(isolate());
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPreferences::RegisterDefaults(mate::Arguments* args) {
|
||||
base::DictionaryValue value;
|
||||
|
||||
if(!args->GetNext(&value)) {
|
||||
args->ThrowError("Invalid userDefault data provided");
|
||||
} else {
|
||||
@try {
|
||||
NSDictionary* dict = DictionaryValueToNSDictionary(value);
|
||||
for (id key in dict) {
|
||||
id value = [dict objectForKey:key];
|
||||
if ([value isKindOfClass:[NSNull class]] || value == nil) {
|
||||
args->ThrowError("Invalid userDefault data provided");
|
||||
return;
|
||||
}
|
||||
}
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
|
||||
} @catch (NSException* exception) {
|
||||
args->ThrowError("Invalid userDefault data provided");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPreferences::SetUserDefault(const std::string& name,
|
||||
const std::string& type,
|
||||
mate::Arguments* args) {
|
||||
const auto throwConversionError = [&] {
|
||||
args->ThrowError("Unable to convert value to: " + type);
|
||||
};
|
||||
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString* key = base::SysUTF8ToNSString(name);
|
||||
if (type == "string") {
|
||||
std::string value;
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
[defaults setObject:base::SysUTF8ToNSString(value) forKey:key];
|
||||
} else if (type == "boolean") {
|
||||
bool value;
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
[defaults setBool:value forKey:key];
|
||||
} else if (type == "float") {
|
||||
float value;
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
[defaults setFloat:value forKey:key];
|
||||
} else if (type == "integer") {
|
||||
int value;
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
[defaults setInteger:value forKey:key];
|
||||
} else if (type == "double") {
|
||||
double value;
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
[defaults setDouble:value forKey:key];
|
||||
} else if (type == "url") {
|
||||
GURL value;
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (NSURL* url = net::NSURLWithGURL(value)) {
|
||||
[defaults setURL:url forKey:key];
|
||||
}
|
||||
} else if (type == "array") {
|
||||
base::ListValue value;
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (NSArray* array = ListValueToNSArray(value)) {
|
||||
[defaults setObject:array forKey:key];
|
||||
}
|
||||
} else if (type == "dictionary") {
|
||||
base::DictionaryValue value;
|
||||
if (!args->GetNext(&value)) {
|
||||
throwConversionError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (NSDictionary* dict = DictionaryValueToNSDictionary(value)) {
|
||||
[defaults setObject:dict forKey:key];
|
||||
}
|
||||
} else {
|
||||
args->ThrowError("Invalid type: " + type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SystemPreferences::RemoveUserDefault(const std::string& name) {
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults removeObjectForKey:base::SysUTF8ToNSString(name)];
|
||||
}
|
||||
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
NSString* mode = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:@"AppleInterfaceStyle"];
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#include "atom/browser/api/atom_api_system_preferences.h"
|
||||
|
||||
#include "atom/common/color_util.h"
|
||||
#include "base/win/wrapped_window_proc.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
#include "ui/gfx/win/hwnd_util.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const wchar_t kSystemPreferencesWindowClass[] =
|
||||
L"Electron_SystemPreferencesHostWindow";
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace api {
|
||||
|
||||
bool SystemPreferences::IsAeroGlassEnabled() {
|
||||
return ui::win::IsAeroGlassEnabled();
|
||||
}
|
||||
|
||||
std::string hexColorDWORDToRGBA(DWORD color) {
|
||||
DWORD rgba = color << 8 | color >> 24;
|
||||
std::ostringstream stream;
|
||||
stream << std::hex << std::setw(8) << std::setfill('0') << rgba;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetAccentColor() {
|
||||
DWORD color = 0;
|
||||
BOOL opaque = FALSE;
|
||||
|
||||
if (FAILED(dwmGetColorizationColor(&color, &opaque))) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return hexColorDWORDToRGBA(color);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetColor(const std::string& color,
|
||||
mate::Arguments* args) {
|
||||
int id;
|
||||
if (color == "3d-dark-shadow") {
|
||||
id = COLOR_3DDKSHADOW;
|
||||
} else if (color == "3d-face") {
|
||||
id = COLOR_3DFACE;
|
||||
} else if (color == "3d-highlight") {
|
||||
id = COLOR_3DHIGHLIGHT;
|
||||
} else if (color == "3d-light") {
|
||||
id = COLOR_3DLIGHT;
|
||||
} else if (color == "3d-shadow") {
|
||||
id = COLOR_3DSHADOW;
|
||||
} else if (color == "active-border") {
|
||||
id = COLOR_ACTIVEBORDER;
|
||||
} else if (color == "active-caption") {
|
||||
id = COLOR_ACTIVECAPTION;
|
||||
} else if (color == "active-caption-gradient") {
|
||||
id = COLOR_GRADIENTACTIVECAPTION;
|
||||
} else if (color == "app-workspace") {
|
||||
id = COLOR_APPWORKSPACE;
|
||||
} else if (color == "button-text") {
|
||||
id = COLOR_BTNTEXT;
|
||||
} else if (color == "caption-text") {
|
||||
id = COLOR_CAPTIONTEXT;
|
||||
} else if (color == "desktop") {
|
||||
id = COLOR_DESKTOP;
|
||||
} else if (color == "disabled-text") {
|
||||
id = COLOR_GRAYTEXT;
|
||||
} else if (color == "highlight") {
|
||||
id = COLOR_HIGHLIGHT;
|
||||
} else if (color == "highlight-text") {
|
||||
id = COLOR_HIGHLIGHTTEXT;
|
||||
} else if (color == "hotlight") {
|
||||
id = COLOR_HOTLIGHT;
|
||||
} else if (color == "inactive-border") {
|
||||
id = COLOR_INACTIVEBORDER;
|
||||
} else if (color == "inactive-caption") {
|
||||
id = COLOR_INACTIVECAPTION;
|
||||
} else if (color == "inactive-caption-gradient") {
|
||||
id = COLOR_GRADIENTINACTIVECAPTION;
|
||||
} else if (color == "inactive-caption-text") {
|
||||
id = COLOR_INACTIVECAPTIONTEXT;
|
||||
} else if (color == "info-background") {
|
||||
id = COLOR_INFOBK;
|
||||
} else if (color == "info-text") {
|
||||
id = COLOR_INFOTEXT;
|
||||
} else if (color == "menu") {
|
||||
id = COLOR_MENU;
|
||||
} else if (color == "menu-highlight") {
|
||||
id = COLOR_MENUHILIGHT;
|
||||
} else if (color == "menubar") {
|
||||
id = COLOR_MENUBAR;
|
||||
} else if (color == "menu-text") {
|
||||
id = COLOR_MENUTEXT;
|
||||
} else if (color == "scrollbar") {
|
||||
id = COLOR_SCROLLBAR;
|
||||
} else if (color == "window") {
|
||||
id = COLOR_WINDOW;
|
||||
} else if (color == "window-frame") {
|
||||
id = COLOR_WINDOWFRAME;
|
||||
} else if (color == "window-text") {
|
||||
id = COLOR_WINDOWTEXT;
|
||||
} else {
|
||||
args->ThrowError("Unknown color: " + color);
|
||||
return "";
|
||||
}
|
||||
|
||||
return ToRGBHex(color_utils::GetSysSkColor(id));
|
||||
}
|
||||
|
||||
void SystemPreferences::InitializeWindow() {
|
||||
invertered_color_scheme_ = IsInvertedColorScheme();
|
||||
|
||||
// Wait until app is ready before creating sys color listener
|
||||
// Creating this listener before the app is ready causes global shortcuts
|
||||
// to not fire
|
||||
if (Browser::Get()->is_ready())
|
||||
color_change_listener_.reset(new gfx::ScopedSysColorChangeListener(this));
|
||||
else
|
||||
Browser::Get()->AddObserver(this);
|
||||
|
||||
WNDCLASSEX window_class;
|
||||
base::win::InitializeWindowClass(
|
||||
kSystemPreferencesWindowClass,
|
||||
&base::win::WrappedWindowProc<SystemPreferences::WndProcStatic>,
|
||||
0, 0, 0, NULL, NULL, NULL, NULL, NULL,
|
||||
&window_class);
|
||||
instance_ = window_class.hInstance;
|
||||
atom_ = RegisterClassEx(&window_class);
|
||||
|
||||
// Create an offscreen window for receiving broadcast messages for the system
|
||||
// colorization color. Create a hidden WS_POPUP window instead of an
|
||||
// HWND_MESSAGE window, because only top-level windows such as popups can
|
||||
// receive broadcast messages like "WM_DWMCOLORIZATIONCOLORCHANGED".
|
||||
window_ = CreateWindow(MAKEINTATOM(atom_),
|
||||
0, WS_POPUP, 0, 0, 0, 0, 0, 0, instance_, 0);
|
||||
gfx::CheckWindowCreated(window_);
|
||||
gfx::SetWindowUserData(window_, this);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK SystemPreferences::WndProcStatic(HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
SystemPreferences* msg_wnd = reinterpret_cast<SystemPreferences*>(
|
||||
GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
||||
if (msg_wnd)
|
||||
return msg_wnd->WndProc(hwnd, message, wparam, lparam);
|
||||
else
|
||||
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK SystemPreferences::WndProc(HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
if (message == WM_DWMCOLORIZATIONCOLORCHANGED) {
|
||||
DWORD new_color = (DWORD) wparam;
|
||||
std::string new_color_string = hexColorDWORDToRGBA(new_color);
|
||||
if (new_color_string != current_color_) {
|
||||
Emit("accent-color-changed", hexColorDWORDToRGBA(new_color));
|
||||
current_color_ = new_color_string;
|
||||
}
|
||||
}
|
||||
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
void SystemPreferences::OnSysColorChange() {
|
||||
bool new_invertered_color_scheme = IsInvertedColorScheme();
|
||||
if (new_invertered_color_scheme != invertered_color_scheme_) {
|
||||
invertered_color_scheme_ = new_invertered_color_scheme;
|
||||
Emit("inverted-color-scheme-changed", new_invertered_color_scheme);
|
||||
}
|
||||
Emit("color-changed");
|
||||
}
|
||||
|
||||
void SystemPreferences::OnFinishLaunching(
|
||||
const base::DictionaryValue& launch_info) {
|
||||
color_change_listener_.reset(new gfx::ScopedSysColorChangeListener(this));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
@@ -40,6 +39,8 @@ struct Converter<atom::TrayIcon::HighlightMode> {
|
||||
}
|
||||
}
|
||||
|
||||
// Support old boolean parameter
|
||||
// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
|
||||
bool highlight;
|
||||
if (ConvertFromV8(isolate, val, &highlight)) {
|
||||
if (highlight)
|
||||
@@ -70,8 +71,7 @@ Tray::Tray(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
|
||||
|
||||
Tray::~Tray() {
|
||||
// Destroy the native tray in next tick.
|
||||
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(
|
||||
FROM_HERE, tray_icon_.release());
|
||||
base::MessageLoop::current()->DeleteSoon(FROM_HERE, tray_icon_.release());
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -84,10 +84,8 @@ mate::WrappableBase* Tray::New(mate::Handle<NativeImage> image,
|
||||
return new Tray(args->isolate(), args->GetThis(), image);
|
||||
}
|
||||
|
||||
void Tray::OnClicked(const gfx::Rect& bounds,
|
||||
const gfx::Point& location,
|
||||
int modifiers) {
|
||||
EmitWithFlags("click", modifiers, bounds, location);
|
||||
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
EmitWithFlags("click", modifiers, bounds);
|
||||
}
|
||||
|
||||
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
@@ -122,18 +120,6 @@ void Tray::OnDropText(const std::string& text) {
|
||||
Emit("drop-text", text);
|
||||
}
|
||||
|
||||
void Tray::OnMouseEntered(const gfx::Point& location, int modifiers) {
|
||||
EmitWithFlags("mouse-enter", modifiers, location);
|
||||
}
|
||||
|
||||
void Tray::OnMouseExited(const gfx::Point& location, int modifiers) {
|
||||
EmitWithFlags("mouse-leave", modifiers, location);
|
||||
}
|
||||
|
||||
void Tray::OnMouseMoved(const gfx::Point& location, int modifiers) {
|
||||
EmitWithFlags("mouse-move", modifiers, location);
|
||||
}
|
||||
|
||||
void Tray::OnDragEntered() {
|
||||
Emit("drag-enter");
|
||||
}
|
||||
|
||||
@@ -47,9 +47,7 @@ class Tray : public mate::TrackableObject<Tray>,
|
||||
~Tray() override;
|
||||
|
||||
// TrayIconObserver:
|
||||
void OnClicked(const gfx::Rect& bounds,
|
||||
const gfx::Point& location,
|
||||
int modifiers) override;
|
||||
void OnClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnRightClicked(const gfx::Rect& bounds, int modifiers) override;
|
||||
void OnBalloonShow() override;
|
||||
@@ -61,9 +59,6 @@ class Tray : public mate::TrackableObject<Tray>,
|
||||
void OnDragEntered() override;
|
||||
void OnDragExited() override;
|
||||
void OnDragEnded() override;
|
||||
void OnMouseEntered(const gfx::Point& location, int modifiers) override;
|
||||
void OnMouseExited(const gfx::Point& location, int modifiers) override;
|
||||
void OnMouseMoved(const gfx::Point& location, int modifiers) override;
|
||||
|
||||
void SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
void SetPressedImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
|
||||
|
||||
@@ -1,481 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_url_request.h"
|
||||
#include <string>
|
||||
#include "atom/browser/api/atom_api_session.h"
|
||||
#include "atom/browser/net/atom_url_request.h"
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<scoped_refptr<const net::IOBufferWithSize>> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
scoped_refptr<const net::IOBufferWithSize> buffer) {
|
||||
return node::Buffer::Copy(isolate, buffer->data(), buffer->size())
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
scoped_refptr<const net::IOBufferWithSize>* out) {
|
||||
auto size = node::Buffer::Length(val);
|
||||
|
||||
if (size == 0) {
|
||||
// Support conversion from empty buffer. A use case is
|
||||
// a GET request without body.
|
||||
// Since zero-sized IOBuffer(s) are not supported, we set the
|
||||
// out pointer to null.
|
||||
*out = nullptr;
|
||||
return true;
|
||||
}
|
||||
auto data = node::Buffer::Data(val);
|
||||
if (!data) {
|
||||
// This is an error as size is positive but data is null.
|
||||
return false;
|
||||
}
|
||||
|
||||
*out = new net::IOBufferWithSize(size);
|
||||
// We do a deep copy. We could have used Buffer's internal memory
|
||||
// but that is much more complicated to be properly handled.
|
||||
memcpy((*out)->data(), data, size);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
namespace api {
|
||||
|
||||
template <typename Flags>
|
||||
URLRequest::StateBase<Flags>::StateBase(Flags initialState)
|
||||
: state_(initialState) {}
|
||||
|
||||
template <typename Flags>
|
||||
void URLRequest::StateBase<Flags>::SetFlag(Flags flag) {
|
||||
state_ =
|
||||
static_cast<Flags>(static_cast<int>(state_) | static_cast<int>(flag));
|
||||
}
|
||||
|
||||
template <typename Flags>
|
||||
bool URLRequest::StateBase<Flags>::operator==(Flags flag) const {
|
||||
return state_ == flag;
|
||||
}
|
||||
|
||||
template <typename Flags>
|
||||
bool URLRequest::StateBase<Flags>::IsFlagSet(Flags flag) const {
|
||||
return static_cast<int>(state_) & static_cast<int>(flag);
|
||||
}
|
||||
|
||||
URLRequest::RequestState::RequestState()
|
||||
: StateBase(RequestStateFlags::kNotStarted) {}
|
||||
|
||||
bool URLRequest::RequestState::NotStarted() const {
|
||||
return *this == RequestStateFlags::kNotStarted;
|
||||
}
|
||||
|
||||
bool URLRequest::RequestState::Started() const {
|
||||
return IsFlagSet(RequestStateFlags::kStarted);
|
||||
}
|
||||
|
||||
bool URLRequest::RequestState::Finished() const {
|
||||
return IsFlagSet(RequestStateFlags::kFinished);
|
||||
}
|
||||
|
||||
bool URLRequest::RequestState::Canceled() const {
|
||||
return IsFlagSet(RequestStateFlags::kCanceled);
|
||||
}
|
||||
|
||||
bool URLRequest::RequestState::Failed() const {
|
||||
return IsFlagSet(RequestStateFlags::kFailed);
|
||||
}
|
||||
|
||||
bool URLRequest::RequestState::Closed() const {
|
||||
return IsFlagSet(RequestStateFlags::kClosed);
|
||||
}
|
||||
|
||||
URLRequest::ResponseState::ResponseState()
|
||||
: StateBase(ResponseStateFlags::kNotStarted) {}
|
||||
|
||||
bool URLRequest::ResponseState::NotStarted() const {
|
||||
return *this == ResponseStateFlags::kNotStarted;
|
||||
}
|
||||
|
||||
bool URLRequest::ResponseState::Started() const {
|
||||
return IsFlagSet(ResponseStateFlags::kStarted);
|
||||
}
|
||||
|
||||
bool URLRequest::ResponseState::Ended() const {
|
||||
return IsFlagSet(ResponseStateFlags::kEnded);
|
||||
}
|
||||
|
||||
bool URLRequest::ResponseState::Failed() const {
|
||||
return IsFlagSet(ResponseStateFlags::kFailed);
|
||||
}
|
||||
|
||||
URLRequest::URLRequest(v8::Isolate* isolate, v8::Local<v8::Object> wrapper) {
|
||||
InitWith(isolate, wrapper);
|
||||
}
|
||||
|
||||
URLRequest::~URLRequest() {
|
||||
// A request has been created in JS, it was not used and then
|
||||
// it got collected, no close event to cleanup, only destructor
|
||||
// is called.
|
||||
if (atom_request_) {
|
||||
atom_request_->Terminate();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
mate::WrappableBase* URLRequest::New(mate::Arguments* args) {
|
||||
auto isolate = args->isolate();
|
||||
v8::Local<v8::Object> options;
|
||||
args->GetNext(&options);
|
||||
mate::Dictionary dict(isolate, options);
|
||||
std::string method;
|
||||
dict.Get("method", &method);
|
||||
std::string url;
|
||||
dict.Get("url", &url);
|
||||
std::string redirect_policy;
|
||||
dict.Get("redirect", &redirect_policy);
|
||||
std::string partition;
|
||||
mate::Handle<api::Session> session;
|
||||
if (dict.Get("session", &session)) {
|
||||
} else if (dict.Get("partition", &partition)) {
|
||||
session = Session::FromPartition(isolate, partition);
|
||||
} else {
|
||||
// Use the default session if not specified.
|
||||
session = Session::FromPartition(isolate, "");
|
||||
}
|
||||
auto browser_context = session->browser_context();
|
||||
auto api_url_request = new URLRequest(args->isolate(), args->GetThis());
|
||||
auto atom_url_request = AtomURLRequest::Create(
|
||||
browser_context, method, url, redirect_policy, api_url_request);
|
||||
|
||||
api_url_request->atom_request_ = atom_url_request;
|
||||
|
||||
return api_url_request;
|
||||
}
|
||||
|
||||
// static
|
||||
void URLRequest::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "URLRequest"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
// Request API
|
||||
.MakeDestroyable()
|
||||
.SetMethod("write", &URLRequest::Write)
|
||||
.SetMethod("cancel", &URLRequest::Cancel)
|
||||
.SetMethod("setExtraHeader", &URLRequest::SetExtraHeader)
|
||||
.SetMethod("removeExtraHeader", &URLRequest::RemoveExtraHeader)
|
||||
.SetMethod("setChunkedUpload", &URLRequest::SetChunkedUpload)
|
||||
.SetMethod("followRedirect", &URLRequest::FollowRedirect)
|
||||
.SetMethod("_setLoadFlags", &URLRequest::SetLoadFlags)
|
||||
.SetProperty("notStarted", &URLRequest::NotStarted)
|
||||
.SetProperty("finished", &URLRequest::Finished)
|
||||
// Response APi
|
||||
.SetProperty("statusCode", &URLRequest::StatusCode)
|
||||
.SetProperty("statusMessage", &URLRequest::StatusMessage)
|
||||
.SetProperty("rawResponseHeaders", &URLRequest::RawResponseHeaders)
|
||||
.SetProperty("httpVersionMajor", &URLRequest::ResponseHttpVersionMajor)
|
||||
.SetProperty("httpVersionMinor", &URLRequest::ResponseHttpVersionMinor);
|
||||
}
|
||||
|
||||
bool URLRequest::NotStarted() const {
|
||||
return request_state_.NotStarted();
|
||||
}
|
||||
|
||||
bool URLRequest::Finished() const {
|
||||
return request_state_.Finished();
|
||||
}
|
||||
|
||||
bool URLRequest::Canceled() const {
|
||||
return request_state_.Canceled();
|
||||
}
|
||||
|
||||
bool URLRequest::Write(scoped_refptr<const net::IOBufferWithSize> buffer,
|
||||
bool is_last) {
|
||||
if (request_state_.Canceled() || request_state_.Failed() ||
|
||||
request_state_.Finished() || request_state_.Closed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request_state_.NotStarted()) {
|
||||
request_state_.SetFlag(RequestStateFlags::kStarted);
|
||||
// Pin on first write.
|
||||
Pin();
|
||||
}
|
||||
|
||||
if (is_last) {
|
||||
request_state_.SetFlag(RequestStateFlags::kFinished);
|
||||
EmitRequestEvent(true, "finish");
|
||||
}
|
||||
|
||||
DCHECK(atom_request_);
|
||||
if (atom_request_) {
|
||||
return atom_request_->Write(buffer, is_last);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void URLRequest::Cancel() {
|
||||
if (request_state_.Canceled() || request_state_.Closed()) {
|
||||
// Cancel only once.
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark as canceled.
|
||||
request_state_.SetFlag(RequestStateFlags::kCanceled);
|
||||
|
||||
DCHECK(atom_request_);
|
||||
if (atom_request_ && request_state_.Started()) {
|
||||
// Really cancel if it was started.
|
||||
atom_request_->Cancel();
|
||||
}
|
||||
EmitRequestEvent(true, "abort");
|
||||
|
||||
if (response_state_.Started() && !response_state_.Ended()) {
|
||||
EmitResponseEvent(true, "aborted");
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
void URLRequest::FollowRedirect() {
|
||||
if (request_state_.Canceled() || request_state_.Closed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(atom_request_);
|
||||
if (atom_request_) {
|
||||
atom_request_->FollowRedirect();
|
||||
}
|
||||
}
|
||||
|
||||
bool URLRequest::SetExtraHeader(const std::string& name,
|
||||
const std::string& value) {
|
||||
// Request state must be in the initial non started state.
|
||||
if (!request_state_.NotStarted()) {
|
||||
// Cannot change headers after send.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!net::HttpUtil::IsValidHeaderName(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!net::HttpUtil::IsValidHeaderValue(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DCHECK(atom_request_);
|
||||
if (atom_request_) {
|
||||
atom_request_->SetExtraHeader(name, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void URLRequest::RemoveExtraHeader(const std::string& name) {
|
||||
// State must be equal to not started.
|
||||
if (!request_state_.NotStarted()) {
|
||||
// Cannot change headers after send.
|
||||
return;
|
||||
}
|
||||
DCHECK(atom_request_);
|
||||
if (atom_request_) {
|
||||
atom_request_->RemoveExtraHeader(name);
|
||||
}
|
||||
}
|
||||
|
||||
void URLRequest::SetChunkedUpload(bool is_chunked_upload) {
|
||||
// State must be equal to not started.
|
||||
if (!request_state_.NotStarted()) {
|
||||
// Cannot change headers after send.
|
||||
return;
|
||||
}
|
||||
DCHECK(atom_request_);
|
||||
if (atom_request_) {
|
||||
atom_request_->SetChunkedUpload(is_chunked_upload);
|
||||
}
|
||||
}
|
||||
|
||||
void URLRequest::SetLoadFlags(int flags) {
|
||||
// State must be equal to not started.
|
||||
if (!request_state_.NotStarted()) {
|
||||
// Cannot change load flags after start.
|
||||
return;
|
||||
}
|
||||
DCHECK(atom_request_);
|
||||
if (atom_request_) {
|
||||
atom_request_->SetLoadFlags(flags);
|
||||
}
|
||||
}
|
||||
|
||||
void URLRequest::OnReceivedRedirect(
|
||||
int status_code,
|
||||
const std::string& method,
|
||||
const GURL& url,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers) {
|
||||
if (request_state_.Canceled() || request_state_.Closed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(atom_request_);
|
||||
if (!atom_request_) {
|
||||
return;
|
||||
}
|
||||
|
||||
EmitRequestEvent(false, "redirect", status_code, method, url,
|
||||
response_headers.get());
|
||||
}
|
||||
|
||||
void URLRequest::OnAuthenticationRequired(
|
||||
scoped_refptr<const net::AuthChallengeInfo> auth_info) {
|
||||
if (request_state_.Canceled() || request_state_.Closed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(atom_request_);
|
||||
if (!atom_request_) {
|
||||
return;
|
||||
}
|
||||
|
||||
Emit("login", auth_info.get(),
|
||||
base::Bind(&AtomURLRequest::PassLoginInformation, atom_request_));
|
||||
}
|
||||
|
||||
void URLRequest::OnResponseStarted(
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers) {
|
||||
if (request_state_.Canceled() || request_state_.Failed() ||
|
||||
request_state_.Closed()) {
|
||||
// Don't emit any event after request cancel.
|
||||
return;
|
||||
}
|
||||
response_headers_ = response_headers;
|
||||
response_state_.SetFlag(ResponseStateFlags::kStarted);
|
||||
Emit("response");
|
||||
}
|
||||
|
||||
void URLRequest::OnResponseData(
|
||||
scoped_refptr<const net::IOBufferWithSize> buffer) {
|
||||
if (request_state_.Canceled() || request_state_.Closed() ||
|
||||
request_state_.Failed() || response_state_.Failed()) {
|
||||
// In case we received an unexpected event from Chromium net,
|
||||
// don't emit any data event after request cancel/error/close.
|
||||
return;
|
||||
}
|
||||
if (!buffer || !buffer->data() || !buffer->size()) {
|
||||
return;
|
||||
}
|
||||
Emit("data", buffer);
|
||||
}
|
||||
|
||||
void URLRequest::OnResponseCompleted() {
|
||||
if (request_state_.Canceled() || request_state_.Closed() ||
|
||||
request_state_.Failed() || response_state_.Failed()) {
|
||||
// In case we received an unexpected event from Chromium net,
|
||||
// don't emit any data event after request cancel/error/close.
|
||||
return;
|
||||
}
|
||||
response_state_.SetFlag(ResponseStateFlags::kEnded);
|
||||
Emit("end");
|
||||
Close();
|
||||
}
|
||||
|
||||
void URLRequest::OnError(const std::string& error, bool isRequestError) {
|
||||
auto error_object = v8::Exception::Error(mate::StringToV8(isolate(), error));
|
||||
if (isRequestError) {
|
||||
request_state_.SetFlag(RequestStateFlags::kFailed);
|
||||
EmitRequestEvent(false, "error", error_object);
|
||||
} else {
|
||||
response_state_.SetFlag(ResponseStateFlags::kFailed);
|
||||
EmitResponseEvent(false, "error", error_object);
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
int URLRequest::StatusCode() const {
|
||||
if (response_headers_) {
|
||||
return response_headers_->response_code();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string URLRequest::StatusMessage() const {
|
||||
std::string result;
|
||||
if (response_headers_) {
|
||||
result = response_headers_->GetStatusText();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
net::HttpResponseHeaders* URLRequest::RawResponseHeaders() const {
|
||||
return response_headers_.get();
|
||||
}
|
||||
|
||||
uint32_t URLRequest::ResponseHttpVersionMajor() const {
|
||||
if (response_headers_) {
|
||||
return response_headers_->GetHttpVersion().major_value();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t URLRequest::ResponseHttpVersionMinor() const {
|
||||
if (response_headers_) {
|
||||
return response_headers_->GetHttpVersion().minor_value();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void URLRequest::Close() {
|
||||
if (!request_state_.Closed()) {
|
||||
request_state_.SetFlag(RequestStateFlags::kClosed);
|
||||
if (response_state_.Started()) {
|
||||
// Emit a close event if we really have a response object.
|
||||
EmitResponseEvent(true, "close");
|
||||
}
|
||||
EmitRequestEvent(true, "close");
|
||||
}
|
||||
Unpin();
|
||||
if (atom_request_) {
|
||||
// A request has been created in JS, used and then it ended.
|
||||
// We release unneeded net resources.
|
||||
atom_request_->Terminate();
|
||||
}
|
||||
atom_request_ = nullptr;
|
||||
}
|
||||
|
||||
void URLRequest::Pin() {
|
||||
if (wrapper_.IsEmpty()) {
|
||||
wrapper_.Reset(isolate(), GetWrapper());
|
||||
}
|
||||
}
|
||||
|
||||
void URLRequest::Unpin() {
|
||||
wrapper_.Reset();
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void URLRequest::EmitRequestEvent(Args... args) {
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
mate::CustomEmit(isolate(), GetWrapper(), "_emitRequestEvent", args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void URLRequest::EmitResponseEvent(Args... args) {
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
mate::CustomEmit(isolate(), GetWrapper(), "_emitResponseEvent", args...);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
@@ -1,213 +0,0 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_URL_REQUEST_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_URL_REQUEST_H_
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable_base.h"
|
||||
#include "net/base/auth.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomURLRequest;
|
||||
|
||||
namespace api {
|
||||
|
||||
//
|
||||
// The URLRequest class implements the V8 binding between the JavaScript API
|
||||
// and Chromium native net library. It is responsible for handling HTTP/HTTPS
|
||||
// requests.
|
||||
//
|
||||
// The current class provides only the binding layer. Two other JavaScript
|
||||
// classes (ClientRequest and IncomingMessage) in the net module provide the
|
||||
// final API, including some state management and arguments validation.
|
||||
//
|
||||
// URLRequest's methods fall into two main categories: command and event
|
||||
// methods. They are always executed on the Browser's UI thread.
|
||||
// Command methods are called directly from JavaScript code via the API defined
|
||||
// in BuildPrototype. A command method is generally implemented by forwarding
|
||||
// the call to a corresponding method on AtomURLRequest which does the
|
||||
// synchronization on the Browser IO thread. The latter then calls into Chromium
|
||||
// net library. On the other hand, net library events originate on the IO
|
||||
// thread in AtomURLRequest and are synchronized back on the UI thread, then
|
||||
// forwarded to a corresponding event method in URLRequest and then to
|
||||
// JavaScript via the EmitRequestEvent/EmitResponseEvent helpers.
|
||||
//
|
||||
// URLRequest lifetime management: we followed the Wrapper/Wrappable pattern
|
||||
// defined in native_mate. However, we augment that pattern with a pin/unpin
|
||||
// mechanism. The main reason is that we want the JS API to provide a similar
|
||||
// lifetime guarantees as the XMLHttpRequest.
|
||||
// https://xhr.spec.whatwg.org/#garbage-collection
|
||||
//
|
||||
// The primary motivation is to not garbage collect a URLInstance as long as the
|
||||
// object is emitting network events. For instance, in the following JS code
|
||||
//
|
||||
// (function() {
|
||||
// let request = new URLRequest(...);
|
||||
// request.on('response', (response)=>{
|
||||
// response.on('data', (data) = > {
|
||||
// console.log(data.toString());
|
||||
// });
|
||||
// });
|
||||
// })();
|
||||
//
|
||||
// we still want data to be logged even if the response/request objects are n
|
||||
// more referenced in JavaScript.
|
||||
//
|
||||
// Binding by simply following the native_mate Wrapper/Wrappable pattern will
|
||||
// delete the URLRequest object when the corresponding JS object is collected.
|
||||
// The v8 handle is a private member in WrappableBase and it is always weak,
|
||||
// there is no way to make it strong without changing native_mate.
|
||||
// The solution we implement consists of maintaining some kind of state that
|
||||
// prevents collection of JS wrappers as long as the request is emitting network
|
||||
// events. At initialization, the object is unpinned. When the request starts,
|
||||
// it is pinned. When no more events would be emitted, the object is unpinned
|
||||
// and lifetime is again managed by the standard native mate Wrapper/Wrappable
|
||||
// pattern.
|
||||
//
|
||||
// pin/unpin: are implemented by constructing/reseting a V8 strong persistent
|
||||
// handle.
|
||||
//
|
||||
// The URLRequest/AtmURLRequest interaction could have been implemented in a
|
||||
// single class. However, it implies that the resulting class lifetime will be
|
||||
// managed by two conflicting mechanisms: JavaScript garbage collection and
|
||||
// Chromium reference counting. Reasoning about lifetime issues become much
|
||||
// more complex.
|
||||
//
|
||||
// We chose to split the implementation into two classes linked via a
|
||||
// reference counted/raw pointers. A URLRequest instance is deleted if it is
|
||||
// unpinned and the corresponding JS wrapper object is garbage collected. On the
|
||||
// other hand, an AtmURLRequest instance lifetime is totally governed by
|
||||
// reference counting.
|
||||
//
|
||||
class URLRequest : public mate::EventEmitter<URLRequest> {
|
||||
public:
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// Methods for reporting events into JavaScript.
|
||||
void OnReceivedRedirect(
|
||||
int status_code,
|
||||
const std::string& method,
|
||||
const GURL& url,
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers);
|
||||
void OnAuthenticationRequired(
|
||||
scoped_refptr<const net::AuthChallengeInfo> auth_info);
|
||||
void OnResponseStarted(
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers);
|
||||
void OnResponseData(scoped_refptr<const net::IOBufferWithSize> data);
|
||||
void OnResponseCompleted();
|
||||
void OnError(const std::string& error, bool isRequestError);
|
||||
|
||||
protected:
|
||||
explicit URLRequest(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
~URLRequest() override;
|
||||
|
||||
private:
|
||||
template <typename Flags>
|
||||
class StateBase {
|
||||
public:
|
||||
void SetFlag(Flags flag);
|
||||
|
||||
protected:
|
||||
explicit StateBase(Flags initialState);
|
||||
bool operator==(Flags flag) const;
|
||||
bool IsFlagSet(Flags flag) const;
|
||||
|
||||
private:
|
||||
Flags state_;
|
||||
};
|
||||
|
||||
enum class RequestStateFlags {
|
||||
kNotStarted = 0x0,
|
||||
kStarted = 0x1,
|
||||
kFinished = 0x2,
|
||||
kCanceled = 0x4,
|
||||
kFailed = 0x8,
|
||||
kClosed = 0x10
|
||||
};
|
||||
|
||||
class RequestState : public StateBase<RequestStateFlags> {
|
||||
public:
|
||||
RequestState();
|
||||
bool NotStarted() const;
|
||||
bool Started() const;
|
||||
bool Finished() const;
|
||||
bool Canceled() const;
|
||||
bool Failed() const;
|
||||
bool Closed() const;
|
||||
};
|
||||
|
||||
enum class ResponseStateFlags {
|
||||
kNotStarted = 0x0,
|
||||
kStarted = 0x1,
|
||||
kEnded = 0x2,
|
||||
kFailed = 0x4
|
||||
};
|
||||
|
||||
class ResponseState : public StateBase<ResponseStateFlags> {
|
||||
public:
|
||||
ResponseState();
|
||||
bool NotStarted() const;
|
||||
bool Started() const;
|
||||
bool Ended() const;
|
||||
bool Canceled() const;
|
||||
bool Failed() const;
|
||||
bool Closed() const;
|
||||
};
|
||||
|
||||
bool NotStarted() const;
|
||||
bool Finished() const;
|
||||
bool Canceled() const;
|
||||
bool Failed() const;
|
||||
bool Write(scoped_refptr<const net::IOBufferWithSize> buffer, bool is_last);
|
||||
void Cancel();
|
||||
void FollowRedirect();
|
||||
bool SetExtraHeader(const std::string& name, const std::string& value);
|
||||
void RemoveExtraHeader(const std::string& name);
|
||||
void SetChunkedUpload(bool is_chunked_upload);
|
||||
void SetLoadFlags(int flags);
|
||||
|
||||
int StatusCode() const;
|
||||
std::string StatusMessage() const;
|
||||
net::HttpResponseHeaders* RawResponseHeaders() const;
|
||||
uint32_t ResponseHttpVersionMajor() const;
|
||||
uint32_t ResponseHttpVersionMinor() const;
|
||||
|
||||
void Close();
|
||||
void Pin();
|
||||
void Unpin();
|
||||
template <typename... Args>
|
||||
void EmitRequestEvent(Args... args);
|
||||
template <typename... Args>
|
||||
void EmitResponseEvent(Args... args);
|
||||
|
||||
scoped_refptr<AtomURLRequest> atom_request_;
|
||||
RequestState request_state_;
|
||||
ResponseState response_state_;
|
||||
|
||||
// Used to implement pin/unpin.
|
||||
v8::Global<v8::Object> wrapper_;
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(URLRequest);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_URL_REQUEST_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,14 +12,10 @@
|
||||
#include "atom/browser/api/save_page_handler.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/common_web_contents_delegate.h"
|
||||
#include "atom/browser/ui/autofill_popup.h"
|
||||
#include "content/common/cursors/webcursor.h"
|
||||
#include "content/public/browser/keyboard_event_processing_result.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "content/public/common/favicon_url.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "printing/backend/print_backend.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
namespace blink {
|
||||
@@ -30,10 +26,6 @@ namespace brightray {
|
||||
class InspectableWebContents;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class ResourceRequestBody;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
@@ -43,8 +35,6 @@ namespace atom {
|
||||
|
||||
struct SetSizeParams;
|
||||
class AtomBrowserContext;
|
||||
class AtomJavaScriptDialogManager;
|
||||
class WebContentsZoomController;
|
||||
class WebViewGuestDelegate;
|
||||
|
||||
namespace api {
|
||||
@@ -55,11 +45,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
public:
|
||||
enum Type {
|
||||
BACKGROUND_PAGE, // A DevTools extension background page.
|
||||
BROWSER_WINDOW, // Used by BrowserWindow.
|
||||
BROWSER_VIEW, // Used by BrowserView.
|
||||
REMOTE, // Thin wrap around an existing WebContents.
|
||||
WEB_VIEW, // Used by <webview>.
|
||||
OFF_SCREEN, // Used for offscreen rendering
|
||||
BROWSER_WINDOW, // Used by BrowserWindow.
|
||||
REMOTE, // Thin wrap around an existing WebContents.
|
||||
WEB_VIEW, // Used by <webview>.
|
||||
OFF_SCREEN, // Used for offscreen rendering
|
||||
};
|
||||
|
||||
// For node.js callback function type: function(error, buffer)
|
||||
@@ -69,8 +58,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// Create from an existing WebContents.
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents, Type type);
|
||||
|
||||
// Create a new WebContents.
|
||||
static mate::Handle<WebContents> Create(
|
||||
@@ -79,12 +66,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// Notifies to destroy any guest web contents before destroying self.
|
||||
void DestroyWebContents(bool async);
|
||||
|
||||
int64_t GetID() const;
|
||||
int GetProcessID() const;
|
||||
base::ProcessId GetOSProcessID() const;
|
||||
int GetID() const;
|
||||
Type GetType() const;
|
||||
bool Equal(const WebContents* web_contents) const;
|
||||
void LoadURL(const GURL& url, const mate::Dictionary& options);
|
||||
@@ -99,8 +81,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void GoBack();
|
||||
void GoForward();
|
||||
void GoToOffset(int offset);
|
||||
const std::string GetWebRTCIPHandlingPolicy() const;
|
||||
void SetWebRTCIPHandlingPolicy(const std::string& webrtc_ip_handling_policy);
|
||||
bool IsCrashed() const;
|
||||
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
|
||||
std::string GetUserAgent();
|
||||
@@ -117,17 +97,11 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void DisableDeviceEmulation();
|
||||
void InspectElement(int x, int y);
|
||||
void InspectServiceWorker();
|
||||
void HasServiceWorker(
|
||||
const base::Callback<void(bool)>&);
|
||||
void HasServiceWorker(const base::Callback<void(bool)>&);
|
||||
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
|
||||
void SetIgnoreMenuShortcuts(bool ignore);
|
||||
void SetAudioMuted(bool muted);
|
||||
bool IsAudioMuted();
|
||||
void Print(mate::Arguments* args);
|
||||
std::vector<printing::PrinterBasicInfo> GetPrinterList();
|
||||
void SetEmbedder(const WebContents* embedder);
|
||||
void SetDevToolsWebContents(const WebContents* devtools);
|
||||
v8::Local<v8::Value> GetNativeView() const;
|
||||
|
||||
// Print current page as PDF.
|
||||
void PrintToPDF(const base::DictionaryValue& setting,
|
||||
@@ -190,14 +164,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
bool IsPainting() const;
|
||||
void SetFrameRate(int frame_rate);
|
||||
int GetFrameRate() const;
|
||||
void Invalidate();
|
||||
gfx::Size GetSizeForNewRenderView(content::WebContents*) const override;
|
||||
|
||||
// Methods for zoom handling.
|
||||
void SetZoomLevel(double level);
|
||||
double GetZoomLevel();
|
||||
void SetZoomFactor(double factor);
|
||||
double GetZoomFactor();
|
||||
|
||||
// Callback triggered on permission response.
|
||||
void OnEnterFullscreenModeForTab(content::WebContents* source,
|
||||
@@ -205,12 +171,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
bool allowed);
|
||||
|
||||
// Create window with the given disposition.
|
||||
void OnCreateWindow(
|
||||
const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const std::vector<std::string>& features,
|
||||
const scoped_refptr<content::ResourceRequestBody>& body);
|
||||
void OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition);
|
||||
|
||||
// Returns the web preferences of current WebContents.
|
||||
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
|
||||
@@ -218,10 +181,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// Returns the owner window.
|
||||
v8::Local<v8::Value> GetOwnerBrowserWindow();
|
||||
|
||||
// Grants the child process the capability to access URLs with the origin of
|
||||
// the specified URL.
|
||||
void GrantOriginAccess(const GURL& url);
|
||||
|
||||
// Properties.
|
||||
int32_t ID() const;
|
||||
v8::Local<v8::Value> Session(v8::Isolate* isolate);
|
||||
@@ -229,40 +188,17 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> Debugger(v8::Isolate* isolate);
|
||||
|
||||
WebContentsZoomController* GetZoomController() { return zoom_controller_; }
|
||||
|
||||
protected:
|
||||
WebContents(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
Type type);
|
||||
WebContents(v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
|
||||
~WebContents();
|
||||
|
||||
void InitWithSessionAndOptions(v8::Isolate* isolate,
|
||||
content::WebContents *web_contents,
|
||||
mate::Handle<class Session> session,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
// content::WebContentsDelegate:
|
||||
bool DidAddMessageToConsole(content::WebContents* source,
|
||||
int32_t level,
|
||||
const base::string16& message,
|
||||
int32_t line_no,
|
||||
const base::string16& source_id) override;
|
||||
void WebContentsCreated(
|
||||
content::WebContents* source_contents,
|
||||
int opener_render_process_id,
|
||||
int opener_render_frame_id,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
content::WebContents* new_contents)
|
||||
override;
|
||||
void AddNewContents(content::WebContents* source,
|
||||
content::WebContents* new_contents,
|
||||
WindowOpenDisposition disposition,
|
||||
const gfx::Rect& initial_rect,
|
||||
bool user_gesture,
|
||||
bool* was_blocked) override;
|
||||
bool AddMessageToConsole(content::WebContents* source,
|
||||
int32_t level,
|
||||
const base::string16& message,
|
||||
int32_t line_no,
|
||||
const base::string16& source_id) override;
|
||||
content::WebContents* OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) override;
|
||||
@@ -278,15 +214,10 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void HandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
|
||||
content::WebContents* source,
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
void EnterFullscreenModeForTab(content::WebContents* source,
|
||||
const GURL& origin) override;
|
||||
void ExitFullscreenModeForTab(content::WebContents* source) override;
|
||||
void RendererUnresponsive(
|
||||
content::WebContents* source,
|
||||
const content::WebContentsUnresponsiveState& unresponsive_state) override;
|
||||
void RendererUnresponsive(content::WebContents* source) override;
|
||||
void RendererResponsive(content::WebContents* source) override;
|
||||
bool HandleContextMenu(const content::ContextMenuParams& params) override;
|
||||
bool OnGoToEntryOffset(int offset) override;
|
||||
@@ -311,12 +242,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
std::unique_ptr<content::BluetoothChooser> RunBluetoothChooser(
|
||||
content::RenderFrameHost* frame,
|
||||
const content::BluetoothChooser::EventHandler& handler) override;
|
||||
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
|
||||
content::WebContents* source) override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
|
||||
void RenderViewCreated(content::RenderViewHost*) override;
|
||||
void RenderViewDeleted(content::RenderViewHost*) override;
|
||||
void RenderProcessGone(base::TerminationStatus status) override;
|
||||
void DocumentLoadedInFrame(
|
||||
@@ -333,12 +261,11 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void DidGetResourceResponseStart(
|
||||
const content::ResourceRequestDetails& details) override;
|
||||
void DidGetRedirectForResourceRequest(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const content::ResourceRedirectDetails& details) override;
|
||||
void DidFinishNavigation(
|
||||
content::NavigationHandle* navigation_handle) override;
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
bool OnMessageReceived(const IPC::Message& message,
|
||||
content::RenderFrameHost* frame_host) override;
|
||||
void WebContentsDestroyed() override;
|
||||
void NavigationEntryCommitted(
|
||||
const content::LoadCommittedDetails& load_details) override;
|
||||
@@ -347,10 +274,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
const std::vector<content::FaviconURL>& urls) override;
|
||||
void PluginCrashed(const base::FilePath& plugin_path,
|
||||
base::ProcessId plugin_pid) override;
|
||||
void MediaStartedPlaying(const MediaPlayerInfo& video_type,
|
||||
const MediaPlayerId& id) override;
|
||||
void MediaStoppedPlaying(const MediaPlayerInfo& video_type,
|
||||
const MediaPlayerId& id) override;
|
||||
void MediaStartedPlaying(const MediaPlayerId& id) override;
|
||||
void MediaStoppedPlaying(const MediaPlayerId& id) override;
|
||||
void DidChangeThemeColor(SkColor theme_color) override;
|
||||
|
||||
// brightray::InspectableWebContentsDelegate:
|
||||
@@ -361,11 +286,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void DevToolsOpened() override;
|
||||
void DevToolsClosed() override;
|
||||
|
||||
void ShowAutofillPopup(content::RenderFrameHost* frame_host,
|
||||
const gfx::RectF& bounds,
|
||||
const std::vector<base::string16>& values,
|
||||
const std::vector<base::string16>& labels);
|
||||
|
||||
private:
|
||||
AtomBrowserContext* GetBrowserContext() const;
|
||||
|
||||
@@ -385,30 +305,15 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
const base::ListValue& args,
|
||||
IPC::Message* message);
|
||||
|
||||
// Called when received a synchronous message from renderer to
|
||||
// set temporary zoom level.
|
||||
void OnSetTemporaryZoomLevel(double level, IPC::Message* reply_msg);
|
||||
|
||||
// Called when received a synchronous message from renderer to
|
||||
// get the zoom level.
|
||||
void OnGetZoomLevel(IPC::Message* reply_msg);
|
||||
|
||||
void InitZoomController(content::WebContents* web_contents,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
v8::Global<v8::Value> session_;
|
||||
v8::Global<v8::Value> devtools_web_contents_;
|
||||
v8::Global<v8::Value> debugger_;
|
||||
|
||||
std::unique_ptr<AtomJavaScriptDialogManager> dialog_manager_;
|
||||
std::unique_ptr<WebViewGuestDelegate> guest_delegate_;
|
||||
|
||||
// The host webcontents that may contain this webcontents.
|
||||
WebContents* embedder_;
|
||||
|
||||
// The zoom controller for this webContents.
|
||||
WebContentsZoomController* zoom_controller_;
|
||||
|
||||
// The type of current WebContents.
|
||||
Type type_;
|
||||
|
||||
|
||||
@@ -20,14 +20,13 @@ using content::BrowserThread;
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<URLPattern> {
|
||||
struct Converter<extensions::URLPattern> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
URLPattern* out) {
|
||||
extensions::URLPattern* out) {
|
||||
std::string pattern;
|
||||
if (!ConvertFromV8(isolate, val, &pattern))
|
||||
return false;
|
||||
*out = URLPattern(URLPattern::SCHEME_ALL);
|
||||
return out->Parse(pattern) == URLPattern::PARSE_SUCCESS;
|
||||
return out->Parse(pattern) == extensions::URLPattern::PARSE_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -37,26 +36,6 @@ namespace atom {
|
||||
|
||||
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,
|
||||
AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
@@ -94,15 +73,10 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
|
||||
return;
|
||||
}
|
||||
|
||||
brightray::URLRequestContextGetter* url_request_context_getter =
|
||||
browser_context_->url_request_context_getter();
|
||||
if (!url_request_context_getter)
|
||||
return;
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&CallNetworkDelegateMethod<Method, Event, Listener>,
|
||||
base::RetainedRef(url_request_context_getter),
|
||||
method, type, std::move(patterns), std::move(listener)));
|
||||
auto delegate = browser_context_->network_delegate();
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(method, base::Unretained(delegate), type,
|
||||
patterns, listener));
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -3,16 +3,12 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/web_contents_zoom_controller.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/native_mate_converters/content_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
// Must be the last in the includes list.
|
||||
// See https://github.com/electron/electron/issues/10363
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using atom::WebContentsPreferences;
|
||||
|
||||
@@ -28,12 +24,6 @@ void AddGuest(int guest_instance_id,
|
||||
manager->AddGuest(guest_instance_id, element_instance_id, embedder,
|
||||
guest_web_contents);
|
||||
|
||||
double zoom_factor;
|
||||
if (options.GetDouble(atom::options::kZoomFactor, &zoom_factor)) {
|
||||
atom::WebContentsZoomController::FromWebContents(guest_web_contents)
|
||||
->SetDefaultZoomFactor(zoom_factor);
|
||||
}
|
||||
|
||||
WebContentsPreferences::FromWebContents(guest_web_contents)->Merge(options);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,23 +3,20 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_window.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_browser_view.h"
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "native_mate/constructor.h"
|
||||
@@ -32,11 +29,8 @@
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "atom/browser/ui/win/taskbar_host.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#endif
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
namespace mate {
|
||||
|
||||
@@ -77,9 +71,7 @@ v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
|
||||
|
||||
Window::Window(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options) {
|
||||
mate::Handle<class WebContents> web_contents;
|
||||
|
||||
// Use options.webPreferences in WebContents.
|
||||
// Use options.webPreferences to create WebContents.
|
||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
|
||||
@@ -91,41 +83,8 @@ Window::Window(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
|
||||
v8::Local<v8::Value> transparent;
|
||||
if (options.Get("transparent", &transparent))
|
||||
web_preferences.Set("transparent", transparent);
|
||||
|
||||
#if defined(ENABLE_OSR)
|
||||
// Offscreen windows are always created frameless.
|
||||
bool offscreen;
|
||||
if (web_preferences.Get("offscreen", &offscreen) && offscreen) {
|
||||
auto window_options = const_cast<mate::Dictionary&>(options);
|
||||
window_options.Set(options::kFrame, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (options.Get("webContents", &web_contents) && !web_contents.IsEmpty()) {
|
||||
// Set webPreferences from options if using an existing webContents.
|
||||
// These preferences will be used when the webContent launches new
|
||||
// render processes.
|
||||
auto* existing_preferences =
|
||||
WebContentsPreferences::FromWebContents(web_contents->web_contents());
|
||||
base::DictionaryValue web_preferences_dict;
|
||||
if (mate::ConvertFromV8(isolate, web_preferences.GetHandle(),
|
||||
&web_preferences_dict)) {
|
||||
existing_preferences->web_preferences()->Clear();
|
||||
existing_preferences->Merge(web_preferences_dict);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Creates the WebContents used by BrowserWindow.
|
||||
web_contents = WebContents::Create(isolate, web_preferences);
|
||||
}
|
||||
|
||||
Init(isolate, wrapper, options, web_contents);
|
||||
}
|
||||
|
||||
void Window::Init(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options,
|
||||
mate::Handle<class WebContents> web_contents) {
|
||||
// Creates the WebContents used by BrowserWindow.
|
||||
auto web_contents = WebContents::Create(isolate, web_preferences);
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents.get();
|
||||
|
||||
@@ -135,7 +94,7 @@ void Window::Init(v8::Isolate* isolate,
|
||||
|
||||
// The parent window.
|
||||
mate::Handle<Window> parent;
|
||||
if (options.Get("parent", &parent) && !parent.IsEmpty())
|
||||
if (options.Get("parent", &parent))
|
||||
parent_window_.Reset(isolate, parent.ToV8());
|
||||
|
||||
// Creates BrowserWindow.
|
||||
@@ -144,12 +103,11 @@ void Window::Init(v8::Isolate* isolate,
|
||||
options,
|
||||
parent.IsEmpty() ? nullptr : parent->window_.get()));
|
||||
web_contents->SetOwnerWindow(window_.get());
|
||||
window_->set_is_offscreen_dummy(api_web_contents_->IsOffScreen());
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
// Sets the window icon.
|
||||
mate::Handle<NativeImage> icon;
|
||||
if (options.Get(options::kIcon, &icon) && !icon.IsEmpty())
|
||||
if (options.Get(options::kIcon, &icon))
|
||||
SetIcon(icon);
|
||||
#endif
|
||||
|
||||
@@ -171,7 +129,7 @@ Window::~Window() {
|
||||
|
||||
// Destroy the native window in next tick because the native code might be
|
||||
// iterating all windows.
|
||||
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release());
|
||||
base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
|
||||
}
|
||||
|
||||
void Window::WillCloseWindow(bool* prevent_default) {
|
||||
@@ -184,13 +142,13 @@ void Window::WillDestroyNativeObject() {
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
for (v8::Local<v8::Value> value : child_windows_.Values(isolate())) {
|
||||
mate::Handle<Window> child;
|
||||
if (mate::ConvertFromV8(isolate(), value, &child) && !child.IsEmpty())
|
||||
if (mate::ConvertFromV8(isolate(), value, &child))
|
||||
child->window_->CloseImmediately();
|
||||
}
|
||||
}
|
||||
|
||||
void Window::OnWindowClosed() {
|
||||
api_web_contents_->DestroyWebContents(true /* async */);
|
||||
api_web_contents_->DestroyWebContents();
|
||||
|
||||
RemoveFromWeakMap();
|
||||
window_->RemoveObserver(this);
|
||||
@@ -203,15 +161,8 @@ void Window::OnWindowClosed() {
|
||||
|
||||
RemoveFromParentChildWindows();
|
||||
|
||||
ResetBrowserView();
|
||||
|
||||
// Destroy the native class when window is closed.
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, GetDestroyClosure());
|
||||
}
|
||||
|
||||
void Window::OnWindowEndSession() {
|
||||
Emit("session-end");
|
||||
base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure());
|
||||
}
|
||||
|
||||
void Window::OnWindowBlur() {
|
||||
@@ -278,22 +229,10 @@ void Window::OnWindowScrollTouchEnd() {
|
||||
Emit("scroll-touch-end");
|
||||
}
|
||||
|
||||
void Window::OnWindowScrollTouchEdge() {
|
||||
Emit("scroll-touch-edge");
|
||||
}
|
||||
|
||||
void Window::OnWindowSwipe(const std::string& direction) {
|
||||
Emit("swipe", direction);
|
||||
}
|
||||
|
||||
void Window::OnWindowSheetBegin() {
|
||||
Emit("sheet-begin");
|
||||
}
|
||||
|
||||
void Window::OnWindowSheetEnd() {
|
||||
Emit("sheet-end");
|
||||
}
|
||||
|
||||
void Window::OnWindowEnterHtmlFullScreen() {
|
||||
Emit("enter-html-full-screen");
|
||||
}
|
||||
@@ -314,15 +253,6 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) {
|
||||
Emit("app-command", command_name);
|
||||
}
|
||||
|
||||
void Window::OnTouchBarItemResult(const std::string& item_id,
|
||||
const base::DictionaryValue& details) {
|
||||
Emit("-touch-bar-interaction", item_id, details);
|
||||
}
|
||||
|
||||
void Window::OnNewWindowForTab() {
|
||||
Emit("new-window-for-tab");
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
|
||||
if (IsWindowMessageHooked(message)) {
|
||||
@@ -393,10 +323,6 @@ bool Window::IsEnabled() {
|
||||
return window_->IsEnabled();
|
||||
}
|
||||
|
||||
void Window::SetEnabled(bool enable) {
|
||||
window_->SetEnabled(enable);
|
||||
}
|
||||
|
||||
void Window::Maximize() {
|
||||
window_->Maximize();
|
||||
}
|
||||
@@ -555,19 +481,8 @@ bool Window::IsClosable() {
|
||||
return window_->IsClosable();
|
||||
}
|
||||
|
||||
void Window::SetAlwaysOnTop(bool top, mate::Arguments* args) {
|
||||
std::string level = "floating";
|
||||
int relativeLevel = 0;
|
||||
std::string error;
|
||||
|
||||
args->GetNext(&level);
|
||||
args->GetNext(&relativeLevel);
|
||||
|
||||
window_->SetAlwaysOnTop(top, level, relativeLevel, &error);
|
||||
|
||||
if (!error.empty()) {
|
||||
args->ThrowError(error);
|
||||
}
|
||||
void Window::SetAlwaysOnTop(bool top) {
|
||||
window_->SetAlwaysOnTop(top);
|
||||
}
|
||||
|
||||
bool Window::IsAlwaysOnTop() {
|
||||
@@ -608,14 +523,6 @@ void Window::SetSkipTaskbar(bool skip) {
|
||||
window_->SetSkipTaskbar(skip);
|
||||
}
|
||||
|
||||
void Window::SetSimpleFullScreen(bool simple_fullscreen) {
|
||||
window_->SetSimpleFullScreen(simple_fullscreen);
|
||||
}
|
||||
|
||||
bool Window::IsSimpleFullScreen() {
|
||||
return window_->IsSimpleFullScreen();
|
||||
}
|
||||
|
||||
void Window::SetKiosk(bool kiosk) {
|
||||
window_->SetKiosk(kiosk);
|
||||
}
|
||||
@@ -636,14 +543,6 @@ bool Window::HasShadow() {
|
||||
return window_->HasShadow();
|
||||
}
|
||||
|
||||
void Window::SetOpacity(const double opacity) {
|
||||
window_->SetOpacity(opacity);
|
||||
}
|
||||
|
||||
double Window::GetOpacity() {
|
||||
return window_->GetOpacity();
|
||||
}
|
||||
|
||||
void Window::FocusOnWebView() {
|
||||
window_->FocusOnWebView();
|
||||
}
|
||||
@@ -672,11 +571,8 @@ bool Window::IsDocumentEdited() {
|
||||
return window_->IsDocumentEdited();
|
||||
}
|
||||
|
||||
void Window::SetIgnoreMouseEvents(bool ignore, mate::Arguments* args) {
|
||||
mate::Dictionary options;
|
||||
bool forward = false;
|
||||
args->GetNext(&options) && options.Get("forward", &forward);
|
||||
return window_->SetIgnoreMouseEvents(ignore, forward);
|
||||
void Window::SetIgnoreMouseEvents(bool ignore) {
|
||||
return window_->SetIgnoreMouseEvents(ignore);
|
||||
}
|
||||
|
||||
void Window::SetContentProtection(bool enable) {
|
||||
@@ -731,7 +627,7 @@ void Window::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
|
||||
mate::Handle<Menu> menu;
|
||||
if (value->IsObject() &&
|
||||
mate::V8ToString(value->ToObject()->GetConstructorName()) == "Menu" &&
|
||||
mate::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) {
|
||||
mate::ConvertFromV8(isolate, value, &menu)) {
|
||||
menu_.Reset(isolate, menu.ToV8());
|
||||
window_->SetMenu(menu->model());
|
||||
} else if (value->IsNull()) {
|
||||
@@ -792,25 +688,6 @@ bool Window::SetThumbnailToolTip(const std::string& tooltip) {
|
||||
return window->taskbar_host().SetThumbnailToolTip(
|
||||
window_->GetAcceleratedWidget(), tooltip);
|
||||
}
|
||||
|
||||
void Window::SetAppDetails(const mate::Dictionary& options) {
|
||||
base::string16 app_id;
|
||||
base::FilePath app_icon_path;
|
||||
int app_icon_index = 0;
|
||||
base::string16 relaunch_command;
|
||||
base::string16 relaunch_display_name;
|
||||
|
||||
options.Get("appId", &app_id);
|
||||
options.Get("appIconPath", &app_icon_path);
|
||||
options.Get("appIconIndex", &app_icon_index);
|
||||
options.Get("relaunchCommand", &relaunch_command);
|
||||
options.Get("relaunchDisplayName", &relaunch_display_name);
|
||||
|
||||
ui::win::SetAppDetailsForWindow(
|
||||
app_id, app_icon_path, app_icon_index,
|
||||
relaunch_command, relaunch_display_name,
|
||||
window_->GetAcceleratedWidget());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
@@ -832,17 +709,6 @@ void Window::SetAspectRatio(double aspect_ratio, mate::Arguments* args) {
|
||||
window_->SetAspectRatio(aspect_ratio, extra_size);
|
||||
}
|
||||
|
||||
void Window::PreviewFile(const std::string& path, mate::Arguments* args) {
|
||||
std::string display_name;
|
||||
if (!args->GetNext(&display_name))
|
||||
display_name = path;
|
||||
window_->PreviewFile(path, display_name);
|
||||
}
|
||||
|
||||
void Window::CloseFilePreview() {
|
||||
window_->CloseFilePreview();
|
||||
}
|
||||
|
||||
void Window::SetParentWindow(v8::Local<v8::Value> value,
|
||||
mate::Arguments* args) {
|
||||
if (IsModal()) {
|
||||
@@ -851,7 +717,7 @@ void Window::SetParentWindow(v8::Local<v8::Value> value,
|
||||
}
|
||||
|
||||
mate::Handle<Window> parent;
|
||||
if (value->IsNull() || value->IsUndefined()) {
|
||||
if (value->IsNull()) {
|
||||
RemoveFromParentChildWindows();
|
||||
parent_window_.Reset();
|
||||
window_->SetParentWindow(nullptr);
|
||||
@@ -875,41 +741,6 @@ std::vector<v8::Local<v8::Object>> Window::GetChildWindows() const {
|
||||
return child_windows_.Values(isolate());
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Window::GetBrowserView() const {
|
||||
if (browser_view_.IsEmpty()) {
|
||||
return v8::Null(isolate());
|
||||
}
|
||||
|
||||
return v8::Local<v8::Value>::New(isolate(), browser_view_);
|
||||
}
|
||||
|
||||
void Window::SetBrowserView(v8::Local<v8::Value> value) {
|
||||
ResetBrowserView();
|
||||
|
||||
mate::Handle<BrowserView> browser_view;
|
||||
if (value->IsNull() || value->IsUndefined()) {
|
||||
window_->SetBrowserView(nullptr);
|
||||
} else if (mate::ConvertFromV8(isolate(), value, &browser_view)) {
|
||||
window_->SetBrowserView(browser_view->view());
|
||||
browser_view->web_contents()->SetOwnerWindow(window_.get());
|
||||
browser_view_.Reset(isolate(), value);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::ResetBrowserView() {
|
||||
if (browser_view_.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mate::Handle<BrowserView> browser_view;
|
||||
if (mate::ConvertFromV8(isolate(), GetBrowserView(), &browser_view)
|
||||
&& !browser_view.IsEmpty()) {
|
||||
browser_view->web_contents()->SetOwnerWindow(nullptr);
|
||||
}
|
||||
|
||||
browser_view_.Reset();
|
||||
}
|
||||
|
||||
bool Window::IsModal() const {
|
||||
return window_->is_modal();
|
||||
}
|
||||
@@ -928,63 +759,15 @@ bool Window::IsVisibleOnAllWorkspaces() {
|
||||
return window_->IsVisibleOnAllWorkspaces();
|
||||
}
|
||||
|
||||
void Window::SetAutoHideCursor(bool auto_hide) {
|
||||
window_->SetAutoHideCursor(auto_hide);
|
||||
}
|
||||
|
||||
void Window::SelectPreviousTab() {
|
||||
window_->SelectPreviousTab();
|
||||
}
|
||||
|
||||
void Window::SelectNextTab() {
|
||||
window_->SelectNextTab();
|
||||
}
|
||||
|
||||
void Window::MergeAllWindows() {
|
||||
window_->MergeAllWindows();
|
||||
}
|
||||
|
||||
void Window::MoveTabToNewWindow() {
|
||||
window_->MoveTabToNewWindow();
|
||||
}
|
||||
|
||||
void Window::ToggleTabBar() {
|
||||
window_->ToggleTabBar();
|
||||
}
|
||||
|
||||
void Window::AddTabbedWindow(NativeWindow* window) {
|
||||
window_->AddTabbedWindow(window);
|
||||
}
|
||||
|
||||
void Window::SetVibrancy(mate::Arguments* args) {
|
||||
std::string type;
|
||||
|
||||
args->GetNext(&type);
|
||||
window_->SetVibrancy(type);
|
||||
}
|
||||
|
||||
void Window::SetTouchBar(const std::vector<mate::PersistentDictionary>& items) {
|
||||
window_->SetTouchBar(items);
|
||||
}
|
||||
|
||||
void Window::RefreshTouchBarItem(const std::string& item_id) {
|
||||
window_->RefreshTouchBarItem(item_id);
|
||||
}
|
||||
|
||||
void Window::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) {
|
||||
window_->SetEscapeTouchBarItem(item);
|
||||
}
|
||||
|
||||
int32_t Window::ID() const {
|
||||
return weak_map_id();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
|
||||
if (web_contents_.IsEmpty()) {
|
||||
if (web_contents_.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
return v8::Local<v8::Value>::New(isolate, web_contents_);
|
||||
else
|
||||
return v8::Local<v8::Value>::New(isolate, web_contents_);
|
||||
}
|
||||
|
||||
void Window::RemoveFromParentChildWindows() {
|
||||
@@ -992,10 +775,8 @@ void Window::RemoveFromParentChildWindows() {
|
||||
return;
|
||||
|
||||
mate::Handle<Window> parent;
|
||||
if (!mate::ConvertFromV8(isolate(), GetParentWindow(), &parent)
|
||||
|| parent.IsEmpty()) {
|
||||
if (!mate::ConvertFromV8(isolate(), GetParentWindow(), &parent))
|
||||
return;
|
||||
}
|
||||
|
||||
parent->child_windows_.Remove(ID());
|
||||
}
|
||||
@@ -1015,7 +796,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("hide", &Window::Hide)
|
||||
.SetMethod("isVisible", &Window::IsVisible)
|
||||
.SetMethod("isEnabled", &Window::IsEnabled)
|
||||
.SetMethod("setEnabled", & Window::SetEnabled)
|
||||
.SetMethod("maximize", &Window::Maximize)
|
||||
.SetMethod("unmaximize", &Window::Unmaximize)
|
||||
.SetMethod("isMaximized", &Window::IsMaximized)
|
||||
@@ -1025,15 +805,11 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("setFullScreen", &Window::SetFullScreen)
|
||||
.SetMethod("isFullScreen", &Window::IsFullscreen)
|
||||
.SetMethod("setAspectRatio", &Window::SetAspectRatio)
|
||||
.SetMethod("previewFile", &Window::PreviewFile)
|
||||
.SetMethod("closeFilePreview", &Window::CloseFilePreview)
|
||||
#if !defined(OS_WIN)
|
||||
.SetMethod("setParentWindow", &Window::SetParentWindow)
|
||||
#endif
|
||||
.SetMethod("getParentWindow", &Window::GetParentWindow)
|
||||
.SetMethod("getChildWindows", &Window::GetChildWindows)
|
||||
.SetMethod("getBrowserView", &Window::GetBrowserView)
|
||||
.SetMethod("setBrowserView", &Window::SetBrowserView)
|
||||
.SetMethod("isModal", &Window::IsModal)
|
||||
.SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle)
|
||||
.SetMethod("getBounds", &Window::GetBounds)
|
||||
@@ -1070,15 +846,11 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getTitle", &Window::GetTitle)
|
||||
.SetMethod("flashFrame", &Window::FlashFrame)
|
||||
.SetMethod("setSkipTaskbar", &Window::SetSkipTaskbar)
|
||||
.SetMethod("setSimpleFullScreen", &Window::SetSimpleFullScreen)
|
||||
.SetMethod("isSimpleFullScreen", &Window::IsSimpleFullScreen)
|
||||
.SetMethod("setKiosk", &Window::SetKiosk)
|
||||
.SetMethod("isKiosk", &Window::IsKiosk)
|
||||
.SetMethod("setBackgroundColor", &Window::SetBackgroundColor)
|
||||
.SetMethod("setHasShadow", &Window::SetHasShadow)
|
||||
.SetMethod("hasShadow", &Window::HasShadow)
|
||||
.SetMethod("setOpacity", &Window::SetOpacity)
|
||||
.SetMethod("getOpacity", &Window::GetOpacity)
|
||||
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
|
||||
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
|
||||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||
@@ -1101,19 +873,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
&Window::SetVisibleOnAllWorkspaces)
|
||||
.SetMethod("isVisibleOnAllWorkspaces",
|
||||
&Window::IsVisibleOnAllWorkspaces)
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("setAutoHideCursor", &Window::SetAutoHideCursor)
|
||||
.SetMethod("mergeAllWindows", &Window::MergeAllWindows)
|
||||
.SetMethod("selectPreviousTab", &Window::SelectPreviousTab)
|
||||
.SetMethod("selectNextTab", &Window::SelectNextTab)
|
||||
.SetMethod("moveTabToNewWindow", &Window::MoveTabToNewWindow)
|
||||
.SetMethod("toggleTabBar", &Window::ToggleTabBar)
|
||||
.SetMethod("addTabbedWindow", &Window::AddTabbedWindow)
|
||||
#endif
|
||||
.SetMethod("setVibrancy", &Window::SetVibrancy)
|
||||
.SetMethod("_setTouchBarItems", &Window::SetTouchBar)
|
||||
.SetMethod("_refreshTouchBarItem", &Window::RefreshTouchBarItem)
|
||||
.SetMethod("_setEscapeTouchBarItem", &Window::SetEscapeTouchBarItem)
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("hookWindowMessage", &Window::HookWindowMessage)
|
||||
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
|
||||
@@ -1121,7 +880,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages)
|
||||
.SetMethod("setThumbnailClip", &Window::SetThumbnailClip)
|
||||
.SetMethod("setThumbnailToolTip", &Window::SetThumbnailToolTip)
|
||||
.SetMethod("setAppDetails", &Window::SetAppDetails)
|
||||
#endif
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
.SetMethod("setIcon", &Window::SetIcon)
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "atom/common/key_weak_map.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/persistent_dictionary.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
class GURL;
|
||||
@@ -52,8 +51,6 @@ class Window : public mate::TrackableObject<Window>,
|
||||
|
||||
NativeWindow* window() const { return window_.get(); }
|
||||
|
||||
int32_t ID() const;
|
||||
|
||||
protected:
|
||||
Window(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options);
|
||||
@@ -63,7 +60,6 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void WillCloseWindow(bool* prevent_default) override;
|
||||
void WillDestroyNativeObject() override;
|
||||
void OnWindowClosed() override;
|
||||
void OnWindowEndSession() override;
|
||||
void OnWindowBlur() override;
|
||||
void OnWindowFocus() override;
|
||||
void OnWindowShow() override;
|
||||
@@ -78,10 +74,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void OnWindowMoved() override;
|
||||
void OnWindowScrollTouchBegin() override;
|
||||
void OnWindowScrollTouchEnd() override;
|
||||
void OnWindowScrollTouchEdge() override;
|
||||
void OnWindowSwipe(const std::string& direction) override;
|
||||
void OnWindowSheetBegin() override;
|
||||
void OnWindowSheetEnd() override;
|
||||
void OnWindowEnterFullScreen() override;
|
||||
void OnWindowLeaveFullScreen() override;
|
||||
void OnWindowEnterHtmlFullScreen() override;
|
||||
@@ -89,19 +82,12 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void OnRendererUnresponsive() override;
|
||||
void OnRendererResponsive() override;
|
||||
void OnExecuteWindowsCommand(const std::string& command_name) override;
|
||||
void OnTouchBarItemResult(const std::string& item_id,
|
||||
const base::DictionaryValue& details) override;
|
||||
void OnNewWindowForTab() override;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void Init(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options,
|
||||
mate::Handle<class WebContents> web_contents);
|
||||
// APIs for NativeWindow.
|
||||
void Close();
|
||||
void Focus();
|
||||
@@ -112,7 +98,6 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void Hide();
|
||||
bool IsVisible();
|
||||
bool IsEnabled();
|
||||
void SetEnabled(bool enable);
|
||||
void Maximize();
|
||||
void Unmaximize();
|
||||
bool IsMaximized();
|
||||
@@ -146,7 +131,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
bool IsFullScreenable();
|
||||
void SetClosable(bool closable);
|
||||
bool IsClosable();
|
||||
void SetAlwaysOnTop(bool top, mate::Arguments* args);
|
||||
void SetAlwaysOnTop(bool top);
|
||||
bool IsAlwaysOnTop();
|
||||
void Center();
|
||||
void SetPosition(int x, int y, mate::Arguments* args);
|
||||
@@ -155,15 +140,11 @@ class Window : public mate::TrackableObject<Window>,
|
||||
std::string GetTitle();
|
||||
void FlashFrame(bool flash);
|
||||
void SetSkipTaskbar(bool skip);
|
||||
void SetSimpleFullScreen(bool simple_fullscreen);
|
||||
bool IsSimpleFullScreen();
|
||||
void SetKiosk(bool kiosk);
|
||||
bool IsKiosk();
|
||||
void SetBackgroundColor(const std::string& color_name);
|
||||
void SetHasShadow(bool has_shadow);
|
||||
bool HasShadow();
|
||||
void SetOpacity(const double opacity);
|
||||
double GetOpacity();
|
||||
void FocusOnWebView();
|
||||
void BlurWebView();
|
||||
bool IsWebViewFocused();
|
||||
@@ -171,7 +152,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
std::string GetRepresentedFilename();
|
||||
void SetDocumentEdited(bool edited);
|
||||
bool IsDocumentEdited();
|
||||
void SetIgnoreMouseEvents(bool ignore, mate::Arguments* args);
|
||||
void SetIgnoreMouseEvents(bool ignore);
|
||||
void SetContentProtection(bool enable);
|
||||
void SetFocusable(bool focusable);
|
||||
void SetProgressBar(double progress, mate::Arguments* args);
|
||||
@@ -184,14 +165,9 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void SetMenuBarVisibility(bool visible);
|
||||
bool IsMenuBarVisible();
|
||||
void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
|
||||
void PreviewFile(const std::string& path, mate::Arguments* args);
|
||||
void CloseFilePreview();
|
||||
void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
|
||||
v8::Local<v8::Value> GetParentWindow() const;
|
||||
std::vector<v8::Local<v8::Object>> GetChildWindows() const;
|
||||
v8::Local<v8::Value> GetBrowserView() const;
|
||||
void SetBrowserView(v8::Local<v8::Value> value);
|
||||
void ResetBrowserView();
|
||||
bool IsModal() const;
|
||||
v8::Local<v8::Value> GetNativeWindowHandle();
|
||||
|
||||
@@ -205,7 +181,6 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void UnhookAllWindowMessages();
|
||||
bool SetThumbnailClip(const gfx::Rect& region);
|
||||
bool SetThumbnailToolTip(const std::string& tooltip);
|
||||
void SetAppDetails(const mate::Dictionary& options);
|
||||
#endif
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
@@ -215,20 +190,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void SetVisibleOnAllWorkspaces(bool visible);
|
||||
bool IsVisibleOnAllWorkspaces();
|
||||
|
||||
void SetAutoHideCursor(bool auto_hide);
|
||||
|
||||
void SelectPreviousTab();
|
||||
void SelectNextTab();
|
||||
void MergeAllWindows();
|
||||
void MoveTabToNewWindow();
|
||||
void ToggleTabBar();
|
||||
void AddTabbedWindow(NativeWindow* window);
|
||||
|
||||
void SetVibrancy(mate::Arguments* args);
|
||||
void SetTouchBar(const std::vector<mate::PersistentDictionary>& items);
|
||||
void RefreshTouchBarItem(const std::string& item_id);
|
||||
void SetEscapeTouchBarItem(const mate::PersistentDictionary& item);
|
||||
|
||||
int32_t ID() const;
|
||||
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
|
||||
|
||||
// Remove this window from parent window's |child_windows_|.
|
||||
@@ -239,7 +201,6 @@ class Window : public mate::TrackableObject<Window>,
|
||||
MessageCallbackMap messages_callback_map_;
|
||||
#endif
|
||||
|
||||
v8::Global<v8::Value> browser_view_;
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
v8::Global<v8::Value> menu_;
|
||||
v8::Global<v8::Value> parent_window_;
|
||||
|
||||
@@ -42,10 +42,8 @@ class EventEmitter : public Wrappable<T> {
|
||||
|
||||
// Make the convinient methods visible:
|
||||
// https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
|
||||
v8::Local<v8::Object> GetWrapper() { return Wrappable<T>::GetWrapper(); }
|
||||
v8::Isolate* isolate() const { return Wrappable<T>::isolate(); }
|
||||
v8::Local<v8::Object> GetWrapper() const {
|
||||
return Wrappable<T>::GetWrapper();
|
||||
}
|
||||
|
||||
// this.emit(name, event, args...);
|
||||
template<typename... Args>
|
||||
@@ -81,12 +79,8 @@ class EventEmitter : public Wrappable<T> {
|
||||
const Args&... args) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
v8::Local<v8::Object> wrapper = GetWrapper();
|
||||
if (wrapper.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
v8::Local<v8::Object> event = internal::CreateJSEvent(
|
||||
isolate(), wrapper, sender, message);
|
||||
isolate(), GetWrapper(), sender, message);
|
||||
return EmitWithEvent(name, event, args...);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/event_subscriber.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// A FunctionTemplate lifetime is bound to the v8 context, so it can be safely
|
||||
// stored as a global here since there's only one for the main process.
|
||||
v8::Global<v8::FunctionTemplate> g_cached_template;
|
||||
|
||||
struct JSHandlerData {
|
||||
JSHandlerData(v8::Isolate* isolate,
|
||||
mate::internal::EventSubscriberBase* subscriber)
|
||||
: handle_(isolate, v8::External::New(isolate, this)),
|
||||
subscriber_(subscriber) {
|
||||
handle_.SetWeak(this, GC, v8::WeakCallbackType::kFinalizer);
|
||||
}
|
||||
|
||||
static void GC(const v8::WeakCallbackInfo<JSHandlerData>& data) {
|
||||
delete data.GetParameter();
|
||||
}
|
||||
|
||||
v8::Global<v8::External> handle_;
|
||||
mate::internal::EventSubscriberBase* subscriber_;
|
||||
};
|
||||
|
||||
void InvokeCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
v8::Locker locker(info.GetIsolate());
|
||||
v8::HandleScope handle_scope(info.GetIsolate());
|
||||
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
mate::Arguments args(info);
|
||||
v8::Local<v8::Value> handler, event;
|
||||
args.GetNext(&handler);
|
||||
args.GetNext(&event);
|
||||
DCHECK(handler->IsExternal());
|
||||
DCHECK(event->IsString());
|
||||
JSHandlerData* handler_data = static_cast<JSHandlerData*>(
|
||||
v8::Local<v8::External>::Cast(handler)->Value());
|
||||
handler_data->subscriber_->EventEmitted(mate::V8ToString(event), &args);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
EventSubscriberBase::EventSubscriberBase(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> emitter)
|
||||
: isolate_(isolate), emitter_(isolate, emitter) {
|
||||
if (g_cached_template.IsEmpty()) {
|
||||
g_cached_template = v8::Global<v8::FunctionTemplate>(
|
||||
isolate_, v8::FunctionTemplate::New(isolate_, InvokeCallback));
|
||||
}
|
||||
}
|
||||
|
||||
EventSubscriberBase::~EventSubscriberBase() {
|
||||
if (!isolate_) {
|
||||
return;
|
||||
}
|
||||
RemoveAllListeners();
|
||||
emitter_.Reset();
|
||||
DCHECK_EQ(js_handlers_.size(), 0u);
|
||||
}
|
||||
|
||||
void EventSubscriberBase::On(const std::string& event_name) {
|
||||
DCHECK(js_handlers_.find(event_name) == js_handlers_.end());
|
||||
v8::Locker locker(isolate_);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
auto fn_template = g_cached_template.Get(isolate_);
|
||||
auto event = mate::StringToV8(isolate_, event_name);
|
||||
auto js_handler_data = new JSHandlerData(isolate_, this);
|
||||
v8::Local<v8::Value> fn = internal::BindFunctionWith(
|
||||
isolate_, isolate_->GetCurrentContext(), fn_template->GetFunction(),
|
||||
js_handler_data->handle_.Get(isolate_), event);
|
||||
js_handlers_.insert(
|
||||
std::make_pair(event_name, v8::Global<v8::Value>(isolate_, fn)));
|
||||
internal::ValueVector converted_args = {event, fn};
|
||||
internal::CallMethodWithArgs(isolate_, emitter_.Get(isolate_), "on",
|
||||
&converted_args);
|
||||
}
|
||||
|
||||
void EventSubscriberBase::Off(const std::string& event_name) {
|
||||
v8::Locker locker(isolate_);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
auto js_handler = js_handlers_.find(event_name);
|
||||
DCHECK(js_handler != js_handlers_.end());
|
||||
RemoveListener(js_handler);
|
||||
}
|
||||
|
||||
void EventSubscriberBase::RemoveAllListeners() {
|
||||
v8::Locker locker(isolate_);
|
||||
v8::Isolate::Scope isolate_scope(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
while (!js_handlers_.empty()) {
|
||||
RemoveListener(js_handlers_.begin());
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, v8::Global<v8::Value>>::iterator
|
||||
EventSubscriberBase::RemoveListener(
|
||||
std::map<std::string, v8::Global<v8::Value>>::iterator it) {
|
||||
internal::ValueVector args = {StringToV8(isolate_, it->first),
|
||||
it->second.Get(isolate_)};
|
||||
internal::CallMethodWithArgs(
|
||||
isolate_, v8::Local<v8::Object>::Cast(emitter_.Get(isolate_)),
|
||||
"removeListener", &args);
|
||||
it->second.Reset();
|
||||
return js_handlers_.erase(it);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace mate
|
||||
@@ -1,139 +0,0 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_EVENT_SUBSCRIBER_H_
|
||||
#define ATOM_BROWSER_API_EVENT_SUBSCRIBER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/api/event_emitter_caller.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/native_mate/arguments.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace internal {
|
||||
|
||||
class EventSubscriberBase {
|
||||
public:
|
||||
EventSubscriberBase(v8::Isolate* isolate, v8::Local<v8::Object> emitter);
|
||||
virtual ~EventSubscriberBase();
|
||||
virtual void EventEmitted(const std::string& event_name,
|
||||
mate::Arguments* args) = 0;
|
||||
|
||||
protected:
|
||||
void On(const std::string& event_name);
|
||||
void Off(const std::string& event_name);
|
||||
void RemoveAllListeners();
|
||||
|
||||
private:
|
||||
std::map<std::string, v8::Global<v8::Value>>::iterator RemoveListener(
|
||||
std::map<std::string, v8::Global<v8::Value>>::iterator it);
|
||||
|
||||
v8::Isolate* isolate_;
|
||||
v8::Global<v8::Object> emitter_;
|
||||
std::map<std::string, v8::Global<v8::Value>> js_handlers_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EventSubscriberBase);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename HandlerType>
|
||||
class EventSubscriber : internal::EventSubscriberBase {
|
||||
public:
|
||||
using EventCallback = void (HandlerType::*)(mate::Arguments* args);
|
||||
// Alias to unique_ptr with deleter.
|
||||
using unique_ptr = std::unique_ptr<EventSubscriber<HandlerType>,
|
||||
void (*)(EventSubscriber<HandlerType>*)>;
|
||||
// EventSubscriber should only be created/deleted in the main thread since it
|
||||
// communicates with the V8 engine. This smart pointer makes it simpler to
|
||||
// bind the lifetime of EventSubscriber with a class whose lifetime is managed
|
||||
// by a non-UI thread.
|
||||
class SafePtr : public unique_ptr {
|
||||
public:
|
||||
SafePtr() : SafePtr(nullptr) {}
|
||||
explicit SafePtr(EventSubscriber<HandlerType>* ptr)
|
||||
: unique_ptr(ptr, Deleter) {}
|
||||
|
||||
private:
|
||||
// Custom deleter that schedules destructor invocation to the main thread.
|
||||
static void Deleter(EventSubscriber<HandlerType>* ptr) {
|
||||
DCHECK(
|
||||
!::content::BrowserThread::CurrentlyOn(::content::BrowserThread::UI));
|
||||
DCHECK(ptr);
|
||||
// Acquire handler lock and reset handler_ to ensure that any new events
|
||||
// emitted will be ignored after this function returns
|
||||
base::AutoLock auto_lock(ptr->handler_lock_);
|
||||
ptr->handler_ = nullptr;
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(
|
||||
[](EventSubscriber<HandlerType>* subscriber) {
|
||||
{
|
||||
// It is possible that this function will execute in the UI
|
||||
// thread before the outer function has returned and destroyed
|
||||
// its auto_lock. We need to acquire the lock before deleting
|
||||
// or risk a crash.
|
||||
base::AutoLock auto_lock(subscriber->handler_lock_);
|
||||
}
|
||||
delete subscriber;
|
||||
},
|
||||
ptr));
|
||||
}
|
||||
};
|
||||
|
||||
EventSubscriber(HandlerType* handler,
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> emitter)
|
||||
: EventSubscriberBase(isolate, emitter), handler_(handler) {
|
||||
DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
|
||||
}
|
||||
|
||||
void On(const std::string& event, EventCallback callback) {
|
||||
DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
|
||||
EventSubscriberBase::On(event);
|
||||
callbacks_.insert(std::make_pair(event, callback));
|
||||
}
|
||||
|
||||
void Off(const std::string& event) {
|
||||
DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
|
||||
EventSubscriberBase::Off(event);
|
||||
DCHECK(callbacks_.find(event) != callbacks_.end());
|
||||
callbacks_.erase(callbacks_.find(event));
|
||||
}
|
||||
|
||||
void RemoveAllListeners() {
|
||||
DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
|
||||
EventSubscriberBase::RemoveAllListeners();
|
||||
callbacks_.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
void EventEmitted(const std::string& event_name,
|
||||
mate::Arguments* args) override {
|
||||
DCHECK_CURRENTLY_ON(::content::BrowserThread::UI);
|
||||
base::AutoLock auto_lock(handler_lock_);
|
||||
if (!handler_) {
|
||||
// handler_ was probably destroyed by another thread and we should not
|
||||
// access it.
|
||||
return;
|
||||
}
|
||||
auto it = callbacks_.find(event_name);
|
||||
if (it != callbacks_.end()) {
|
||||
auto method = it->second;
|
||||
(handler_->*method)(args);
|
||||
}
|
||||
}
|
||||
|
||||
HandlerType* handler_;
|
||||
base::Lock handler_lock_;
|
||||
std::map<std::string, EventCallback> callbacks_;
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // ATOM_BROWSER_API_EVENT_SUBSCRIBER_H_
|
||||
@@ -5,12 +5,9 @@
|
||||
#include "atom/browser/api/frame_subscriber.h"
|
||||
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/bind.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -24,7 +21,6 @@ FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
|
||||
view_(view),
|
||||
callback_(callback),
|
||||
only_dirty_(only_dirty),
|
||||
source_id_for_copy_request_(base::UnguessableToken::Create()),
|
||||
weak_factory_(this) {
|
||||
}
|
||||
|
||||
@@ -33,7 +29,8 @@ bool FrameSubscriber::ShouldCaptureFrame(
|
||||
base::TimeTicks present_time,
|
||||
scoped_refptr<media::VideoFrame>* storage,
|
||||
DeliverFrameCallback* callback) {
|
||||
if (!view_)
|
||||
const auto host = view_ ? view_->GetRenderWidgetHost() : nullptr;
|
||||
if (!view_ || !host)
|
||||
return false;
|
||||
|
||||
if (dirty_rect.IsEmpty())
|
||||
@@ -43,18 +40,7 @@ bool FrameSubscriber::ShouldCaptureFrame(
|
||||
if (only_dirty_)
|
||||
rect = dirty_rect;
|
||||
|
||||
gfx::Size view_size = rect.size();
|
||||
gfx::Size bitmap_size = view_size;
|
||||
gfx::NativeView native_view = view_->GetNativeView();
|
||||
const float scale =
|
||||
display::Screen::GetScreen()->GetDisplayNearestView(native_view)
|
||||
.device_scale_factor();
|
||||
if (scale > 1.0f)
|
||||
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
|
||||
|
||||
rect = gfx::Rect(rect.origin(), bitmap_size);
|
||||
|
||||
view_->CopyFromSurface(
|
||||
host->CopyFromBackingStore(
|
||||
rect,
|
||||
rect.size(),
|
||||
base::Bind(&FrameSubscriber::OnFrameDelivered,
|
||||
@@ -64,10 +50,6 @@ bool FrameSubscriber::ShouldCaptureFrame(
|
||||
return false;
|
||||
}
|
||||
|
||||
const base::UnguessableToken& FrameSubscriber::GetSourceIdForCopyRequest() {
|
||||
return source_id_for_copy_request_;
|
||||
}
|
||||
|
||||
void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback,
|
||||
const gfx::Rect& damage_rect,
|
||||
const SkBitmap& bitmap,
|
||||
@@ -78,31 +60,20 @@ void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback,
|
||||
v8::Locker locker(isolate_);
|
||||
v8::HandleScope handle_scope(isolate_);
|
||||
|
||||
size_t rgb_row_size = bitmap.width() * bitmap.bytesPerPixel();
|
||||
|
||||
v8::MaybeLocal<v8::Object> buffer =
|
||||
node::Buffer::New(isolate_, rgb_row_size * bitmap.height());
|
||||
|
||||
size_t rgb_arr_size = bitmap.width() * bitmap.height() *
|
||||
bitmap.bytesPerPixel();
|
||||
v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate_, rgb_arr_size);
|
||||
if (buffer.IsEmpty())
|
||||
return;
|
||||
|
||||
auto local_buffer = buffer.ToLocalChecked();
|
||||
|
||||
{
|
||||
auto source = static_cast<const unsigned char*>(bitmap.getPixels());
|
||||
auto target = node::Buffer::Data(local_buffer);
|
||||
|
||||
for (int y = 0; y < bitmap.height(); ++y) {
|
||||
memcpy(target, source, rgb_row_size);
|
||||
source += bitmap.rowBytes();
|
||||
target += rgb_row_size;
|
||||
}
|
||||
}
|
||||
bitmap.copyPixelsTo(
|
||||
reinterpret_cast<uint8_t*>(node::Buffer::Data(buffer.ToLocalChecked())),
|
||||
rgb_arr_size);
|
||||
|
||||
v8::Local<v8::Value> damage =
|
||||
mate::Converter<gfx::Rect>::ToV8(isolate_, damage_rect);
|
||||
|
||||
callback_.Run(local_buffer, damage);
|
||||
callback_.Run(buffer.ToLocalChecked(), damage);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_view_frame_subscriber.h"
|
||||
#include "content/public/browser/readback_types.h"
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
#include "v8/include/v8.h"
|
||||
@@ -32,7 +32,6 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
|
||||
base::TimeTicks present_time,
|
||||
scoped_refptr<media::VideoFrame>* storage,
|
||||
DeliverFrameCallback* callback) override;
|
||||
const base::UnguessableToken& GetSourceIdForCopyRequest() override;
|
||||
|
||||
private:
|
||||
void OnFrameDelivered(const FrameCaptureCallback& callback,
|
||||
@@ -45,8 +44,6 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
|
||||
FrameCaptureCallback callback_;
|
||||
bool only_dirty_;
|
||||
|
||||
base::UnguessableToken source_id_for_copy_request_;
|
||||
|
||||
base::WeakPtrFactory<FrameSubscriber> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FrameSubscriber);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/supports_user_data.h"
|
||||
|
||||
namespace mate {
|
||||
@@ -47,19 +46,16 @@ void TrackableObjectBase::Destroy() {
|
||||
}
|
||||
|
||||
void TrackableObjectBase::AttachAsUserData(base::SupportsUserData* wrapped) {
|
||||
wrapped->SetUserData(kTrackedObjectKey,
|
||||
base::MakeUnique<IDUserData>(weak_map_id_));
|
||||
wrapped->SetUserData(kTrackedObjectKey, new IDUserData(weak_map_id_));
|
||||
}
|
||||
|
||||
// static
|
||||
int32_t TrackableObjectBase::GetIDFromWrappedClass(
|
||||
base::SupportsUserData* wrapped) {
|
||||
if (wrapped) {
|
||||
auto id = static_cast<IDUserData*>(wrapped->GetUserData(kTrackedObjectKey));
|
||||
if (id)
|
||||
return *id;
|
||||
}
|
||||
return 0;
|
||||
int32_t TrackableObjectBase::GetIDFromWrappedClass(base::SupportsUserData* w) {
|
||||
auto id = static_cast<IDUserData*>(w->GetUserData(kTrackedObjectKey));
|
||||
if (id)
|
||||
return *id;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -30,15 +30,15 @@ class TrackableObjectBase {
|
||||
// Wrap TrackableObject into a class that SupportsUserData.
|
||||
void AttachAsUserData(base::SupportsUserData* wrapped);
|
||||
|
||||
// Get the weak_map_id from SupportsUserData.
|
||||
static int32_t GetIDFromWrappedClass(base::SupportsUserData* wrapped);
|
||||
|
||||
protected:
|
||||
virtual ~TrackableObjectBase();
|
||||
|
||||
// Returns a closure that can destroy the native class.
|
||||
base::Closure GetDestroyClosure();
|
||||
|
||||
// Get the weak_map_id from SupportsUserData.
|
||||
static int32_t GetIDFromWrappedClass(base::SupportsUserData* wrapped);
|
||||
|
||||
// Register a callback that should be destroyed before JavaScript environment
|
||||
// gets destroyed.
|
||||
static base::Closure RegisterDestructionCallback(const base::Closure& c);
|
||||
@@ -62,16 +62,7 @@ class TrackableObject : public TrackableObjectBase,
|
||||
public:
|
||||
// Mark the JS object as destroyed.
|
||||
void MarkDestroyed() {
|
||||
v8::Local<v8::Object> wrapper = Wrappable<T>::GetWrapper();
|
||||
if (!wrapper.IsEmpty()) {
|
||||
wrapper->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDestroyed() {
|
||||
v8::Local<v8::Object> wrapper = Wrappable<T>::GetWrapper();
|
||||
return wrapper->InternalFieldCount() == 0 ||
|
||||
wrapper->GetAlignedPointerFromInternalField(0) == nullptr;
|
||||
Wrappable<T>::GetWrapper()->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
|
||||
// Finds out the TrackableObject from its ID in weak map.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user