Compare commits

..

62 Commits

Author SHA1 Message Date
Kevin Sawicki
39d33df350 Bump v1.3.15 2017-04-20 16:20:45 -07:00
Kevin Sawicki
f6b7924aba Merge pull request #9240 from electron/backport-remote-fixes
Backport 1.4 remote module bug fixes to 1.3
2017-04-20 14:49:50 -07:00
Kevin Sawicki
bb8be83c43 Disable media device specs on CI where they may not be available 2017-04-20 13:20:14 -07:00
Kevin Sawicki
24294749a0 Guard against missing members in setObjectMembers 2017-04-20 13:03:30 -07:00
Kevin Sawicki
a23c6e39a2 Don't load remote properties until they are accessed 2017-04-20 13:03:20 -07:00
Kevin Sawicki
4244a72f95 Allow spec to be run multiple times in same runner 2017-04-20 13:03:14 -07:00
Kevin Sawicki
daad31be1c Only set members when members exist 2017-04-20 13:03:09 -07:00
Kevin Sawicki
821ef92d87 Add failing spec for missing remote properties 2017-04-20 13:02:53 -07:00
Kevin Sawicki
049ea30964 Bump v1.3.14 2017-03-14 10:26:25 -07:00
Kevin Sawicki
9a3cf30bc9 Merge pull request #8922 from electron/v8-snapshot-patch
Upgrade libcc for v8 snapshot patch
2017-03-14 10:20:17 -07:00
Kevin Sawicki
2f4dc075e0 Upgrade libcc for v8 snapshot patch 2017-03-14 09:07:54 -07:00
Kevin Sawicki
93c4f90bee Bump v1.3.13 2016-12-06 14:12:51 -08:00
Kevin Sawicki
35be33a02f Merge pull request #8142 from electron/1-3-backports
Backports to 1.3
2016-12-06 14:12:25 -08:00
Kevin Sawicki
746ea3e045 Use getId in render-view-deleted fixture 2016-12-06 13:27:59 -08:00
Kevin Sawicki
1bd9fc1a09 Remove unused CallbacksRegistry.call method 2016-12-06 12:59:22 -08:00
Kevin Sawicki
ac54984763 Use 1.3 getId implementation to track render view deletesp 2016-12-06 12:57:42 -08:00
Kevin Sawicki
c300104cbd Upgrade libcc for Chrome 56 Linux key event fix 2016-12-06 09:59:00 -08:00
Kevin Sawicki
fc299189eb Update expected error message for missing remote object 2016-12-05 12:57:32 -08:00
Kevin Sawicki
5a768b3dfe Expose getProcessId from 1.4 for render-view-deleted fix 2016-12-05 10:23:12 -08:00
Kevin Sawicki
ab634e6c20 Use spread syntax instead of function apply 2016-12-05 10:03:13 -08:00
Kevin Sawicki
f5a6f290bc 🎨 Assign binding as const 2016-12-05 09:56:14 -08:00
Kevin Sawicki
3fe9762082 Implement window.alert/confirm/close in main process 2016-12-05 09:55:10 -08:00
Kevin Sawicki
cac7e9460d Pass args array instead of arguments object 2016-12-05 09:51:54 -08:00
Kevin Sawicki
d29bed026c Co-locate with other private methods 2016-12-05 09:51:35 -08:00
Kevin Sawicki
02dcc1bf3f Add spec for render-view-deleted issue 2016-12-05 09:49:15 -08:00
Kevin Sawicki
7a9a2c003c Don't clear until render view is deleted for process id 2016-12-05 09:48:11 -08:00
Kevin Sawicki
ab21a8b03a Log build type 2016-12-05 09:47:51 -08:00
Kevin Sawicki
0a587bc611 Add initial arm specific cibuild script 2016-12-05 09:47:41 -08:00
Kevin Sawicki
0037af51f3 Bump v1.3.12 2016-11-28 10:50:25 -08:00
Kevin Sawicki
435162af17 Remove unintended returns 2016-11-28 10:49:26 -08:00
Kevin Sawicki
64077277b1 Access URL through webContents directly 2016-11-28 10:48:52 -08:00
Kevin Sawicki
acb95f4614 Add more origin comparison specs 2016-11-28 10:48:41 -08:00
Kevin Sawicki
082b47fb85 window.opener location should be webview src URL 2016-11-28 10:48:31 -08:00
Kevin Sawicki
650867772a Bump v1.3.11 2016-11-23 13:20:57 -08:00
Kevin Sawicki
13d2fc9c81 Always use guest contents for canAccessWindow check 2016-11-23 11:45:05 -08:00
Kevin Sawicki
04a846a106 Add failing specs window.opener from <webview> opened window 2016-11-23 11:44:58 -08:00
Kevin Sawicki
cb84d26d20 Bump v1.3.10 2016-11-22 09:33:38 -08:00
Kevin Sawicki
78cf807cf0 Add initial spec for zoom level limits 2016-11-22 09:19:55 -08:00
Kevin Sawicki
f3de3334cf Add setZoomLevelLimits to planned breaking changes 2016-11-22 09:19:39 -08:00
Kevin Sawicki
a9d5a1d771 Add 2.0 comment about setZoomLevelLimits 2016-11-22 09:18:59 -08:00
Kevin Sawicki
2356577614 Expose setVisualZoomLevelLimits on webContents and <web-view> 2016-11-22 09:18:54 -08:00
Kevin Sawicki
94a5132b07 Document webFrame.setVisualZoomLevelLimits as public 2016-11-22 09:18:50 -08:00
Kevin Sawicki
dca200d918 Export a setVisualZoomLevelLimits method 2016-11-22 09:18:45 -08:00
Paul Betts
e86e7d699f 📝 2016-11-22 09:18:16 -08:00
Paul Betts
922fcfb3da Lint 2016-11-22 09:18:11 -08:00
Paul Betts
1d35151353 Add new method to set layout-based zoom level limit 2016-11-22 09:18:07 -08:00
Kevin Sawicki
cb9fdc45e6 Bump v1.3.9 2016-11-16 11:29:03 -08:00
Kevin Sawicki
2dafd845b9 Make scheme const 2016-11-16 11:29:03 -08:00
Kevin Sawicki
9017f90b57 Use sender.id instead of sender.webContents.id 2016-11-16 11:29:03 -08:00
Kevin Sawicki
b94638894e Don't log blocked messages when guestWindow is null 2016-11-16 11:29:03 -08:00
Kevin Sawicki
8a3288d791 Always call done callback in before block 2016-11-16 11:29:03 -08:00
Cheng Zhao
6f5336c63f Fix standard linting errors 2016-11-16 11:29:03 -08:00
Cheng Zhao
73c1fab423 Print error messages 2016-11-16 11:29:03 -08:00
Cheng Zhao
1e36ee918e Do permission check when calling guest window methods 2016-11-16 11:29:03 -08:00
Cheng Zhao
1f49da7a06 spec: Should check origin before accessing window.opener 2016-11-16 11:28:52 -08:00
Kevin Sawicki
037a458e1d Bump v1.3.8 2016-10-20 11:34:18 +09:00
Jacob Groundwater
03a274ee27 Fire a11y event on touch screens using screen readers 2016-10-18 13:52:05 +09:00
Paul Betts
c4bd516b77 Code Cleanup 2016-10-18 13:51:55 +09:00
Paul Betts
4c914c1277 Check harder before enabling Accessibility support 2016-10-18 13:51:34 +09:00
Cheng Zhao
e3688a8e9d Bump v1.3.7 2016-09-27 03:19:21 +00:00
Cheng Zhao
375534cf4a module search paths have changed 2016-09-27 03:00:08 +00:00
Cheng Zhao
397e5ad0ac Update to Node v6.5.0 2016-09-27 02:45:19 +00:00
1236 changed files with 48094 additions and 65733 deletions

View File

@@ -1,344 +0,0 @@
version: 2
jobs:
electron-linux-arm:
docker:
- image: electronbuilds/electron:0.0.3
environment:
TARGET_ARCH: arm
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-arm64:
docker:
- image: electronbuilds/electron:0.0.3
environment:
TARGET_ARCH: arm64
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-ia32:
docker:
- image: electronbuilds/electron:0.0.3
environment:
TARGET_ARCH: ia32
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-mips64el:
docker:
- image: electronbuilds/electron:0.0.3
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.3
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
build-arm64:
jobs:
- electron-linux-arm64
build-ia32:
jobs:
- electron-linux-ia32
build-x64:
jobs:
- electron-linux-x64
build-mips64el:
jobs:
- electron-linux-mips64el

View File

@@ -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$"

View File

@@ -1,2 +0,0 @@
*
!tools/xvfb-init.sh

21
.github/CODEOWNERS vendored
View File

@@ -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

View File

@@ -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 .
-->

29
.github/config.yml vendored
View File

@@ -1,29 +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 possiblec

25
.github/stale.yml vendored
View File

@@ -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!

53
.gitignore vendored
View File

@@ -1,47 +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/cross-gcc-4.9.3-n64-loongson-rc5.4
/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/download/
/vendor/llvm-build/
/vendor/llvm/
/vendor/node/deps/node-inspect/.npmrc
/vendor/npm/
/vendor/python_26/
/vendor/npm/
/vendor/llvm/
/vendor/llvm-build/
/vendor/.gclient
node_modules/
SHASUMS256.txt
*.xcodeproj
*.swp
*.pyc
*.VC.db
*.VC.VC.opendb
.vs/
.vscode/
*.vcxproj
*.vcxproj.user
*.vcxproj.filters
*.sln
debug.log
npm-debug.log

14
.gitmodules vendored
View File

@@ -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

View File

@@ -1 +1 @@
v8.2.1
v6.3.0

View File

@@ -1,6 +0,0 @@
{
"plugins": [
["remark-lint-code-block-style", "fenced"],
["remark-lint-fenced-code-flag"]
]
}

View File

@@ -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

View File

@@ -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/

View File

@@ -1,10 +1,12 @@
# 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
@@ -12,7 +14,6 @@ propose changes to this document in a pull request.
## Submitting Issues
### Creating Issues
* 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:
@@ -26,15 +27,6 @@ possible with your report. If you can, please include:
* Perform a [cursory search](https://github.com/electron/electron/issues?utf8=✓&q=is%3Aissue+)
to see if a similar issue has already been submitted
### 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!
## Submitting Pull Requests
* Include screenshots and animated GIFs in your pull request whenever possible.

View File

@@ -1,18 +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 --force-yes nodejs
# Install wget used by crash reporter
RUN apt-get install -y --force-yes wget
# Add xvfb init script
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb

View File

@@ -1,17 +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 --force-yes nodejs
# Install wget used by crash reporter
RUN apt-get install -y --force-yes wget
# 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
View File

@@ -0,0 +1,2 @@
* Electron version:
* Operating system:

44
Jenkinsfile vendored
View File

@@ -1,44 +0,0 @@
pipeline {
agent none
stages {
stage('Build') {
parallel {
stage('electron-osx-x64') {
agent {
label 'osx'
}
steps {
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 {
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()
}
}
}
}
}
}
}

View File

@@ -1,4 +1,4 @@
Copyright (c) 2013-2017 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

119
README.md
View File

@@ -1,110 +1,81 @@
[![Electron Logo](https://electronjs.org/images/electron-logo.svg)](https://electronjs.org)
[![Electron Logo](http://electron.atom.io/images/electron-logo.svg)](http://electron.atom.io/)
[![Travis Build Status](https://travis-ci.org/electron/electron.svg?branch=master)](https://travis-ci.org/electron/electron)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/bc56v83355fi3369/branch/master?svg=true)](https://ci.appveyor.com/project/electron-bot/electron/branch/master)
[![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron?type=dev)
[![Join the Electron Community on Slack](https://atom-slack.herokuapp.com/badge.svg)](https://atom-slack.herokuapp.com/)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/kvxe4byi7jcxbe26/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/electron)
[![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron#info=devDependencies)
[![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://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](https://electronjs.org/docs/tutorial/electron-versioning).
For more installation options and troubleshooting tips, see
[installation](https://electronjs.org/docs/tutorial/installation).
## 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)*
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).

View File

@@ -1,9 +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).

View File

@@ -20,6 +20,6 @@ branches:
only:
- master
# disable build and test phases
# disable build and test pahses
build: off
test: off

View File

@@ -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

View File

@@ -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);

View File

@@ -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[]);

View File

@@ -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);
}

View File

@@ -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,7 +34,7 @@
namespace {
const auto kRunAsNode = "ELECTRON_RUN_AS_NODE";
const char* kRunAsNode = "ELECTRON_RUN_AS_NODE";
bool IsEnvSet(const char* name) {
#if defined(OS_WIN)
@@ -55,39 +51,8 @@ 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);
~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
int argc = 0;
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
bool run_as_node = IsEnvSet(kRunAsNode);
@@ -95,43 +60,49 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
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);
}
}
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;
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;
@@ -139,32 +110,33 @@ 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[]) {
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));
}
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[]) {
int main(int argc, const char* argv[]) {
if (IsEnvSet(kRunAsNode)) {
return AtomInitializeICUandStartNode(argc, argv);
return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
}
return AtomMain(argc, argv);

View File

@@ -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"
@@ -31,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();
}
@@ -74,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);
@@ -102,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);
@@ -120,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.
@@ -153,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();
}

File diff suppressed because it is too large Load Diff

View File

@@ -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_

View File

@@ -7,16 +7,12 @@
#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/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"
@@ -46,25 +42,14 @@ int NodeMain(int argc, char *argv[]) {
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();
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);

View File

@@ -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,13 +19,13 @@ 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;
}
@@ -37,9 +35,9 @@ bool UvTaskRunner::RunsTasksOnCurrentThread() const {
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);

View File

@@ -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 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);
};

View File

@@ -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,21 +30,14 @@
#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/ssl_cert_request_info.h"
#include "ui/base/l10n/l10n_util.h"
@@ -54,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 {
@@ -307,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;
}
@@ -323,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")
@@ -375,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")
@@ -424,21 +377,9 @@ void OnClientCertificateSelected(
v8::Isolate* isolate,
std::shared_ptr<content::ClientCertificateDelegate> delegate,
mate::Arguments* args) {
if (args->Length() == 2) {
delegate->ContinueWithCertificate(nullptr);
return;
}
v8::Local<v8::Value> val;
args->GetNext(&val);
if (val->IsNull()) {
delegate->ContinueWithCertificate(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;
}
@@ -448,7 +389,7 @@ void OnClientCertificateSelected(
auto certs = net::X509Certificate::CreateCertificateListFromBytes(
data.c_str(), data.length(), net::X509Certificate::FORMAT_AUTO);
if (!certs.empty())
if (certs.size() > 0)
delegate->ContinueWithCertificate(certs[0].get());
}
@@ -474,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,
@@ -494,35 +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);
content::BrowserChildProcessObserver::Add(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);
}
@@ -531,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) {
@@ -550,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();
}
@@ -573,91 +490,43 @@ 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() {
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();
}
void App::OnCreateWindow(
const GURL& target_url,
const std::string& frame_name,
WindowOpenDisposition disposition,
const std::vector<std::string>& features,
const scoped_refptr<content::ResourceRequestBodyImpl>& body,
int render_process_id,
int render_frame_id) {
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 =
@@ -666,11 +535,7 @@ void App::OnCreateWindow(
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,
features,
body);
api_web_contents->OnCreateWindow(target_url, frame_name, disposition);
}
}
@@ -683,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",
@@ -696,7 +561,7 @@ 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(
@@ -720,65 +585,8 @@ void App::SelectClientCertificate(
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) {
@@ -788,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;
}
@@ -796,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;
}
@@ -821,7 +629,7 @@ std::string App::GetLocale() {
bool App::MakeSingleInstance(
const ProcessSingleton::NotificationCallback& callback) {
if (process_singleton_)
if (process_singleton_.get())
return false;
base::FilePath user_dir;
@@ -842,7 +650,7 @@ bool App::MakeSingleInstance(
}
void App::ReleaseSingleInstance() {
if (process_singleton_) {
if (process_singleton_.get()) {
process_singleton_->Cleanup();
process_singleton_.reset();
}
@@ -861,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);
}
@@ -890,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,
@@ -1010,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));
@@ -1171,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)
@@ -1181,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))
@@ -1197,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)
@@ -1211,22 +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)
.SetMethod("enableMixedSandbox", &App::EnableMixedSandbox)
// TODO(juturu): Remove in 2.0, deprecate before then with warnings
#if defined(OS_MACOSX)
.SetMethod("moveToApplicationsFolder", &App::MoveToApplicationsFolder)
.SetMethod("isInApplicationsFolder", &App::IsInApplicationsFolder)
#endif
.SetMethod("getAppMemoryInfo", &App::GetAppMetrics);
&App::DisableHardwareAcceleration);
}
} // namespace api

View File

@@ -5,24 +5,14 @@
#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"
@@ -44,45 +34,24 @@ 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,
const std::vector<std::string>& features,
const scoped_refptr<content::ResourceRequestBodyImpl>& body,
int render_process_id,
int render_frame_id);
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(
@@ -91,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;
@@ -113,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:
@@ -145,31 +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,
std::unique_ptr<content::ClientCertificateDelegate> delegate) 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,
@@ -183,25 +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(OS_WIN)
// Get the current Jump List settings.
@@ -217,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);
};

View File

@@ -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");
}
@@ -107,14 +87,16 @@ void AutoUpdater::SetFeedURL(const std::string& url, mate::Arguments* args) {
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

View File

@@ -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;

View File

@@ -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, &params)) {
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)

View File

@@ -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_

View File

@@ -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

View File

@@ -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

View File

@@ -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);
};

View File

@@ -9,14 +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 "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 {
@@ -44,23 +44,12 @@ 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());
v8::Local<v8::String> local_message =
v8::String::NewFromUtf8(isolate(), message.data());
v8::MaybeLocal<v8::Value> parsed_message = v8::JSON::Parse(
isolate()->GetCurrentContext(), local_message);
if (parsed_message.IsEmpty()) {
std::unique_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
if (!parsed_message->IsType(base::Value::TYPE_DICTIONARY))
return;
}
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
if (!mate::ConvertFromV8(isolate(), parsed_message.ToLocalChecked(),
dict.get())) {
return;
}
base::DictionaryValue* dict =
static_cast<base::DictionaryValue*>(parsed_message.get());
int id;
if (!dict->GetInteger("id", &id)) {
std::string method;
@@ -118,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;
}
@@ -147,7 +136,7 @@ void Debugger::SendCommand(mate::Arguments* args) {
std::string json_args;
base::JSONWriter::Write(request, &json_args);
agent_host_->DispatchProtocolMessage(this, json_args);
agent_host_->DispatchProtocolMessage(json_args);
}
// static

View File

@@ -4,15 +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 "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"
@@ -62,12 +61,10 @@ void DesktopCapturer::StartHandling(bool capture_window,
options.set_disable_effects(false);
#endif
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);
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)));

View File

@@ -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,27 +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));
return true;
}
};
} // namespace mate
namespace {
@@ -70,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) {
@@ -80,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);
}
}
@@ -129,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

View File

@@ -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

View File

@@ -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);

View File

@@ -176,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

View File

@@ -53,9 +53,9 @@ 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, bool async) = 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_;

View File

@@ -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,25 +19,15 @@ 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, bool async) override;
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
int32_t window_id, int x, int y, int positioning_item,
bool async);
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;
static void SendActionToFirstResponder(const std::string& action);
scoped_nsobject<AtomMenuController> menu_controller_;
// window ID -> open context menu
std::map<int32_t, scoped_nsobject<AtomMenuController>> popup_controllers_;
base::WeakPtrFactory<MenuMac> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MenuMac);
};

View File

@@ -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, bool async) {
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, async);
if (async)
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
else
popup.Run();
}
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
int32_t window_id, int x, int y, int positioning_item,
bool async) {
if (!native_window)
return;
brightray::InspectableWebContents* web_contents =
native_window->inspectable_web_contents();
if (!web_contents)
return;
auto close_callback = base::Bind(&MenuMac::ClosePopupAt,
weak_factory_.GetWeakPtr(), window_id);
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,33 +69,11 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
if (rightmostMenuPoint > screenRight)
position.x = position.x - [menu size].width;
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
if (async) {
[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;
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
} else {
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
close_callback.Run();
}
}
void MenuMac::ClosePopupAt(int32_t window_id) {
popup_controllers_.erase(window_id);
// Show the menu.
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
}
// static

View File

@@ -8,20 +8,17 @@
#include "atom/browser/unresponsive_suppressor.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, bool async) {
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
if (!native_window)
return;
@@ -41,20 +38,14 @@ void MenuViews::PopupAt(
location = gfx::Point(origin.x() + x, origin.y() + y);
}
int flags = MenuRunner::CONTEXT_MENU | MenuRunner::HAS_MNEMONICS;
if (async)
flags |= MenuRunner::ASYNC;
// 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::ClosePopupAt, weak_factory_.GetWeakPtr(), window_id);
menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner(
model(), flags, close_callback));
ignore_result(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()),
@@ -62,10 +53,6 @@ void MenuViews::PopupAt(
ui::MENU_SOURCE_MOUSE));
}
void MenuViews::ClosePopupAt(int32_t window_id) {
menu_runners_.erase(window_id);
}
// static
mate::WrappableBase* Menu::New(mate::Arguments* args) {
return new MenuViews(args->isolate(), args->GetThis());

View File

@@ -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,16 +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, bool async) override;
void ClosePopupAt(int32_t window_id) override;
void PopupAt(Window* window, int x, int y, int positioning_item) override;
private:
// 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);
};

View File

@@ -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)

View File

@@ -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_

View File

@@ -1,258 +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 "atom/common/node_includes.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"
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_);
}
}
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_;
}
base::string16 Notification::GetReplyPlaceholder() const {
return reply_placeholder_;
}
bool Notification::GetHasReply() const {
return has_reply_;
}
std::vector<brightray::NotificationAction> Notification::GetActions() const {
return actions_;
}
base::string16 Notification::GetSound() const {
return sound_;
}
// 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::SetReplyPlaceholder(const base::string16& new_placeholder) {
reply_placeholder_ = new_placeholder;
}
void Notification::SetHasReply(bool new_has_reply) {
has_reply_ = new_has_reply;
}
void Notification::SetActions(
const std::vector<brightray::NotificationAction>& actions) {
actions_ = actions;
}
void Notification::SetSound(const base::string16& new_sound) {
sound_ = new_sound;
}
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_;
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("replyPlaceholder", &Notification::GetReplyPlaceholder,
&Notification::SetReplyPlaceholder)
.SetProperty("hasReply", &Notification::GetHasReply,
&Notification::SetHasReply)
.SetProperty("actions", &Notification::GetActions,
&Notification::SetActions)
.SetProperty("sound", &Notification::GetSound,
&Notification::SetSound);
}
} // 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)

View File

@@ -1,94 +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;
base::string16 GetReplyPlaceholder() const;
bool GetHasReply() const;
std::vector<brightray::NotificationAction> GetActions() const;
base::string16 GetSound() 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 SetReplyPlaceholder(const base::string16& new_reply_placeholder);
void SetHasReply(bool new_has_reply);
void SetActions(const std::vector<brightray::NotificationAction>& actions);
void SetSound(const base::string16& sound);
private:
base::string16 title_;
base::string16 subtitle_;
base::string16 body_;
gfx::Image icon_;
base::string16 icon_path_;
bool has_icon_ = false;
bool silent_ = false;
base::string16 reply_placeholder_;
bool has_reply_ = false;
std::vector<brightray::NotificationAction> actions_;
base::string16 sound_;
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_

View File

@@ -5,12 +5,11 @@
#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 {
@@ -44,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);
}

View File

@@ -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();

View File

@@ -9,7 +9,7 @@
#include <memory>
#include "atom/browser/api/trackable_object.h"
#include "device/power_save_blocker/power_save_blocker.h"
#include "content/public/browser/power_save_blocker.h"
#include "native_mate/handle.h"
namespace mate {
@@ -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);

View File

@@ -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,

View File

@@ -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:
@@ -78,10 +77,6 @@ class Protocol : public mate::TrackableObject<Protocol> {
net::URLRequestJob* MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
if (!request->initiator().has_value()) {
// Don't intercept this request as it was created by `net.request`.
return nullptr;
}
RequestJob* request_job = new RequestJob(request, network_delegate);
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
return request_job;

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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

View File

@@ -29,13 +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/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"
@@ -51,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;
@@ -63,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) {
@@ -110,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) {
@@ -153,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,
@@ -204,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 {
@@ -234,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 =
@@ -267,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)
@@ -284,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(
@@ -372,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) {
@@ -417,33 +330,12 @@ 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>());
}
} // 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);
@@ -464,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();
@@ -496,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(),
@@ -593,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,
@@ -633,55 +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)));
}
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_);
@@ -753,18 +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)
.SetProperty("cookies", &Session::Cookies)
.SetProperty("protocol", &Session::Protocol)
.SetProperty("webRequest", &Session::WebRequest);
@@ -794,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);
}

View File

@@ -8,7 +8,6 @@
#include <string>
#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"
@@ -74,13 +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);
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);

View File

@@ -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)
@@ -66,13 +63,9 @@ void SystemPreferences::BuildPrototype(
.SetMethod("unsubscribeLocalNotification",
&SystemPreferences::UnsubscribeLocalNotification)
.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);
}

View File

@@ -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,14 +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 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);
@@ -97,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);
};

View File

@@ -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,112 +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::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"];

View File

@@ -1,190 +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_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) {
std::ostringstream stream;
stream << std::hex << color;
std::string hexColor = stream.str();
return hexColor.substr(2) + hexColor.substr(0, 2);
}
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

View File

@@ -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"
@@ -72,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
@@ -86,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) {
@@ -124,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");
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -12,13 +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_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 {
@@ -29,10 +26,6 @@ namespace brightray {
class InspectableWebContents;
}
namespace content {
class ResourceRequestBodyImpl;
}
namespace mate {
class Arguments;
class Dictionary;
@@ -42,8 +35,6 @@ namespace atom {
struct SetSizeParams;
class AtomBrowserContext;
class AtomJavaScriptDialogManager;
class WebContentsZoomController;
class WebViewGuestDelegate;
namespace api {
@@ -54,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)
@@ -68,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(
@@ -78,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);
@@ -98,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();
@@ -116,16 +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);
v8::Local<v8::Value> GetNativeView() const;
// Print current page as PDF.
void PrintToPDF(const base::DictionaryValue& setting,
@@ -188,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,
@@ -203,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::ResourceRequestBodyImpl>& 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);
@@ -216,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);
@@ -227,38 +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;
@@ -274,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;
@@ -307,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(
@@ -329,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;
@@ -343,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:
@@ -357,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;
@@ -381,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_;

View File

@@ -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;
}
};

View File

@@ -3,12 +3,10 @@
// 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/node_includes.h"
#include "atom/common/options_switches.h"
#include "content/public/browser/browser_context.h"
#include "native_mate/dictionary.h"
@@ -26,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);
}

View File

@@ -5,21 +5,18 @@
#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/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)) {
// 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();
@@ -144,7 +103,6 @@ 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.
@@ -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) {
@@ -190,7 +148,7 @@ void Window::WillDestroyNativeObject() {
}
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)) {
@@ -551,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() {
@@ -604,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);
}
@@ -632,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();
}
@@ -668,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) {
@@ -788,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)
@@ -828,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()) {
@@ -871,40 +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()) {
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->web_contents()->SetOwnerWindow(nullptr);
}
browser_view_.Reset();
}
bool Window::IsModal() const {
return window_->is_modal();
}
@@ -923,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() {
@@ -1017,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)
@@ -1062,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)
@@ -1093,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)
@@ -1113,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)

View File

@@ -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();
@@ -145,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);
@@ -154,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();
@@ -170,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);
@@ -183,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();
@@ -204,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)
@@ -214,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_|.
@@ -238,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_;

View File

@@ -79,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...);
}

View File

@@ -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(), 0);
}
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

View File

@@ -1,132 +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) {
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_

View File

@@ -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,32 +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();
{
SkAutoLockPixels lock(bitmap);
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

View File

@@ -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);

View File

@@ -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

View File

@@ -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.

View File

@@ -4,58 +4,28 @@
#include "atom/browser/atom_access_token_store.h"
#include <string>
#include <utility>
#include "atom/browser/atom_browser_context.h"
#include "atom/common/google_api_key.h"
#include "base/environment.h"
#include "content/public/browser/browser_thread.h"
#include "device/geolocation/geolocation_provider.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_context_getter.h"
using content::BrowserThread;
#include "content/public/browser/geolocation_provider.h"
namespace atom {
namespace internal {
namespace {
class GeoURLRequestContextGetter : public net::URLRequestContextGetter {
public:
net::URLRequestContext* GetURLRequestContext() override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!url_request_context_.get()) {
net::URLRequestContextBuilder builder;
builder.set_proxy_config_service(
net::ProxyService::CreateSystemProxyConfigService(
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)));
url_request_context_ = builder.Build();
}
return url_request_context_.get();
}
// Notice that we just combined the api key with the url together here, because
// if we use the standard {url: key} format Chromium would override our key with
// the predefined one in common.gypi of libchromiumcontent, which is empty.
const char* kGeolocationProviderURL =
"https://www.googleapis.com/geolocation/v1/geolocate?key="
GOOGLEAPIS_API_KEY;
scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
const override {
return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
}
} // namespace
private:
friend class atom::AtomAccessTokenStore;
GeoURLRequestContextGetter() {}
~GeoURLRequestContextGetter() override {}
std::unique_ptr<net::URLRequestContext> url_request_context_;
DISALLOW_COPY_AND_ASSIGN(GeoURLRequestContextGetter);
};
} // namespace internal
AtomAccessTokenStore::AtomAccessTokenStore()
: request_context_getter_(new internal::GeoURLRequestContextGetter) {
device::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
AtomAccessTokenStore::AtomAccessTokenStore() {
content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
}
AtomAccessTokenStore::~AtomAccessTokenStore() {
@@ -63,23 +33,35 @@ AtomAccessTokenStore::~AtomAccessTokenStore() {
void AtomAccessTokenStore::LoadAccessTokens(
const LoadAccessTokensCallback& callback) {
std::unique_ptr<base::Environment> env(base::Environment::Create());
std::string api_key;
if (!env->GetVar("GOOGLE_API_KEY", &api_key))
api_key = GOOGLEAPIS_API_KEY;
// Equivalent to access_token_map[kGeolocationProviderURL].
// Somehow base::string16 is causing compilation errors when used in a pair
// of std::map on Linux, this can work around it.
device::AccessTokenStore::AccessTokenMap access_token_map;
std::pair<GURL, base::string16> token_pair;
token_pair.first = GURL(GOOGLEAPIS_ENDPOINT + api_key);
access_token_map.insert(token_pair);
callback.Run(access_token_map, request_context_getter_.get());
content::BrowserThread::PostTaskAndReply(
content::BrowserThread::UI,
FROM_HERE,
base::Bind(&AtomAccessTokenStore::GetRequestContextOnUIThread, this),
base::Bind(&AtomAccessTokenStore::RespondOnOriginatingThread,
this, callback));
}
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
const base::string16& access_token) {
}
void AtomAccessTokenStore::GetRequestContextOnUIThread() {
auto browser_context = AtomBrowserContext::From("", false);
request_context_getter_ = browser_context->GetRequestContext();
}
void AtomAccessTokenStore::RespondOnOriginatingThread(
const LoadAccessTokensCallback& callback) {
// Equivelent to access_token_map[kGeolocationProviderURL].
// Somehow base::string16 is causing compilation errors when used in a pair
// of std::map on Linux, this can work around it.
AccessTokenMap access_token_map;
std::pair<GURL, base::string16> token_pair;
token_pair.first = GURL(kGeolocationProviderURL);
access_token_map.insert(token_pair);
callback.Run(access_token_map, request_context_getter_.get());
request_context_getter_ = nullptr;
}
} // namespace atom

View File

@@ -5,27 +5,27 @@
#ifndef ATOM_BROWSER_ATOM_ACCESS_TOKEN_STORE_H_
#define ATOM_BROWSER_ATOM_ACCESS_TOKEN_STORE_H_
#include "device/geolocation/access_token_store.h"
#include "content/public/browser/access_token_store.h"
namespace atom {
namespace internal {
class GeoURLRequestContextGetter;
}
class AtomAccessTokenStore : public device::AccessTokenStore {
class AtomAccessTokenStore : public content::AccessTokenStore {
public:
AtomAccessTokenStore();
~AtomAccessTokenStore();
// device::AccessTokenStore:
// content::AccessTokenStore:
void LoadAccessTokens(
const LoadAccessTokensCallback& callback) override;
void SaveAccessToken(const GURL& server_url,
const base::string16& access_token) override;
private:
scoped_refptr<internal::GeoURLRequestContextGetter> request_context_getter_;
void GetRequestContextOnUIThread();
void RespondOnOriginatingThread(const LoadAccessTokensCallback& callback);
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore);
};

View File

@@ -1,138 +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/atom_blob_reader.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_reader.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "atom/common/node_includes.h"
using content::BrowserThread;
namespace atom {
namespace {
void FreeNodeBufferData(char* data, void* hint) {
delete[] data;
}
void RunCallbackInUI(
const AtomBlobReader::CompletionCallback& callback,
char* blob_data,
int size) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
if (blob_data) {
v8::Local<v8::Value> buffer = node::Buffer::New(isolate,
blob_data, static_cast<size_t>(size), &FreeNodeBufferData, nullptr)
.ToLocalChecked();
callback.Run(buffer);
} else {
callback.Run(v8::Null(isolate));
}
}
} // namespace
AtomBlobReader::AtomBlobReader(
content::ChromeBlobStorageContext* blob_context,
storage::FileSystemContext* file_system_context)
: blob_context_(blob_context),
file_system_context_(file_system_context) {
}
AtomBlobReader::~AtomBlobReader() {
}
void AtomBlobReader::StartReading(
const std::string& uuid,
const AtomBlobReader::CompletionCallback& completion_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
auto blob_data_handle =
blob_context_->context()->GetBlobDataFromUUID(uuid);
auto callback = base::Bind(&RunCallbackInUI,
completion_callback);
if (!blob_data_handle) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(callback, nullptr, 0));
return;
}
auto blob_reader = blob_data_handle->CreateReader(
file_system_context_.get(),
BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get());
BlobReadHelper* blob_read_helper =
new BlobReadHelper(std::move(blob_reader), callback);
blob_read_helper->Read();
}
AtomBlobReader::BlobReadHelper::BlobReadHelper(
std::unique_ptr<storage::BlobReader> blob_reader,
const BlobReadHelper::CompletionCallback& callback)
: blob_reader_(std::move(blob_reader)),
completion_callback_(callback) {
}
AtomBlobReader::BlobReadHelper::~BlobReadHelper() {
}
void AtomBlobReader::BlobReadHelper::Read() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
storage::BlobReader::Status size_status = blob_reader_->CalculateSize(
base::Bind(&AtomBlobReader::BlobReadHelper::DidCalculateSize,
base::Unretained(this)));
if (size_status != storage::BlobReader::Status::IO_PENDING)
DidCalculateSize(net::OK);
}
void AtomBlobReader::BlobReadHelper::DidCalculateSize(int result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (result != net::OK) {
DidReadBlobData(nullptr, 0);
return;
}
uint64_t total_size = blob_reader_->total_size();
int bytes_read = 0;
scoped_refptr<net::IOBuffer> blob_data =
new net::IOBuffer(static_cast<size_t>(total_size));
auto callback = base::Bind(&AtomBlobReader::BlobReadHelper::DidReadBlobData,
base::Unretained(this),
base::RetainedRef(blob_data));
storage::BlobReader::Status read_status = blob_reader_->Read(
blob_data.get(),
total_size,
&bytes_read,
callback);
if (read_status != storage::BlobReader::Status::IO_PENDING)
callback.Run(bytes_read);
}
void AtomBlobReader::BlobReadHelper::DidReadBlobData(
const scoped_refptr<net::IOBuffer>& blob_data,
int size) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
char* data = new char[size];
memcpy(data, blob_data->data(), size);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(completion_callback_, data, size));
delete this;
}
} // namespace atom

View File

@@ -1,80 +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_ATOM_BLOB_READER_H_
#define ATOM_BROWSER_ATOM_BLOB_READER_H_
#include <string>
#include "base/callback.h"
namespace content {
class ChromeBlobStorageContext;
}
namespace net {
class IOBuffer;
}
namespace storage {
class BlobDataHandle;
class BlobReader;
class FileSystemContext;
}
namespace v8 {
template <class T>
class Local;
class Value;
}
namespace atom {
// A class to keep track of the blob context. All methods,
// except Ctor are expected to be called on IO thread.
class AtomBlobReader {
public:
using CompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
AtomBlobReader(content::ChromeBlobStorageContext* blob_context,
storage::FileSystemContext* file_system_context);
~AtomBlobReader();
void StartReading(
const std::string& uuid,
const AtomBlobReader::CompletionCallback& callback);
private:
// A self-destroyed helper class to read the blob data.
// Must be accessed on IO thread.
class BlobReadHelper {
public:
using CompletionCallback = base::Callback<void(char*, int)>;
BlobReadHelper(std::unique_ptr<storage::BlobReader> blob_reader,
const BlobReadHelper::CompletionCallback& callback);
~BlobReadHelper();
void Read();
private:
void DidCalculateSize(int result);
void DidReadBlobData(const scoped_refptr<net::IOBuffer>& blob_data,
int bytes_read);
std::unique_ptr<storage::BlobReader> blob_reader_;
BlobReadHelper::CompletionCallback completion_callback_;
DISALLOW_COPY_AND_ASSIGN(BlobReadHelper);
};
scoped_refptr<content::ChromeBlobStorageContext> blob_context_;
scoped_refptr<storage::FileSystemContext> file_system_context_;
DISALLOW_COPY_AND_ASSIGN(AtomBlobReader);
};
} // namespace atom
#endif // ATOM_BROWSER_ATOM_BLOB_READER_H_

View File

@@ -10,12 +10,12 @@
#include "atom/browser/api/atom_api_app.h"
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/atom_access_token_store.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_quota_permission_context.h"
#include "atom/browser/atom_resource_dispatcher_host_delegate.h"
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
#include "atom/browser/child_web_contents_tracker.h"
#include "atom/browser/native_window.h"
#include "atom/browser/web_contents_permission_helper.h"
#include "atom/browser/web_contents_preferences.h"
@@ -30,7 +30,6 @@
#include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
#include "chrome/browser/renderer_host/pepper/widevine_cdm_message_filter.h"
#include "chrome/browser/speech/tts_message_filter.h"
#include "content/common/resource_request_body_impl.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/render_process_host.h"
@@ -38,9 +37,6 @@
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/web_preferences.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "ppapi/host/ppapi_host.h"
@@ -80,82 +76,15 @@ AtomBrowserClient::~AtomBrowserClient() {
content::WebContents* AtomBrowserClient::GetWebContentsFromProcessID(
int process_id) {
// If the process is a pending process, we should use the web contents
// for the frame host passed into OverrideSiteInstanceForNavigation.
if (base::ContainsKey(pending_processes_, process_id))
return pending_processes_[process_id];
// If the process is a pending process, we should use the old one.
if (ContainsKey(pending_processes_, process_id))
process_id = pending_processes_[process_id];
// Certain render process will be created with no associated render view,
// for example: ServiceWorker.
return WebContentsPreferences::GetWebContentsFromProcessID(process_id);
}
bool AtomBrowserClient::ShouldCreateNewSiteInstance(
content::RenderFrameHost* render_frame_host,
content::BrowserContext* browser_context,
content::SiteInstance* current_instance,
const GURL& url) {
if (url.SchemeIs(url::kJavaScriptScheme))
// "javacript:" scheme should always use same SiteInstance
return false;
int process_id = current_instance->GetProcess()->GetID();
if (!IsRendererSandboxed(process_id)) {
if (!RendererUsesNativeWindowOpen(process_id)) {
// non-sandboxed renderers without native window.open should always create
// a new SiteInstance
return true;
}
auto web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
if (!ChildWebContentsTracker::IsChildWebContents(web_contents)) {
// Root WebContents should always create new process to make sure
// native addons are loaded correctly after reload / navigation.
// (Non-root WebContents opened by window.open() should try to
// reuse process to allow synchronous cross-window scripting.)
return true;
}
}
// Create new a SiteInstance if navigating to a different site.
auto src_url = current_instance->GetSiteURL();
return
!content::SiteInstance::IsSameWebSite(browser_context, src_url, url) &&
// `IsSameWebSite` doesn't seem to work for some URIs such as `file:`,
// handle these scenarios by comparing only the site as defined by
// `GetSiteForURL`.
content::SiteInstance::GetSiteForURL(browser_context, url) != src_url;
}
void AtomBrowserClient::AddProcessPreferences(
int process_id, AtomBrowserClient::ProcessPreferences prefs) {
base::AutoLock auto_lock(process_preferences_lock_);
process_preferences_[process_id] = prefs;
}
void AtomBrowserClient::RemoveProcessPreferences(int process_id) {
base::AutoLock auto_lock(process_preferences_lock_);
process_preferences_.erase(process_id);
}
bool AtomBrowserClient::IsRendererSandboxed(int process_id) {
base::AutoLock auto_lock(process_preferences_lock_);
auto it = process_preferences_.find(process_id);
return it != process_preferences_.end() && it->second.sandbox;
}
bool AtomBrowserClient::RendererUsesNativeWindowOpen(int process_id) {
base::AutoLock auto_lock(process_preferences_lock_);
auto it = process_preferences_.find(process_id);
return it != process_preferences_.end() && it->second.native_window_open;
}
bool AtomBrowserClient::RendererDisablesPopups(int process_id) {
base::AutoLock auto_lock(process_preferences_lock_);
auto it = process_preferences_.find(process_id);
return it != process_preferences_.end() && it->second.disable_popups;
}
void AtomBrowserClient::RenderProcessWillLaunch(
content::RenderProcessHost* host) {
int process_id = host->GetID();
@@ -163,17 +92,6 @@ void AtomBrowserClient::RenderProcessWillLaunch(
host->AddFilter(new TtsMessageFilter(process_id, host->GetBrowserContext()));
host->AddFilter(
new WidevineCdmMessageFilter(process_id, host->GetBrowserContext()));
content::WebContents* web_contents = GetWebContentsFromProcessID(process_id);
ProcessPreferences process_prefs;
process_prefs.sandbox = WebContentsPreferences::IsSandboxed(web_contents);
process_prefs.native_window_open
= WebContentsPreferences::UsesNativeWindowOpen(web_contents);
process_prefs.disable_popups
= WebContentsPreferences::DisablePopups(web_contents);
AddProcessPreferences(host->GetID(), process_prefs);
// ensure the ProcessPreferences is removed later
host->AddObserver(this);
}
content::SpeechRecognitionManagerDelegate*
@@ -181,6 +99,10 @@ content::SpeechRecognitionManagerDelegate*
return new AtomSpeechRecognitionManagerDelegate;
}
content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
return new AtomAccessTokenStore;
}
void AtomBrowserClient::OverrideWebkitPrefs(
content::RenderViewHost* host, content::WebPreferences* prefs) {
prefs->javascript_enabled = true;
@@ -196,6 +118,7 @@ void AtomBrowserClient::OverrideWebkitPrefs(
prefs->allow_universal_access_from_file_urls = true;
prefs->allow_file_access_from_file_urls = true;
prefs->experimental_webgl_enabled = true;
prefs->allow_displaying_insecure_content = false;
prefs->allow_running_insecure_content = false;
// Custom preferences of guest page.
@@ -208,7 +131,6 @@ std::string AtomBrowserClient::GetApplicationLocale() {
}
void AtomBrowserClient::OverrideSiteInstanceForNavigation(
content::RenderFrameHost* render_frame_host,
content::BrowserContext* browser_context,
content::SiteInstance* current_instance,
const GURL& url,
@@ -218,8 +140,8 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
return;
}
if (!ShouldCreateNewSiteInstance(render_frame_host, browser_context,
current_instance, url))
// Restart renderer process for all navigations except "javacript:" scheme.
if (url.SchemeIs(url::kJavaScriptScheme))
return;
scoped_refptr<content::SiteInstance> site_instance =
@@ -233,32 +155,24 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&Noop, base::RetainedRef(site_instance)));
// Remember the original web contents for the pending renderer process.
// Remember the original renderer process of the pending renderer process.
auto current_process = current_instance->GetProcess();
auto pending_process = (*new_instance)->GetProcess();
pending_processes_[pending_process->GetID()] =
content::WebContents::FromRenderFrameHost(render_frame_host);;
pending_processes_[pending_process->GetID()] = current_process->GetID();
// Clear the entry in map when process ends.
pending_process->AddObserver(this);
current_process->AddObserver(this);
}
void AtomBrowserClient::AppendExtraCommandLineSwitches(
base::CommandLine* command_line,
int process_id) {
// Make sure we're about to launch a known executable
base::FilePath child_path;
PathService::Get(content::CHILD_PROCESS_EXE, &child_path);
CHECK(base::MakeAbsoluteFilePath(command_line->GetProgram()) == child_path);
std::string process_type =
command_line->GetSwitchValueASCII(::switches::kProcessType);
if (process_type != ::switches::kRendererProcess)
std::string process_type = command_line->GetSwitchValueASCII("type");
if (process_type != "renderer")
return;
// Copy following switches to child process.
static const char* const kCommonSwitchNames[] = {
switches::kStandardSchemes,
switches::kEnableSandbox,
switches::kSecureSchemes
};
command_line->CopySwitchesFrom(
*base::CommandLine::ForCurrentProcess(),
@@ -278,15 +192,12 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
}
#endif
if (delegate_) {
auto app_path = static_cast<api::App*>(delegate_)->GetAppPath();
command_line->AppendSwitchPath(switches::kAppPath, app_path);
}
content::WebContents* web_contents = GetWebContentsFromProcessID(process_id);
if (web_contents)
WebContentsPreferences::AppendExtraCommandLineSwitches(
web_contents, command_line);
if (!web_contents)
return;
WebContentsPreferences::AppendExtraCommandLineSwitches(
web_contents, command_line);
}
void AtomBrowserClient::DidCreatePpapiPlugin(
@@ -309,13 +220,13 @@ void AtomBrowserClient::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) {
if (delegate_) {
delegate_->AllowCertificateError(
web_contents, cert_error, ssl_info, request_url,
resource_type, overridable, strict_enforcement,
expired_previous_decision, callback);
expired_previous_decision, callback, request);
}
}
@@ -337,41 +248,24 @@ void AtomBrowserClient::ResourceDispatcherHostCreated() {
}
bool AtomBrowserClient::CanCreateWindow(
int opener_render_process_id,
int opener_render_frame_id,
const GURL& opener_url,
const GURL& opener_top_level_frame_url,
const GURL& source_origin,
content::mojom::WindowContainerType container_type,
WindowContainerType container_type,
const std::string& frame_name,
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::ResourceRequestBodyImpl>& body,
const blink::WebWindowFeatures& features,
bool user_gesture,
bool opener_suppressed,
content::ResourceContext* context,
int render_process_id,
int opener_render_view_id,
int opener_render_frame_id,
bool* no_javascript_access) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (IsRendererSandboxed(opener_render_process_id)) {
*no_javascript_access = false;
return true;
}
if (RendererUsesNativeWindowOpen(opener_render_process_id)) {
if (RendererDisablesPopups(opener_render_process_id)) {
// <webview> without allowpopups attribute should return
// null from window.open calls
return false;
} else {
*no_javascript_access = false;
return true;
}
}
if (delegate_) {
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(&api::App::OnCreateWindow,
@@ -379,9 +273,7 @@ bool AtomBrowserClient::CanCreateWindow(
target_url,
frame_name,
disposition,
additional_features,
body,
opener_render_process_id,
render_process_id,
opener_render_frame_id));
}
@@ -395,7 +287,6 @@ void AtomBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
additional_schemes->insert(additional_schemes->end(),
schemes_list.begin(),
schemes_list.end());
additional_schemes->push_back(content::kChromeDevToolsScheme);
}
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
@@ -426,27 +317,11 @@ void AtomBrowserClient::WebNotificationAllowed(
void AtomBrowserClient::RenderProcessHostDestroyed(
content::RenderProcessHost* host) {
int process_id = host->GetID();
pending_processes_.erase(process_id);
RemoveProcessPreferences(process_id);
}
void AtomBrowserClient::RenderProcessReady(content::RenderProcessHost* host) {
render_process_host_pids_[host->GetID()] = base::GetProcId(host->GetHandle());
if (delegate_) {
static_cast<api::App*>(delegate_)->RenderProcessReady(host);
}
}
void AtomBrowserClient::RenderProcessExited(content::RenderProcessHost* host,
base::TerminationStatus status,
int exit_code) {
auto host_pid = render_process_host_pids_.find(host->GetID());
if (host_pid != render_process_host_pids_.end()) {
if (delegate_) {
static_cast<api::App*>(delegate_)->RenderProcessDisconnected(
host_pid->second);
for (const auto& entry : pending_processes_) {
if (entry.first == process_id || entry.second == process_id) {
pending_processes_.erase(entry.first);
break;
}
render_process_host_pids_.erase(host_pid);
}
}

View File

@@ -6,7 +6,6 @@
#define ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
#include <map>
#include <set>
#include <string>
#include <vector>
@@ -50,11 +49,11 @@ class AtomBrowserClient : public brightray::BrowserClient,
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
content::SpeechRecognitionManagerDelegate*
CreateSpeechRecognitionManagerDelegate() override;
content::AccessTokenStore* CreateAccessTokenStore() override;
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
content::WebPreferences* prefs) override;
std::string GetApplicationLocale() override;
void OverrideSiteInstanceForNavigation(
content::RenderFrameHost* render_frame_host,
content::BrowserContext* browser_context,
content::SiteInstance* current_instance,
const GURL& dest_url,
@@ -72,31 +71,29 @@ class AtomBrowserClient : public brightray::BrowserClient,
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,
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
void ResourceDispatcherHostCreated() override;
bool CanCreateWindow(
int opener_render_process_id,
int opener_render_frame_id,
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::ResourceRequestBodyImpl>& body,
bool user_gesture,
bool opener_suppressed,
content::ResourceContext* context,
bool* no_javascript_access) override;
bool CanCreateWindow(const GURL& opener_url,
const GURL& opener_top_level_frame_url,
const GURL& source_origin,
WindowContainerType container_type,
const std::string& frame_name,
const GURL& target_url,
const content::Referrer& referrer,
WindowOpenDisposition disposition,
const blink::WebWindowFeatures& features,
bool user_gesture,
bool opener_suppressed,
content::ResourceContext* context,
int render_process_id,
int opener_render_view_id,
int opener_render_frame_id,
bool* no_javascript_access) override;
void GetAdditionalAllowedSchemesForFileSystem(
std::vector<std::string>* schemes) override;
@@ -109,33 +106,10 @@ class AtomBrowserClient : public brightray::BrowserClient,
// content::RenderProcessHostObserver:
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
void RenderProcessReady(content::RenderProcessHost* host) override;
void RenderProcessExited(content::RenderProcessHost* host,
base::TerminationStatus status,
int exit_code) override;
private:
bool ShouldCreateNewSiteInstance(content::RenderFrameHost* render_frame_host,
content::BrowserContext* browser_context,
content::SiteInstance* current_instance,
const GURL& dest_url);
struct ProcessPreferences {
bool sandbox;
bool native_window_open;
bool disable_popups;
};
void AddProcessPreferences(int process_id, ProcessPreferences prefs);
void RemoveProcessPreferences(int process_id);
bool IsRendererSandboxed(int process_id);
bool RendererUsesNativeWindowOpen(int process_id);
bool RendererDisablesPopups(int process_id);
// pending_render_process => web contents.
std::map<int, content::WebContents*> pending_processes_;
std::map<int, ProcessPreferences> process_preferences_;
std::map<int, base::ProcessId> render_process_host_pids_;
base::Lock process_preferences_lock_;
// pending_render_process => current_render_process.
std::map<int, int> pending_processes_;
std::unique_ptr<AtomResourceDispatcherHostDelegate>
resource_dispatcher_host_delegate_;

View File

@@ -5,15 +5,14 @@
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/atom_blob_reader.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/atom_download_manager_delegate.h"
#include "atom/browser/atom_permission_manager.h"
#include "atom/browser/browser.h"
#include "atom/browser/net/about_protocol_handler.h"
#include "atom/browser/net/asar/asar_protocol_handler.h"
#include "atom/browser/net/atom_cert_verifier.h"
#include "atom/browser/net/atom_network_delegate.h"
#include "atom/browser/net/atom_ssl_config_service.h"
#include "atom/browser/net/atom_url_request_job_factory.h"
#include "atom/browser/net/http_protocol_handler.h"
#include "atom/browser/web_view_manager.h"
@@ -31,9 +30,7 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/user_agent.h"
#include "net/ftp/ftp_network_layer.h"
@@ -67,12 +64,11 @@ std::string RemoveWhitespace(const std::string& str) {
} // namespace
AtomBrowserContext::AtomBrowserContext(const std::string& partition,
bool in_memory,
const base::DictionaryValue& options)
AtomBrowserContext::AtomBrowserContext(
const std::string& partition, bool in_memory,
const base::DictionaryValue& options)
: brightray::BrowserContext(partition, in_memory),
network_delegate_(new AtomNetworkDelegate),
cookie_delegate_(new AtomCookieDelegate) {
network_delegate_(new AtomNetworkDelegate) {
// Construct user agent string.
Browser* browser = Browser::Get();
std::string name = RemoveWhitespace(browser->GetName());
@@ -108,10 +104,6 @@ net::NetworkDelegate* AtomBrowserContext::CreateNetworkDelegate() {
return network_delegate_;
}
net::CookieMonsterDelegate* AtomBrowserContext::CreateCookieDelegate() {
return cookie_delegate();
}
std::string AtomBrowserContext::GetUserAgent() {
return user_agent_;
}
@@ -128,8 +120,6 @@ AtomBrowserContext::CreateURLRequestJobFactory(
}
protocol_handlers->clear();
job_factory->SetProtocolHandler(url::kAboutScheme,
base::WrapUnique(new AboutProtocolHandler));
job_factory->SetProtocolHandler(
url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
job_factory->SetProtocolHandler(
@@ -153,7 +143,8 @@ AtomBrowserContext::CreateURLRequestJobFactory(
url_request_context_getter()->GetURLRequestContext()->host_resolver();
job_factory->SetProtocolHandler(
url::kFtpScheme,
net::FtpProtocolHandler::Create(host_resolver));
base::WrapUnique(new net::FtpProtocolHandler(
new net::FtpNetworkLayer(host_resolver))));
return std::move(job_factory);
}
@@ -190,9 +181,12 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() {
return permission_manager_.get();
}
std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier(
brightray::RequireCTDelegate* ct_delegate) {
return base::WrapUnique(new AtomCertVerifier(ct_delegate));
std::unique_ptr<net::CertVerifier> AtomBrowserContext::CreateCertVerifier() {
return base::WrapUnique(new AtomCertVerifier);
}
net::SSLConfigService* AtomBrowserContext::CreateSSLConfigService() {
return new AtomSSLConfigService;
}
std::vector<std::string> AtomBrowserContext::GetCookieableSchemes() {
@@ -213,19 +207,6 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
}
AtomBlobReader* AtomBrowserContext::GetBlobReader() {
if (!blob_reader_.get()) {
content::ChromeBlobStorageContext* blob_context =
content::ChromeBlobStorageContext::GetFor(this);
storage::FileSystemContext* file_system_context =
content::BrowserContext::GetStoragePartition(
this, nullptr)->GetFileSystemContext();
blob_reader_.reset(new AtomBlobReader(blob_context,
file_system_context));
}
return blob_reader_.get();
}
// static
scoped_refptr<AtomBrowserContext> AtomBrowserContext::From(
const std::string& partition, bool in_memory,

View File

@@ -8,13 +8,10 @@
#include <string>
#include <vector>
#include "atom/browser/net/atom_cookie_delegate.h"
#include "brightray/browser/browser_context.h"
#include "net/cookies/cookie_monster.h"
namespace atom {
class AtomBlobReader;
class AtomDownloadManagerDelegate;
class AtomNetworkDelegate;
class AtomPermissionManager;
@@ -33,14 +30,13 @@ class AtomBrowserContext : public brightray::BrowserContext {
// brightray::URLRequestContextGetter::Delegate:
net::NetworkDelegate* CreateNetworkDelegate() override;
net::CookieMonsterDelegate* CreateCookieDelegate() override;
std::string GetUserAgent() override;
std::unique_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
content::ProtocolHandlerMap* protocol_handlers) override;
net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
const base::FilePath& base_path) override;
std::unique_ptr<net::CertVerifier> CreateCertVerifier(
brightray::RequireCTDelegate* ct_delegate) override;
std::unique_ptr<net::CertVerifier> CreateCertVerifier() override;
net::SSLConfigService* CreateSSLConfigService() override;
std::vector<std::string> GetCookieableSchemes() override;
// content::BrowserContext:
@@ -51,11 +47,7 @@ class AtomBrowserContext : public brightray::BrowserContext {
// brightray::BrowserContext:
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
AtomBlobReader* GetBlobReader();
AtomNetworkDelegate* network_delegate() const { return network_delegate_; }
AtomCookieDelegate* cookie_delegate() const {
return cookie_delegate_.get();
}
protected:
AtomBrowserContext(const std::string& partition, bool in_memory,
@@ -66,13 +58,11 @@ class AtomBrowserContext : public brightray::BrowserContext {
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
std::unique_ptr<WebViewManager> guest_manager_;
std::unique_ptr<AtomPermissionManager> permission_manager_;
std::unique_ptr<AtomBlobReader> blob_reader_;
std::string user_agent_;
bool use_cache_;
// Managed by brightray::BrowserContext.
AtomNetworkDelegate* network_delegate_;
scoped_refptr<AtomCookieDelegate> cookie_delegate_;
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
};

View File

@@ -4,57 +4,34 @@
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/api/atom_api_app.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/atom_access_token_store.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_web_ui_controller_factory.h"
#include "atom/browser/bridge_task_runner.h"
#include "atom/browser/browser.h"
#include "atom/browser/javascript_environment.h"
#include "atom/browser/node_debugger.h"
#include "atom/common/api/atom_bindings.h"
#include "atom/common/asar/asar_util.h"
#include "atom/common/node_bindings.h"
#include "atom/common/node_includes.h"
#include "base/command_line.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/browser_process.h"
#include "content/public/browser/child_process_security_policy.h"
#include "device/geolocation/geolocation_delegate.h"
#include "device/geolocation/geolocation_provider.h"
#include "v8/include/v8-debug.h"
#if defined(USE_X11)
#include "chrome/browser/ui/libgtkui/gtk_util.h"
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
#endif
namespace atom {
namespace {
// A provider of Geolocation services to override AccessTokenStore.
class AtomGeolocationDelegate : public device::GeolocationDelegate {
public:
AtomGeolocationDelegate() = default;
scoped_refptr<device::AccessTokenStore> CreateAccessTokenStore() final {
return new AtomAccessTokenStore();
}
private:
DISALLOW_COPY_AND_ASSIGN(AtomGeolocationDelegate);
};
template<typename T>
void Erase(T* container, typename T::iterator iter) {
container->erase(iter);
}
} // namespace
// static
AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr;
@@ -62,8 +39,8 @@ AtomBrowserMainParts::AtomBrowserMainParts()
: fake_browser_process_(new BrowserProcess),
exit_code_(nullptr),
browser_(new Browser),
node_bindings_(NodeBindings::Create(NodeBindings::BROWSER)),
atom_bindings_(new AtomBindings(uv_default_loop())),
node_bindings_(NodeBindings::Create(true)),
atom_bindings_(new AtomBindings),
gc_timer_(true, true) {
DCHECK(!self_) << "Cannot have two AtomBrowserMainParts";
self_ = this;
@@ -73,7 +50,6 @@ AtomBrowserMainParts::AtomBrowserMainParts()
}
AtomBrowserMainParts::~AtomBrowserMainParts() {
asar::ClearArchives();
// Leak the JavascriptEnvironment on exit.
// This is to work around the bug that V8 would be waiting for background
// tasks to finish on exit, while somehow it waits forever in Electron, more
@@ -130,16 +106,18 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
node_bindings_->Initialize();
// Support the "--debug" switch.
node_debugger_.reset(new NodeDebugger(js_env_->isolate()));
// Create the global environment.
node::Environment* env =
node_bindings_->CreateEnvironment(js_env_->context());
node_env_.reset(new NodeEnvironment(env));
// Enable support for v8 inspector
node_debugger_.reset(new NodeDebugger(env));
node_debugger_->Start();
// Make sure node can get correct environment when debugging.
if (node_debugger_->IsRunning())
env->AssignToContext(v8::Debug::GetDebugContext());
// Add Electron extended APIs.
// Add atom-shell extended APIs.
atom_bindings_->BindTo(js_env_->isolate(), env->process_object());
// Load everything.
@@ -167,15 +145,12 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
base::Bind(&v8::Isolate::LowMemoryNotification,
base::Unretained(js_env_->isolate())));
content::WebUIControllerFactory::RegisterFactory(
AtomWebUIControllerFactory::GetInstance());
brightray::BrowserMainParts::PreMainMessageLoopRun();
bridge_task_runner_->MessageLoopIsReady();
bridge_task_runner_ = nullptr;
#if defined(USE_X11)
libgtkui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
libgtk2ui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
#endif
#if !defined(OS_MACOSX)
@@ -184,8 +159,6 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
std::unique_ptr<base::DictionaryValue> empty_info(new base::DictionaryValue);
Browser::Get()->DidFinishLaunching(*empty_info);
#endif
Browser::Get()->PreMainMessageLoopRun();
}
bool AtomBrowserMainParts::MainMessageLoopRun(int* result_code) {
@@ -198,8 +171,6 @@ void AtomBrowserMainParts::PostMainMessageLoopStart() {
#if defined(OS_POSIX)
HandleShutdownSignals();
#endif
device::GeolocationProvider::SetGeolocationDelegate(
new AtomGeolocationDelegate());
}
void AtomBrowserMainParts::PostMainMessageLoopRun() {

View File

@@ -22,7 +22,6 @@ class Browser;
class JavascriptEnvironment;
class NodeBindings;
class NodeDebugger;
class NodeEnvironment;
class BridgeTaskRunner;
class AtomBrowserMainParts : public brightray::BrowserMainParts {
@@ -82,7 +81,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
std::unique_ptr<JavascriptEnvironment> js_env_;
std::unique_ptr<NodeBindings> node_bindings_;
std::unique_ptr<AtomBindings> atom_bindings_;
std::unique_ptr<NodeEnvironment> node_env_;
std::unique_ptr<NodeDebugger> node_debugger_;
base::Timer gc_timer_;

View File

@@ -60,7 +60,7 @@ void AtomDownloadManagerDelegate::CreateDownloadPath(
std::string(),
suggested_filename,
mime_type,
"download");
std::string());
if (!base::PathExists(default_download_path))
base::CreateDirectory(default_download_path);
@@ -90,12 +90,10 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
base::FilePath path;
GetItemSavePath(item, &path);
// Show save dialog if save path was not set already on item
file_dialog::DialogSettings settings;
settings.parent_window = window;
settings.force_detached = window->is_offscreen_dummy();
settings.title = item->GetURL().spec();
settings.default_path = default_path;
if (path.empty() && file_dialog::ShowSaveDialog(settings, &path)) {
if (path.empty() && file_dialog::ShowSaveDialog(window, item->GetURL().spec(),
"", default_path,
file_dialog::Filters(),
&path)) {
// Remember the last selected download directory.
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
download_manager_->GetBrowserContext());
@@ -116,10 +114,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
// If user cancels the file save dialog, run the callback with empty FilePath.
callback.Run(path,
content::DownloadItem::TARGET_DISPOSITION_PROMPT,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
path.empty() ?
content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED :
content::DOWNLOAD_INTERRUPT_REASON_NONE);
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path);
}
void AtomDownloadManagerDelegate::Shutdown() {
@@ -136,8 +131,7 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
callback.Run(download->GetForcedFilePath(),
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
download->GetForcedFilePath(),
content::DOWNLOAD_INTERRUPT_REASON_NONE);
download->GetForcedFilePath());
return true;
}
@@ -148,7 +142,7 @@ bool AtomDownloadManagerDelegate::DetermineDownloadTarget(
callback.Run(save_path,
content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
save_path, content::DOWNLOAD_INTERRUPT_REASON_NONE);
save_path);
return true;
}

Some files were not shown because too many files have changed in this diff Show More