mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
94 Commits
v8.5.3
...
v4.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3846a1b663 | ||
|
|
08d80295d7 | ||
|
|
127ad9252e | ||
|
|
f43920e436 | ||
|
|
62c0f842ae | ||
|
|
acea9d1576 | ||
|
|
8e31642530 | ||
|
|
91533574c7 | ||
|
|
eef05cba6a | ||
|
|
7e63ca603d | ||
|
|
2b7f854a83 | ||
|
|
d07115e1dc | ||
|
|
c268fd872c | ||
|
|
2ac5f33cf8 | ||
|
|
deac580f1a | ||
|
|
a5fa18767a | ||
|
|
3e4d77109a | ||
|
|
081af07892 | ||
|
|
d1c48456e9 | ||
|
|
282829c076 | ||
|
|
6e759e0852 | ||
|
|
74bd220436 | ||
|
|
d16304f2fb | ||
|
|
ac1bfb2337 | ||
|
|
436b9a2ee1 | ||
|
|
9625faeede | ||
|
|
8d4573f289 | ||
|
|
041773c6bc | ||
|
|
a51ad1f956 | ||
|
|
3a4c20b154 | ||
|
|
b2d4c519f8 | ||
|
|
86e35e6221 | ||
|
|
17b80ebb9c | ||
|
|
a313aaea72 | ||
|
|
11ebf5c990 | ||
|
|
daa0be56c9 | ||
|
|
e026e9aa82 | ||
|
|
fdfcd3cf12 | ||
|
|
f8450daa14 | ||
|
|
f68d59d1a3 | ||
|
|
b8bc25665f | ||
|
|
9a5915995e | ||
|
|
4844af489a | ||
|
|
fd4d0320cd | ||
|
|
57153ead89 | ||
|
|
e113ec78ec | ||
|
|
8a90bbf7ba | ||
|
|
cd1c9c8a45 | ||
|
|
6ba390e68a | ||
|
|
b77f41420b | ||
|
|
372fa4cdd0 | ||
|
|
435ca8cff3 | ||
|
|
f30c382d41 | ||
|
|
f88a06df84 | ||
|
|
96a4fce100 | ||
|
|
85b0f254be | ||
|
|
9ac4611075 | ||
|
|
6c18908333 | ||
|
|
f2ca4c11c8 | ||
|
|
7ab6073cdb | ||
|
|
b57d12583f | ||
|
|
3cd67db581 | ||
|
|
630bc64f2f | ||
|
|
a2b4458046 | ||
|
|
fd205a1577 | ||
|
|
1ff102e54a | ||
|
|
d525083d75 | ||
|
|
f1a8483349 | ||
|
|
5fbf1f9a54 | ||
|
|
838f108821 | ||
|
|
df70487f80 | ||
|
|
0c09199f77 | ||
|
|
6281e4ef0b | ||
|
|
abbf9c3ca3 | ||
|
|
b4f4ce1b84 | ||
|
|
5f83e07748 | ||
|
|
203b41fe2e | ||
|
|
c16b34539a | ||
|
|
446275c85a | ||
|
|
1adce9413a | ||
|
|
3ee697b258 | ||
|
|
6e30d855ba | ||
|
|
948fc6f612 | ||
|
|
8c2d16f031 | ||
|
|
11486b99a4 | ||
|
|
ebb2c53c3d | ||
|
|
8094f1a3f0 | ||
|
|
b7f20f1878 | ||
|
|
e9e0219ae8 | ||
|
|
24b809f2bc | ||
|
|
cfbb22b380 | ||
|
|
f9ae1aa999 | ||
|
|
f1ec2237e7 | ||
|
|
35df516e28 |
2068
.circleci/config.yml
2068
.circleci/config.yml
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
mkdir -p ~/.ssh
|
||||
echo "|1|B3r+7aO0/x90IdefihIjxIoJrrk=|OJddGDfhbuLFc1bUyy84hhIw57M= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|
||||
|1|rGlEvW55DtzNZp+pzw9gvyOyKi4=|LLWr+7qlkAlw3YGGVfLHHxB/kR0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts
|
||||
@@ -1,3 +1,4 @@
|
||||
*
|
||||
!tools/xvfb-init.sh
|
||||
!tools/run-electron.sh
|
||||
!build/install-build-deps.sh
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# These env vars are only necessary for creating Electron releases.
|
||||
# See docs/development/releasing.md
|
||||
|
||||
APPVEYOR_CLOUD_TOKEN=
|
||||
APPVEYOR_TOKEN=
|
||||
CIRCLE_TOKEN=
|
||||
ELECTRON_GITHUB_TOKEN=
|
||||
VSTS_TOKEN=
|
||||
@@ -1,36 +1,12 @@
|
||||
{
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"rules": {
|
||||
"semi": ["error", "always"],
|
||||
"no-var": "error",
|
||||
"no-unused-vars": 0,
|
||||
"no-global-assign": 0,
|
||||
"guard-for-in": 2,
|
||||
"@typescript-eslint/no-unused-vars": ["error", {
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": false
|
||||
}],
|
||||
"prefer-const": ["error", {
|
||||
"destructuring": "all"
|
||||
}],
|
||||
"node/no-deprecated-api": 0
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.js",
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
11
.gitattributes
vendored
11
.gitattributes
vendored
@@ -1,14 +1,3 @@
|
||||
# `git apply` and friends don't understand CRLF, even on windows. Force those
|
||||
# files to be checked out with LF endings even if core.autocrlf is true.
|
||||
*.patch text eol=lf
|
||||
patches/**/.patches merge=union
|
||||
|
||||
# Source code and markdown files should always use LF as line ending.
|
||||
*.cc text eol=lf
|
||||
*.mm text eol=lf
|
||||
*.h text eol=lf
|
||||
*.js text eol=lf
|
||||
*.ts text eol=lf
|
||||
*.py text eol=lf
|
||||
*.ps1 text eol=lf
|
||||
*.md text eol=lf
|
||||
|
||||
29
.github/CODEOWNERS
vendored
29
.github/CODEOWNERS
vendored
@@ -3,20 +3,19 @@
|
||||
# https://help.github.com/articles/about-codeowners
|
||||
# https://git-scm.com/docs/gitignore
|
||||
|
||||
# Most stuff in here is owned by the Community & Safety WG...
|
||||
/.github/* @electron/wg-community
|
||||
# Everything that falls through the cracks:
|
||||
* @electron/reviewers
|
||||
|
||||
# ...except the Admin WG maintains this file.
|
||||
/.github/CODEOWNERS @electron/wg-admin
|
||||
# filename patterns
|
||||
*browser_view* @electron/browserview
|
||||
*notification* @electron/notifications
|
||||
*pdf* @electron/printing
|
||||
*printing* @electron/printing
|
||||
*updater* @electron/updater
|
||||
|
||||
# Upgrades WG
|
||||
/patches/ @electron/wg-upgrades
|
||||
DEPS @electron/wg-upgrades
|
||||
|
||||
# Docs & Tooling WG
|
||||
/default_app/ @electron/wg-docs-tools
|
||||
/docs/ @electron/wg-docs-tools
|
||||
|
||||
# Releases WG
|
||||
/npm/ @electron/wg-releases
|
||||
/script/release @electron/wg-releases
|
||||
# directories
|
||||
/.github/ @electron/electrocats
|
||||
/default_app/ @electron/docs
|
||||
/docs/ @electron/docs
|
||||
/docs-translations/ @electron/i18n
|
||||
/npm/ @electron/electrocats
|
||||
38
.github/ISSUE_TEMPLATE.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<!--
|
||||
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
|
||||
-->
|
||||
|
||||
* Output of `node_modules/.bin/electron --version`:
|
||||
* Operating System (Platform and Version):
|
||||
|
||||
<!-- If this used to work -->
|
||||
* Output of `node_modules/.bin/electron --version` on last known working Electron version (if applicable):
|
||||
|
||||
### 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 .
|
||||
|
||||
-->
|
||||
54
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
54
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -4,55 +4,29 @@ about: Create a report to help us improve Electron
|
||||
|
||||
---
|
||||
|
||||
<!-- As an open source project with a dedicated but small maintainer team, it can sometimes take a long time for issues to be addressed so please be patient and we will get back to you as soon as we can.
|
||||
-->
|
||||
* Output of `node_modules/.bin/electron --version`:
|
||||
* Operating System (Platform and Version):
|
||||
* Output of `node_modules/.bin/electron --version` on last known working Electron version (if applicable):
|
||||
|
||||
### Preflight Checklist
|
||||
<!-- Please ensure you've completed the following steps by replacing [ ] with [x]-->
|
||||
**Expected Behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
* [ ] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
|
||||
* [ ] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
|
||||
* [ ] I have searched the issue tracker for an issue that matches the one I want to file, without success.
|
||||
**Actual behavior**
|
||||
A clear and concise description of what actually happened.
|
||||
|
||||
### Issue Details
|
||||
**To Reproduce**
|
||||
Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run.
|
||||
|
||||
* **Electron Version:**
|
||||
* <!-- (output of `node_modules/.bin/electron --version`) e.g. 4.0.3 -->
|
||||
* **Operating System:**
|
||||
* <!-- (Platform and Version) e.g. macOS 10.13.6 / Windows 10 (1803) / Ubuntu 18.04 x64 -->
|
||||
* **Last Known Working Electron version:**
|
||||
* <!-- (if applicable) e.g. 3.1.0 -->
|
||||
You can fork [electron-quick-start](https://github.com/electron/electron-quick-start) and include a link to the branch with your changes.
|
||||
|
||||
### Expected Behavior
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
### Actual Behavior
|
||||
<!-- A clear and concise description of what actually happened. -->
|
||||
|
||||
### To Reproduce
|
||||
<!--
|
||||
Your best chance of getting this bug looked at quickly is to provide an example.
|
||||
-->
|
||||
|
||||
<!--
|
||||
For bugs that can be encapsulated in a small experiment, you can use Electron Fiddle (https://github.com/electron/fiddle) to publish your example to a GitHub Gist and link it your bug report.
|
||||
-->
|
||||
|
||||
<!--
|
||||
If Fiddle is insufficient to produce an example, please provide an example REPOSITORY that can be cloned and run. You can fork electron-quick-start (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.
|
||||
```sh
|
||||
$ git clone $YOUR_URL -b $BRANCH
|
||||
$ npm install
|
||||
$ npm start || electron .
|
||||
```
|
||||
-->
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
### Screenshots
|
||||
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||
|
||||
### Additional Information
|
||||
<!-- Add any other context about the problem here. -->
|
||||
**Additional Information**
|
||||
Add any other context about the problem here.
|
||||
|
||||
26
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
26
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
@@ -4,24 +4,14 @@ about: Suggest an idea for Electron
|
||||
|
||||
---
|
||||
|
||||
<!-- As an open source project with a dedicated but small maintainer team, it can sometimes take a long time for issues to be addressed so please be patient and we will get back to you as soon as we can.
|
||||
-->
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is.
|
||||
|
||||
### Preflight Checklist
|
||||
<!-- Please ensure you've completed the following steps by replacing [ ] with [x]-->
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
* [ ] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
|
||||
* [ ] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
|
||||
* [ ] I have searched the issue tracker for a feature request that matches the one I want to file, without success.
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
### Problem Description
|
||||
<!-- Is your feature request related to a problem? Please add a clear and concise description of what the problem is. -->
|
||||
|
||||
### Proposed Solution
|
||||
<!-- Describe the solution you'd like in a clear and concise manner -->
|
||||
|
||||
### Alternatives Considered
|
||||
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
|
||||
|
||||
### Additional Information
|
||||
<!-- Add any other context about the problem here. -->
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
|
||||
13
.github/ISSUE_TEMPLATE/mac-app-store-private-api-rejection.md
vendored
Normal file
13
.github/ISSUE_TEMPLATE/mac-app-store-private-api-rejection.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
name: Mac App Store Private API Rejection
|
||||
about: Your app was rejected from the Mac App Store for using private API's
|
||||
|
||||
---
|
||||
|
||||
* Electron Version:
|
||||
|
||||
**Rejection Email**
|
||||
Paste the contents of your rejection email here, censoring any private information such as app names.
|
||||
|
||||
**Additional Information**
|
||||
Add any other context about the problem here.
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
name: Mac App Store Private API Rejection
|
||||
about: Your app was rejected from the Mac App Store for using private API's
|
||||
|
||||
---
|
||||
|
||||
<!-- As an open source project with a dedicated but small maintainer team, it can sometimes take a long time for issues to be addressed so please be patient and we will get back to you as soon as we can.
|
||||
-->
|
||||
|
||||
### Preflight Checklist
|
||||
<!-- Please ensure you've completed the following steps by replacing [ ] with [x]-->
|
||||
|
||||
* [ ] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
|
||||
* [ ] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
|
||||
|
||||
### Issue Details
|
||||
|
||||
* **Electron Version:**
|
||||
* <!-- (output of `node_modules/.bin/electron --version`) e.g. 4.0.3 -->
|
||||
|
||||
### Rejection Email
|
||||
<!-- Paste the contents of your rejection email here, censoring any private information such as app names.-->
|
||||
|
||||
### Additional Information
|
||||
<!-- Add any other context about the problem here. -->
|
||||
@@ -4,7 +4,6 @@ about: Do not create an issue for security reports, send an email to security@el
|
||||
|
||||
---
|
||||
|
||||
### Notice
|
||||
Do not create an issue for security reports, send an email to:
|
||||
|
||||
**DO NOT** create an issue for security reports.
|
||||
Send an email to: **security@electronjs.org**.
|
||||
security@electronjs.org
|
||||
11
.github/PULL_REQUEST_TEMPLATE.md
vendored
11
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,4 +1,4 @@
|
||||
#### Description of Change
|
||||
##### Description of Change
|
||||
<!--
|
||||
Thank you for your Pull Request. Please provide a description above and review
|
||||
the requirements below.
|
||||
@@ -6,7 +6,7 @@ the requirements below.
|
||||
Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
#### Checklist
|
||||
##### Checklist
|
||||
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->
|
||||
|
||||
- [ ] PR description included and stakeholders cc'd
|
||||
@@ -14,8 +14,9 @@ Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTIN
|
||||
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/master/docs/development/testing.md)
|
||||
- [ ] relevant documentation is changed or added
|
||||
- [ ] PR title follows semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines)
|
||||
- [ ] [PR release notes](https://github.com/electron/clerk/blob/master/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/master/README.md#examples).
|
||||
|
||||
#### Release Notes
|
||||
|
||||
Notes: <!-- Please add a one-line description for app developers to read in the release notes, or `no-notes` if no notes relevant to app developers. Examples and help on special cases: https://github.com/electron/clerk/blob/master/README.md#examples -->
|
||||
##### Release Notes
|
||||
<!-- Used to describe release notes for future release versions. See https://github.com/electron/clerk/blob/master/README.md for details. -->
|
||||
|
||||
Notes: <!-- One-line Change Summary Here-->
|
||||
18
.github/config.yml
vendored
18
.github/config.yml
vendored
@@ -1,3 +1,13 @@
|
||||
# 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).
|
||||
|
||||
# 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! 💖
|
||||
@@ -26,7 +36,11 @@ newPRWelcomeComment: |
|
||||
firstPRMergeComment: >
|
||||
Congrats on merging your first pull request! 🎉🎉🎉
|
||||
|
||||
# Users authorized to run manual trop backports
|
||||
# Configuration for trop - https://github.com/codebytere/trop
|
||||
|
||||
watchedProject:
|
||||
name: Backports
|
||||
|
||||
authorizedUsers:
|
||||
- alexeykuzmin
|
||||
- ckerr
|
||||
@@ -34,6 +48,6 @@ authorizedUsers:
|
||||
- deepak1556
|
||||
- jkleinsc
|
||||
- MarshallOfSound
|
||||
- miniak
|
||||
- nitsakh
|
||||
- nornagon
|
||||
- zcbenz
|
||||
|
||||
25
.github/stale.yml
vendored
Normal file
25
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# 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!
|
||||
18
.gitignore
vendored
18
.gitignore
vendored
@@ -16,6 +16,13 @@
|
||||
*.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/
|
||||
/dist/
|
||||
/external_binaries/
|
||||
/out/
|
||||
@@ -37,7 +44,7 @@
|
||||
/vendor/pyyaml
|
||||
node_modules/
|
||||
SHASUMS256.txt
|
||||
**/package-lock.json
|
||||
**/yarn.lock
|
||||
compile_commands.json
|
||||
.envrc
|
||||
|
||||
@@ -56,12 +63,3 @@ spec/.hash
|
||||
|
||||
# Eslint Cache
|
||||
.eslintcache
|
||||
|
||||
# Generated native addon files
|
||||
/spec-main/fixtures/native-addon/echo/build/
|
||||
|
||||
# If someone runs tsc this is where stuff will end up
|
||||
ts-gen
|
||||
|
||||
# Used to accelerate CI builds
|
||||
.depshash
|
||||
|
||||
31
.vsts/lint.yml
Normal file
31
.vsts/lint.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
pool:
|
||||
vmImage: 'Ubuntu 16.04'
|
||||
|
||||
steps:
|
||||
- bash: |
|
||||
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
|
||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git "${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
|
||||
echo "##vso[task.setvariable variable=PATH]$PATH:${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
|
||||
displayName: Setup Depot Tools
|
||||
|
||||
- bash: |
|
||||
chromium_revision="$(grep -A1 chromium_version DEPS | tr -d '\n' | cut -d\' -f4)"
|
||||
buildtools_revision="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep buildtools_revision -A1 | tr -d '\n' | cut -d\' -f4)"
|
||||
|
||||
git clone https://chromium.googlesource.com/chromium/buildtools "${AGENT_TEMPDIRECTORY}/buildtools"
|
||||
(cd "${AGENT_TEMPDIRECTORY}/buildtools" && git checkout "$buildtools_revision")
|
||||
echo "##vso[task.setvariable variable=CHROMIUM_BUILDTOOLS_PATH]$AGENT_TEMPDIRECTORY/buildtools"
|
||||
|
||||
download_from_google_storage --bucket chromium-gn -s "${AGENT_TEMPDIRECTORY}/buildtools/linux64/gn.sha1"
|
||||
displayName: Download gn binary
|
||||
|
||||
- bash: |
|
||||
# gn.py tries to find a gclient root folder starting from the current dir.
|
||||
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
|
||||
touch .gclient
|
||||
# Another option would be to checkout "buildtools" inside the Electron checkout,
|
||||
# but then we would lint its contents (at least gn format), and it doesn't pass it.
|
||||
|
||||
npm install
|
||||
npm run lint
|
||||
displayName: Run Lint
|
||||
@@ -20,23 +20,13 @@ Issues are created [here](https://github.com/electron/electron/issues/new).
|
||||
* [Triaging a Bug Report](https://electronjs.org/docs/development/issues#triaging-a-bug-report)
|
||||
* [Resolving a Bug Report](https://electronjs.org/docs/development/issues#resolving-a-bug-report)
|
||||
|
||||
### Issue Closure
|
||||
|
||||
Bug reports will be closed if the issue has been inactive and the latest affected version no longer receives support. At the moment, Electron maintains its three latest major versions, with a new major version being released every 12 weeks. (For more information on Electron's release cadence, see [this blog post](https://electronjs.org/blog/12-week-cadence).)
|
||||
|
||||
_If an issue has been closed and you still feel it's relevant, feel free to ping a maintainer or add a comment!_
|
||||
|
||||
### Languages
|
||||
|
||||
We accept issues in *any* language.
|
||||
When an issue is posted in a language besides English, it is acceptable and encouraged to post an English-translated copy as a reply.
|
||||
Anyone may post the translated reply.
|
||||
In most cases, a quick pass through translation software is sufficient.
|
||||
Having the original text _as well as_ the translation can help mitigate translation errors.
|
||||
|
||||
Responses to posted issues may or may not be in the original language.
|
||||
|
||||
**Please note** that using non-English as an attempt to circumvent our [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) will be an immediate, and possibly indefinite, ban from the project.
|
||||
### 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!
|
||||
|
||||
## [Pull Requests](https://electronjs.org/docs/development/pull-requests)
|
||||
|
||||
@@ -67,4 +57,4 @@ See [Coding Style](https://electronjs.org/docs/development/coding-style) for inf
|
||||
## Further Reading
|
||||
|
||||
For more in-depth guides on developing Electron, see
|
||||
[/docs/development](/docs/development/README.md)
|
||||
[/docs/development](/docs/development/README.md)
|
||||
57
DEPS
57
DEPS
@@ -5,17 +5,14 @@ gclient_gn_args = [
|
||||
'checkout_android_native_support',
|
||||
'checkout_libaom',
|
||||
'checkout_nacl',
|
||||
'checkout_oculus_sdk',
|
||||
'checkout_openxr'
|
||||
'checkout_oculus_sdk'
|
||||
]
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'80.0.3987.163',
|
||||
'69.0.3497.106',
|
||||
'node_version':
|
||||
'v12.13.0',
|
||||
'nan_version':
|
||||
'2ee313aaca52e2b478965ac50eb5082520380d1b',
|
||||
'4d44266b78256449dd6ae86e419e3ec07257b569',
|
||||
|
||||
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
|
||||
'pyyaml_version': '3.12',
|
||||
@@ -24,13 +21,9 @@ vars = {
|
||||
'boto_git': 'https://github.com/boto',
|
||||
'chromium_git': 'https://chromium.googlesource.com',
|
||||
'electron_git': 'https://github.com/electron',
|
||||
'nodejs_git': 'https://github.com/nodejs',
|
||||
'requests_git': 'https://github.com/kennethreitz',
|
||||
'yaml_git': 'https://github.com/yaml',
|
||||
|
||||
# KEEP IN SYNC WITH utils.js FILE
|
||||
'yarn_version': '1.15.2',
|
||||
|
||||
# To be able to build clean Chromium from sources.
|
||||
'apply_patches': True,
|
||||
|
||||
@@ -40,7 +33,6 @@ vars = {
|
||||
# To allow in-house builds to checkout those manually.
|
||||
'checkout_chromium': True,
|
||||
'checkout_node': True,
|
||||
'checkout_nan': True,
|
||||
|
||||
# It's only needed to parse the native tests configurations.
|
||||
'checkout_pyyaml': False,
|
||||
@@ -48,9 +40,6 @@ vars = {
|
||||
# Python "requests" module is used for releases only.
|
||||
'checkout_requests': False,
|
||||
|
||||
# To allow running hooks without parsing the DEPS tree
|
||||
'process_deps': True,
|
||||
|
||||
# It is always needed for normal Electron builds,
|
||||
# but might be impossible for custom in-house builds.
|
||||
'download_external_binaries': True,
|
||||
@@ -61,8 +50,6 @@ vars = {
|
||||
True,
|
||||
'checkout_oculus_sdk':
|
||||
False,
|
||||
'checkout_openxr':
|
||||
False,
|
||||
'build_with_chromium':
|
||||
True,
|
||||
'checkout_android':
|
||||
@@ -74,39 +61,35 @@ vars = {
|
||||
deps = {
|
||||
'src': {
|
||||
'url': (Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
|
||||
'condition': 'checkout_chromium and process_deps',
|
||||
},
|
||||
'src/third_party/nan': {
|
||||
'url': (Var("nodejs_git")) + '/nan.git@' + (Var("nan_version")),
|
||||
'condition': 'checkout_nan and process_deps',
|
||||
'condition': 'checkout_chromium',
|
||||
},
|
||||
'src/third_party/electron_node': {
|
||||
'url': (Var("nodejs_git")) + '/node.git@' + (Var("node_version")),
|
||||
'condition': 'checkout_node and process_deps',
|
||||
'url': (Var("electron_git")) + '/node.git@' + (Var("node_version")),
|
||||
'condition': 'checkout_node',
|
||||
},
|
||||
'src/electron/vendor/pyyaml': {
|
||||
'url': (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
|
||||
'condition': 'checkout_pyyaml and process_deps',
|
||||
'condition': 'checkout_pyyaml',
|
||||
},
|
||||
'src/electron/vendor/boto': {
|
||||
'url': Var('boto_git') + '/boto.git' + '@' + Var('boto_version'),
|
||||
'condition': 'checkout_boto and process_deps',
|
||||
'condition': 'checkout_boto',
|
||||
},
|
||||
'src/electron/vendor/requests': {
|
||||
'url': Var('requests_git') + '/requests.git' + '@' + Var('requests_version'),
|
||||
'condition': 'checkout_requests and process_deps',
|
||||
'condition': 'checkout_requests',
|
||||
},
|
||||
}
|
||||
|
||||
hooks = [
|
||||
{
|
||||
'name': 'patch_chromium',
|
||||
'condition': '(checkout_chromium and apply_patches) and process_deps',
|
||||
'condition': 'checkout_chromium and apply_patches',
|
||||
'pattern': 'src/electron',
|
||||
'action': [
|
||||
'python',
|
||||
'src/electron/script/apply_all_patches.py',
|
||||
'src/electron/patches/config.json',
|
||||
'src/electron/patches/common/config.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -114,8 +97,10 @@ hooks = [
|
||||
'pattern': 'src/electron/script/update-external-binaries.py',
|
||||
'condition': 'download_external_binaries',
|
||||
'action': [
|
||||
'python3',
|
||||
'python',
|
||||
'src/electron/script/update-external-binaries.py',
|
||||
'--root-url=http://github.com/electron/electron-frameworks/releases/download',
|
||||
'--version=v1.4.0',
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -124,33 +109,31 @@ hooks = [
|
||||
'action': [
|
||||
'python',
|
||||
'-c',
|
||||
'import os, subprocess; os.chdir(os.path.join("src", "electron")); subprocess.check_call(["python", "script/lib/npx.py", "yarn@' + (Var("yarn_version")) + '", "install", "--frozen-lockfile"]);',
|
||||
'import os; os.chdir("src"); os.chdir("electron"); os.system("npm install")',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'setup_boto',
|
||||
'pattern': 'src/electron',
|
||||
'condition': 'checkout_boto and process_deps',
|
||||
'condition': 'checkout_boto',
|
||||
'action': [
|
||||
'python',
|
||||
'-c',
|
||||
'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "boto")); subprocess.check_call(["python", "setup.py", "build"]);',
|
||||
'import os; os.chdir("src"); os.chdir("electron"); os.chdir("vendor"); os.chdir("boto"); os.system("python setup.py build");',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'setup_requests',
|
||||
'pattern': 'src/electron',
|
||||
'condition': 'checkout_requests and process_deps',
|
||||
'condition': 'checkout_requests',
|
||||
'action': [
|
||||
'python',
|
||||
'-c',
|
||||
'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "requests")); subprocess.check_call(["python", "setup.py", "build"]);',
|
||||
'import os; os.chdir("src"); os.chdir("electron"); os.chdir("vendor"); os.chdir("requests"); os.system("python setup.py build");',
|
||||
],
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
recursedeps = [
|
||||
'src',
|
||||
]
|
||||
|
||||
# Touch DEPS to bust cache
|
||||
|
||||
@@ -10,21 +10,18 @@ RUN chmod a+rwx /tmp
|
||||
# Install Linux packages
|
||||
ADD build/install-build-deps.sh /setup/install-build-deps.sh
|
||||
RUN echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | debconf-set-selections
|
||||
RUN dpkg --add-architecture i386
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
curl \
|
||||
libnotify-bin \
|
||||
locales \
|
||||
lsb-release \
|
||||
nano \
|
||||
python-dbus \
|
||||
python-dbusmock \
|
||||
python-pip \
|
||||
python-setuptools \
|
||||
sudo \
|
||||
vim-nox \
|
||||
wget \
|
||||
g++-multilib \
|
||||
libgl1:i386 \
|
||||
&& /setup/install-build-deps.sh --syms --no-prompt --no-chromeos-fonts --lib32 --arm \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@@ -36,9 +33,6 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
# dbusmock is needed for Electron tests
|
||||
RUN pip install python-dbusmock
|
||||
|
||||
RUN mkdir /tmp/workspace
|
||||
RUN chown builduser:builduser /tmp/workspace
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
libcap-dev \
|
||||
libcups2-dev \
|
||||
libdbus-1-dev \
|
||||
libgconf-2-4 \
|
||||
libgconf2-dev \
|
||||
libgnome-keyring-dev \
|
||||
libgtk2.0-0 \
|
||||
libgtk2.0-dev \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM arm64v8/ubuntu:18.04
|
||||
FROM arm64v8/ubuntu:16.04
|
||||
|
||||
RUN groupadd --gid 1000 builduser \
|
||||
&& useradd --uid 1000 --gid builduser --shell /bin/bash --create-home builduser
|
||||
@@ -22,6 +22,8 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
libcap-dev \
|
||||
libcups2-dev \
|
||||
libdbus-1-dev \
|
||||
libgconf-2-4 \
|
||||
libgconf2-dev \
|
||||
libgnome-keyring-dev \
|
||||
libgtk2.0-0 \
|
||||
libgtk2.0-dev \
|
||||
@@ -39,6 +41,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
nano \
|
||||
python-setuptools \
|
||||
python-pip \
|
||||
python-dbusmock \
|
||||
sudo \
|
||||
unzip \
|
||||
wget \
|
||||
@@ -53,9 +56,6 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
|
||||
# crcmod is required by gsutil, which is used for filling the gclient git cache
|
||||
RUN pip install -U crcmod
|
||||
|
||||
# dbusmock is needed for Electron tests
|
||||
RUN pip install python-dbusmock
|
||||
|
||||
ADD tools/xvfb-init.sh /etc/init.d/xvfb
|
||||
RUN chmod a+x /etc/init.d/xvfb
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
8.5.3
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013-2019 GitHub Inc.
|
||||
Copyright (c) 2013-2018 GitHub Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
21
README.md
21
README.md
@@ -2,10 +2,11 @@
|
||||
|
||||
|
||||
[](https://circleci.com/gh/electron/electron/tree/master)
|
||||
[](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/master)
|
||||
[](https://windows-ci.electronjs.org/project/AppVeyor/electron/branch/master)
|
||||
[](https://david-dm.org/electron/electron?type=dev)
|
||||
[](https://atom-slack.herokuapp.com/)
|
||||
|
||||
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹 🇵🇱.
|
||||
:memo: Available Translations: 🇨🇳 🇹🇼 🇧🇷 🇪🇸 🇰🇷 🇯🇵 🇷🇺 🇫🇷 🇹🇭 🇳🇱 🇹🇷 🇮🇩 🇺🇦 🇨🇿 🇮🇹.
|
||||
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).
|
||||
|
||||
The Electron framework lets you write cross-platform desktop applications
|
||||
@@ -58,13 +59,13 @@ npm start
|
||||
|
||||
## Resources for learning Electron
|
||||
|
||||
- [electronjs.org/docs](https://electronjs.org/docs) - All of Electron's documentation
|
||||
- [electronjs.org/docs](https://electronjs.org/docs) - all of Electron's documentation
|
||||
- [electron/fiddle](https://github.com/electron/fiddle) - A tool to build, run, and package small Electron experiments
|
||||
- [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
|
||||
- [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
|
||||
|
||||
@@ -91,10 +92,6 @@ const child = proc.spawn(electron)
|
||||
|
||||
Find documentation translations in [electron/i18n](https://github.com/electron/i18n).
|
||||
|
||||
## Contributing
|
||||
|
||||
If you are interested in reporting/fixing issues and contributing directly to the code base, please see [CONTRIBUTING.md](CONTRIBUTING.md) for more information on what we're looking for and how to get started.
|
||||
|
||||
## Community
|
||||
|
||||
Info on reporting bugs, getting help, finding third-party tools and sample apps,
|
||||
|
||||
108
appveyor.yml
108
appveyor.yml
@@ -23,54 +23,28 @@
|
||||
# https://www.appveyor.com/docs/build-configuration/#secure-variables
|
||||
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
|
||||
|
||||
# Uncomment these lines to enable RDP
|
||||
#on_finish:
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: libcc-20
|
||||
image: vs2019-16.3-10.0.18362
|
||||
image: libcc-20-vs2017-15.7.4
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
|
||||
DISABLE_CRASH_REPORTER_TESTS: true
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
notifications:
|
||||
- provider: Webhook
|
||||
url: https://electron-mission-control.herokuapp.com/rest/appveyor-hook
|
||||
method: POST
|
||||
headers:
|
||||
x-mission-control-secret:
|
||||
secure: 90BLVPcqhJPG7d24v0q/RRray6W3wDQ8uVQlQjOHaBWkw1i8FoA1lsjr2C/v1dVok+tS2Pi6KxDctPUkwIb4T27u4RhvmcPzQhVpfwVJAG9oNtq+yKN7vzHfg7k/pojEzVdJpQLzeJGcSrZu7VY39Q==
|
||||
on_build_success: false
|
||||
on_build_failure: true
|
||||
on_build_status_changed: false
|
||||
build_script:
|
||||
- ps: >-
|
||||
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||
} else {
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
|
||||
$result = node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
|
||||
Write-Output $result
|
||||
if ($result.ExitCode -eq 0) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
}
|
||||
- echo "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
- cd ..
|
||||
- mkdir src
|
||||
- md src
|
||||
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: $env:SCCACHE_PATH="$pwd\src\electron\external_binaries\sccache.exe"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
$env:GCLIENT_EXTRA_ARGS="$env:GCLIENT_EXTRA_ARGS --custom-var=checkout_boto=True --custom-var=checkout_requests=True"
|
||||
} else {
|
||||
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
|
||||
$env:GCLIENT_EXTRA_ARGS="--custom-var=checkout_boto=True --custom-var=checkout_requests=True"
|
||||
}
|
||||
- >-
|
||||
gclient config
|
||||
@@ -78,82 +52,36 @@ build_script:
|
||||
--unmanaged
|
||||
%GCLIENT_EXTRA_ARGS%
|
||||
"https://github.com/electron/electron"
|
||||
- gclient sync --with_branch_heads --with_tags --ignore_locks --break_repo_locks
|
||||
- ps: >-
|
||||
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
|
||||
# archive current source for future use
|
||||
# only run on x64/woa to avoid contention saving
|
||||
if ($(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30;$LASTEXITCODE -ne 0)) {
|
||||
Write-warning "Could not save source to shared drive; continuing anyway"
|
||||
}
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
|
||||
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
|
||||
}
|
||||
git clone https://github.com/electron/build-tools.git
|
||||
cd build-tools
|
||||
npm install
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
||||
$env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
$env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
cd ..
|
||||
.\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
}
|
||||
- gclient sync --with_branch_heads --with_tags
|
||||
- cd src
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- if DEFINED GN_GOMA_FILE (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% ") else (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\"")
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron:manifests
|
||||
- gn check out/Default //electron/shell/common/api:mojo
|
||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\Users\electron\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- ps: $env:BUILD_CONFIG_PATH="//electron/build/args/%GN_CONFIG%.gn"
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/Default electron:electron_app
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- if "%GN_CONFIG%"=="testing" ( python %LOCAL_GOMA_DIR%\goma_ctl.py stat )
|
||||
- appveyor PushArtifact out/Default/dist.zip
|
||||
- appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
|
||||
- appveyor PushArtifact out/Default/chromedriver.zip
|
||||
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- appveyor PushArtifact node_headers.zip
|
||||
- appveyor PushArtifact out/Default/mksnapshot.zip
|
||||
- appveyor PushArtifact out/Default/hunspell_dictionaries.zip
|
||||
- appveyor PushArtifact out/Default/electron.lib
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
ninja -C out/Default third_party/breakpad:dump_syms
|
||||
}
|
||||
- if "%GN_CONFIG%"=="release" ( python electron\script\dump-symbols.py -d %cd%\out\Default\electron.breakpad.syms -v)
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python electron\script\zip-symbols.py
|
||||
appveyor PushArtifact out/Default/symbols.zip
|
||||
} else {
|
||||
# It's useful to have pdb files when debugging testing builds that are
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
appveyor PushArtifact pdb.zip
|
||||
}
|
||||
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
- ps: >-
|
||||
if ((-Not (Test-Path Env:\TEST_WOA)) -And (-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
|
||||
if ((-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
|
||||
$env:RUN_TESTS="true"
|
||||
}
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- ps: >-
|
||||
if ($env:RUN_TESTS -eq 'true') {
|
||||
New-Item .\out\Default\gen\node_headers\Release -Type directory
|
||||
@@ -162,23 +90,17 @@ test_script:
|
||||
echo "Skipping tests for $env:GN_CONFIG build"
|
||||
}
|
||||
- cd electron
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --ci --enable-logging)
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & npm run test -- --ci )
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying mksnapshot"
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\UPLOAD_TO_S3) {
|
||||
Write-Output "Uploading Electron release distribution to s3"
|
||||
& python script\release\uploaders\upload.py --upload_to_s3
|
||||
& python script\upload.py --upload_to_s3
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python script\release\uploaders\upload.py
|
||||
& python script\upload.py
|
||||
}
|
||||
} elseif (Test-Path Env:\TEST_WOA) {
|
||||
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
}
|
||||
|
||||
@@ -2,28 +2,28 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/app/electron_content_client.h"
|
||||
#include "atom/app/atom_content_client.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "atom/common/chrome_version.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "ppapi/buildflags/buildflags.h"
|
||||
#include "shell/browser/electron_paths.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "url/url_constants.h"
|
||||
// In SHARED_INTERMEDIATE_DIR.
|
||||
#include "widevine_cdm_version.h" // NOLINT(build/include_directory)
|
||||
#include "widevine_cdm_version.h" // NOLINT(build/include)
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE)
|
||||
#include "base/native_library.h"
|
||||
@@ -32,16 +32,11 @@
|
||||
#endif // defined(WIDEVINE_CDM_AVAILABLE)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
#include "atom/common/atom_constants.h"
|
||||
#include "pdf/pdf.h"
|
||||
#include "shell/common/electron_constants.h"
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
#include "content/public/common/pepper_plugin_info.h"
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -105,27 +100,29 @@ 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())
|
||||
flash_version_numbers.emplace_back("11");
|
||||
flash_version_numbers.push_back("11");
|
||||
// |SplitString()| puts in an empty string given an empty string. :(
|
||||
else if (flash_version_numbers[0].empty())
|
||||
flash_version_numbers[0] = "11";
|
||||
if (flash_version_numbers.size() < 2)
|
||||
flash_version_numbers.emplace_back("2");
|
||||
flash_version_numbers.push_back("2");
|
||||
if (flash_version_numbers.size() < 3)
|
||||
flash_version_numbers.emplace_back("999");
|
||||
flash_version_numbers.push_back("999");
|
||||
if (flash_version_numbers.size() < 4)
|
||||
flash_version_numbers.emplace_back("999");
|
||||
flash_version_numbers.push_back("999");
|
||||
// E.g., "Shockwave Flash 10.2 r154":
|
||||
plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
|
||||
flash_version_numbers[1] + " r" +
|
||||
flash_version_numbers[2];
|
||||
plugin.version = base::JoinString(flash_version_numbers, ".");
|
||||
plugin.mime_types.emplace_back(content::kFlashPluginSwfMimeType,
|
||||
content::kFlashPluginSwfExtension,
|
||||
content::kFlashPluginSwfDescription);
|
||||
plugin.mime_types.emplace_back(content::kFlashPluginSplMimeType,
|
||||
content::kFlashPluginSplExtension,
|
||||
content::kFlashPluginSplDescription);
|
||||
content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType,
|
||||
content::kFlashPluginSwfExtension,
|
||||
content::kFlashPluginSwfDescription);
|
||||
plugin.mime_types.push_back(swf_mime_type);
|
||||
content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType,
|
||||
content::kFlashPluginSplExtension,
|
||||
content::kFlashPluginSplDescription);
|
||||
plugin.mime_types.push_back(spl_mime_type);
|
||||
|
||||
return plugin;
|
||||
}
|
||||
@@ -145,7 +142,6 @@ void AddPepperFlashFromCommandLine(
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
#if BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
content::PepperPluginInfo pdf_info;
|
||||
@@ -166,79 +162,62 @@ void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
|
||||
plugins->push_back(pdf_info);
|
||||
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
|
||||
void AppendDelimitedSwitchToVector(const base::StringPiece cmd_switch,
|
||||
std::vector<std::string>* append_me) {
|
||||
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
|
||||
const char* separator,
|
||||
const char* cmd_switch) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
auto switch_value = command_line->GetSwitchValueASCII(cmd_switch);
|
||||
if (!switch_value.empty()) {
|
||||
constexpr base::StringPiece delimiter(",", 1);
|
||||
auto tokens =
|
||||
base::SplitString(switch_value, delimiter, base::TRIM_WHITESPACE,
|
||||
base::SPLIT_WANT_NONEMPTY);
|
||||
append_me->reserve(append_me->size() + tokens.size());
|
||||
std::move(std::begin(tokens), std::end(tokens),
|
||||
std::back_inserter(*append_me));
|
||||
}
|
||||
auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
|
||||
if (!string_with_separator.empty())
|
||||
*vec = base::SplitString(string_with_separator, separator,
|
||||
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ElectronContentClient::ElectronContentClient() = default;
|
||||
AtomContentClient::AtomContentClient() {}
|
||||
|
||||
ElectronContentClient::~ElectronContentClient() = default;
|
||||
AtomContentClient::~AtomContentClient() {}
|
||||
|
||||
base::string16 ElectronContentClient::GetLocalizedString(int message_id) {
|
||||
std::string AtomContentClient::GetProduct() const {
|
||||
return "Chrome/" CHROME_VERSION_STRING;
|
||||
}
|
||||
|
||||
std::string AtomContentClient::GetUserAgent() const {
|
||||
return content::BuildUserAgentFromProduct("Chrome/" CHROME_VERSION_STRING
|
||||
" " ATOM_PRODUCT_NAME
|
||||
"/" ATOM_VERSION_STRING);
|
||||
}
|
||||
|
||||
base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
|
||||
return l10n_util::GetStringUTF16(message_id);
|
||||
}
|
||||
|
||||
base::StringPiece ElectronContentClient::GetDataResource(
|
||||
int resource_id,
|
||||
ui::ScaleFactor scale_factor) {
|
||||
return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
|
||||
resource_id, scale_factor);
|
||||
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);
|
||||
}
|
||||
|
||||
gfx::Image& ElectronContentClient::GetNativeImageNamed(int resource_id) {
|
||||
return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
|
||||
resource_id);
|
||||
}
|
||||
|
||||
base::RefCountedMemory* ElectronContentClient::GetDataResourceBytes(
|
||||
int resource_id) {
|
||||
return ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
|
||||
resource_id);
|
||||
}
|
||||
|
||||
void ElectronContentClient::AddAdditionalSchemes(Schemes* schemes) {
|
||||
AppendDelimitedSwitchToVector(switches::kServiceWorkerSchemes,
|
||||
&schemes->service_worker_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kStandardSchemes,
|
||||
&schemes->standard_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kSecureSchemes,
|
||||
&schemes->secure_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kBypassCSPSchemes,
|
||||
&schemes->csp_bypassing_schemes);
|
||||
AppendDelimitedSwitchToVector(switches::kCORSSchemes,
|
||||
&schemes->cors_enabled_schemes);
|
||||
|
||||
schemes->service_worker_schemes.emplace_back(url::kFileScheme);
|
||||
schemes->standard_schemes.emplace_back("chrome-extension");
|
||||
}
|
||||
|
||||
void ElectronContentClient::AddPepperPlugins(
|
||||
void AtomContentClient::AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
#if BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
||||
AddPepperFlashFromCommandLine(command_line, plugins);
|
||||
#endif // BUILDFLAG(ENABLE_PEPPER_FLASH)
|
||||
#if BUILDFLAG(ENABLE_PLUGINS)
|
||||
ComputeBuiltInPlugins(plugins);
|
||||
#endif // BUILDFLAG(ENABLE_PLUGINS)
|
||||
}
|
||||
|
||||
void ElectronContentClient::AddContentDecryptionModules(
|
||||
void AtomContentClient::AddContentDecryptionModules(
|
||||
std::vector<content::CdmInfo>* cdms,
|
||||
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) {
|
||||
if (cdms) {
|
||||
@@ -271,4 +250,4 @@ void ElectronContentClient::AddContentDecryptionModules(
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
39
atom/app/atom_content_client.h
Normal file
39
atom/app/atom_content_client.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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_APP_ATOM_CONTENT_CLIENT_H_
|
||||
#define ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "brightray/common/content_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomContentClient : public brightray::ContentClient {
|
||||
public:
|
||||
AtomContentClient();
|
||||
~AtomContentClient() override;
|
||||
|
||||
protected:
|
||||
// content::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 AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) override;
|
||||
void AddContentDecryptionModules(
|
||||
std::vector<content::CdmInfo>* cdms,
|
||||
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_ATOM_CONTENT_CLIENT_H_
|
||||
@@ -2,22 +2,22 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_ELECTRON_LIBRARY_MAIN_H_
|
||||
#define SHELL_APP_ELECTRON_LIBRARY_MAIN_H_
|
||||
#ifndef ATOM_APP_ATOM_LIBRARY_MAIN_H_
|
||||
#define ATOM_APP_ATOM_LIBRARY_MAIN_H_
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
extern "C" {
|
||||
__attribute__((visibility("default"))) int ElectronMain(int argc, char* argv[]);
|
||||
__attribute__((visibility("default"))) int AtomMain(int argc, char* argv[]);
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
__attribute__((visibility("default"))) int ElectronInitializeICUandStartNode(
|
||||
__attribute__((visibility("default"))) int AtomInitializeICUandStartNode(
|
||||
int argc,
|
||||
char* argv[]);
|
||||
#endif
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
|
||||
#endif // SHELL_APP_ELECTRON_LIBRARY_MAIN_H_
|
||||
#endif // ATOM_APP_ATOM_LIBRARY_MAIN_H_
|
||||
@@ -2,37 +2,37 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/app/electron_library_main.h"
|
||||
#include "atom/app/atom_library_main.h"
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
#include "atom/app/node_main.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
#include "shell/app/electron_main_delegate.h"
|
||||
#include "shell/app/node_main.h"
|
||||
#include "shell/common/electron_command_line.h"
|
||||
#include "shell/common/mac/main_application_bundle.h"
|
||||
|
||||
int ElectronMain(int argc, char* argv[]) {
|
||||
electron::ElectronMainDelegate delegate;
|
||||
int AtomMain(int argc, char* argv[]) {
|
||||
atom::AtomMainDelegate delegate;
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.argc = argc;
|
||||
params.argv = const_cast<const char**>(argv);
|
||||
electron::ElectronCommandLine::Init(argc, argv);
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
int ElectronInitializeICUandStartNode(int argc, char* argv[]) {
|
||||
int AtomInitializeICUandStartNode(int argc, char* argv[]) {
|
||||
base::AtExitManager atexit_manager;
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
electron::MainApplicationBundlePath()
|
||||
brightray::MainApplicationBundlePath()
|
||||
.Append("Contents")
|
||||
.Append("Frameworks")
|
||||
.Append(ELECTRON_PRODUCT_NAME " Framework.framework"));
|
||||
.Append(ATOM_PRODUCT_NAME " Framework.framework"));
|
||||
base::i18n::InitializeICU();
|
||||
return electron::NodeMain(argc, argv);
|
||||
return atom::NodeMain(argc, argv);
|
||||
}
|
||||
#endif
|
||||
@@ -1,7 +1,3 @@
|
||||
// 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 <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
186
atom/app/atom_main.cc
Normal file
186
atom/app/atom_main.cc
Normal file
@@ -0,0 +1,186 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/atom_main.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
#include "atom/app/atom_main_delegate.h" // NOLINT
|
||||
#include "content/public/app/content_main.h"
|
||||
#else // defined(OS_LINUX)
|
||||
#include "atom/app/atom_library_main.h"
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#include "atom/app/node_main.h"
|
||||
#include "atom/common/atom_command_line.h"
|
||||
#include "base/at_exit.h"
|
||||
#include "base/i18n/icu_util.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
|
||||
namespace {
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
const char kRunAsNode[] = "ELECTRON_RUN_AS_NODE";
|
||||
#endif
|
||||
|
||||
bool IsEnvSet(const char* name) {
|
||||
#if defined(OS_WIN)
|
||||
size_t required_size;
|
||||
getenv_s(&required_size, nullptr, 0, name);
|
||||
return required_size != 0;
|
||||
#else
|
||||
char* indicator = getenv(name);
|
||||
return indicator && indicator[0] != '\0';
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#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 char* 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
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
bool run_as_node = IsEnvSet(kRunAsNode);
|
||||
#else
|
||||
bool run_as_node = false;
|
||||
#endif
|
||||
|
||||
// Make sure the output is printed to console.
|
||||
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
|
||||
base::RouteStdioToConsole(false);
|
||||
|
||||
#ifndef DEBUG
|
||||
// Chromium has its own TLS subsystem which supports automatic destruction
|
||||
// of thread-local data, and also depends on memory allocation routines
|
||||
// provided by the CRT. The problem is that the auto-destruction mechanism
|
||||
// uses a hidden feature of the OS loader which calls a callback on thread
|
||||
// exit, but only after all loaded DLLs have been detached. Since the CRT is
|
||||
// also a DLL, it happens that by the time Chromium's `OnThreadExit` function
|
||||
// is called, the heap functions, though still in memory, no longer perform
|
||||
// their duties, and when Chromium calls `free` on its buffer, it triggers
|
||||
// an access violation error.
|
||||
// We work around this problem by invoking Chromium's `OnThreadExit` in time
|
||||
// from within the CRT's atexit facility, ensuring the heap functions are
|
||||
// still active. The second invocation from the OS loader will be a no-op.
|
||||
extern void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved);
|
||||
atexit([]() { OnThreadExit(nullptr, DLL_THREAD_DETACH, nullptr); });
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (run_as_node) {
|
||||
std::vector<char*> argv(arguments.argc);
|
||||
std::transform(
|
||||
arguments.argv, arguments.argv + arguments.argc, argv.begin(),
|
||||
[](auto& a) { return _strdup(base::WideToUTF8(a).c_str()); });
|
||||
|
||||
base::AtExitManager atexit_manager;
|
||||
base::i18n::InitializeICU();
|
||||
auto ret = atom::NodeMain(argv.size(), argv.data());
|
||||
std::for_each(argv.begin(), argv.end(), free);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
|
||||
return 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;
|
||||
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.instance = instance;
|
||||
params.sandbox_info = &sandbox_info;
|
||||
atom::AtomCommandLine::Init(arguments.argc, arguments.argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
#elif defined(OS_LINUX) // defined(OS_WIN)
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
base::i18n::InitializeICU();
|
||||
base::AtExitManager atexit_manager;
|
||||
return atom::NodeMain(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
atom::AtomMainDelegate delegate;
|
||||
content::ContentMainParams params(&delegate);
|
||||
params.argc = argc;
|
||||
params.argv = const_cast<const char**>(argv);
|
||||
atom::AtomCommandLine::Init(argc, argv);
|
||||
return content::ContentMain(params);
|
||||
}
|
||||
|
||||
#else // defined(OS_LINUX)
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#if BUILDFLAG(ENABLE_RUN_AS_NODE)
|
||||
if (IsEnvSet(kRunAsNode)) {
|
||||
return AtomInitializeICUandStartNode(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
return AtomMain(argc, argv);
|
||||
}
|
||||
|
||||
#endif // defined(OS_MACOSX)
|
||||
@@ -2,9 +2,9 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_ELECTRON_MAIN_H_
|
||||
#define SHELL_APP_ELECTRON_MAIN_H_
|
||||
#ifndef ATOM_APP_ATOM_MAIN_H_
|
||||
#define ATOM_APP_ATOM_MAIN_H_
|
||||
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
#endif // SHELL_APP_ELECTRON_MAIN_H_
|
||||
#endif // ATOM_APP_ATOM_MAIN_H_
|
||||
220
atom/app/atom_main_delegate.cc
Normal file
220
atom/app/atom_main_delegate.cc
Normal file
@@ -0,0 +1,220 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/atom_main_delegate.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/app/atom_content_client.h"
|
||||
#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"
|
||||
#include "base/environment.h"
|
||||
#include "base/logging.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "ipc/ipc_buildflags.h"
|
||||
#include "services/service_manager/sandbox/switches.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
|
||||
#define IPC_MESSAGE_MACROS_LOG_ENABLED
|
||||
#include "content/public/common/content_ipc_logging.h"
|
||||
#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
|
||||
content::RegisterIPCLogger(msg_id, logger)
|
||||
#include "atom/common/common_message_generator.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "atom/app/atom_main_delegate_mac.h"
|
||||
#endif
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const char* kRelauncherProcess = "relauncher";
|
||||
|
||||
bool IsBrowserProcess(base::CommandLine* cmd) {
|
||||
std::string process_type = cmd->GetSwitchValueASCII(::switches::kProcessType);
|
||||
return process_type.empty();
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void InvalidParameterHandler(const wchar_t*,
|
||||
const wchar_t*,
|
||||
const wchar_t*,
|
||||
unsigned int,
|
||||
uintptr_t) {
|
||||
// noop.
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomMainDelegate::AtomMainDelegate() {}
|
||||
|
||||
AtomMainDelegate::~AtomMainDelegate() {}
|
||||
|
||||
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
logging::LoggingSettings settings;
|
||||
#if defined(OS_WIN)
|
||||
// On Windows the terminal returns immediately, so we add a new line to
|
||||
// prevent output in the same line as the prompt.
|
||||
if (IsBrowserProcess(command_line))
|
||||
std::wcout << std::endl;
|
||||
#if defined(DEBUG)
|
||||
// Print logging to debug.log on Windows
|
||||
settings.logging_dest = logging::LOG_TO_ALL;
|
||||
settings.log_file = L"debug.log";
|
||||
settings.lock_log = logging::LOCK_LOG_FILE;
|
||||
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
|
||||
#else
|
||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||
#endif // defined(DEBUG)
|
||||
#else // defined(OS_WIN)
|
||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||
#endif // !defined(OS_WIN)
|
||||
|
||||
// Only enable logging when --enable-logging is specified.
|
||||
auto env = base::Environment::Create();
|
||||
if (!command_line->HasSwitch(::switches::kEnableLogging) &&
|
||||
!env->HasVar("ELECTRON_ENABLE_LOGGING")) {
|
||||
settings.logging_dest = logging::LOG_NONE;
|
||||
logging::SetMinLogLevel(logging::LOG_NUM_SEVERITIES);
|
||||
}
|
||||
|
||||
logging::InitLogging(settings);
|
||||
|
||||
// Logging with pid and timestamp.
|
||||
logging::SetLogItems(true, false, true, false);
|
||||
|
||||
// Enable convient stack printing.
|
||||
#if defined(DEBUG) && defined(OS_LINUX)
|
||||
bool enable_stack_dumping = true;
|
||||
#else
|
||||
bool enable_stack_dumping = env->HasVar("ELECTRON_ENABLE_STACK_DUMPING");
|
||||
#endif
|
||||
#if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
|
||||
// For 32bit ARM enabling stack printing would end up crashing.
|
||||
// https://github.com/electron/electron/pull/11230#issuecomment-363232482
|
||||
enable_stack_dumping = false;
|
||||
#endif
|
||||
if (enable_stack_dumping)
|
||||
base::debug::EnableInProcessStackDumping();
|
||||
|
||||
chrome::RegisterPathProvider();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
SetUpBundleOverrides();
|
||||
#endif
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
void AtomMainDelegate::PreSandboxStartup() {
|
||||
brightray::MainDelegate::PreSandboxStartup();
|
||||
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
// 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(
|
||||
service_manager::switches::kDisableSetuidSandbox);
|
||||
} else {
|
||||
// Disable renderer sandbox for most of node's functions.
|
||||
command_line->AppendSwitch(service_manager::switches::kNoSandbox);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow file:// URIs to read other file:// URIs by default.
|
||||
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Enable AVFoundation.
|
||||
command_line->AppendSwitch("enable-avfoundation");
|
||||
#endif
|
||||
}
|
||||
|
||||
void AtomMainDelegate::PreContentInitialization() {
|
||||
#if defined(OS_MACOSX)
|
||||
RegisterAtomCrApp();
|
||||
#endif
|
||||
}
|
||||
|
||||
content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
|
||||
browser_client_.reset(new AtomBrowserClient);
|
||||
return browser_client_.get();
|
||||
}
|
||||
|
||||
content::ContentRendererClient*
|
||||
AtomMainDelegate::CreateContentRendererClient() {
|
||||
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kEnableSandbox) ||
|
||||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
service_manager::switches::kNoSandbox)) {
|
||||
renderer_client_.reset(new AtomSandboxedRendererClient);
|
||||
} else {
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
}
|
||||
|
||||
return renderer_client_.get();
|
||||
}
|
||||
|
||||
content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() {
|
||||
utility_client_.reset(new AtomContentUtilityClient);
|
||||
return utility_client_.get();
|
||||
}
|
||||
|
||||
int AtomMainDelegate::RunProcess(
|
||||
const std::string& process_type,
|
||||
const content::MainFunctionParams& main_function_params) {
|
||||
if (process_type == kRelauncherProcess)
|
||||
return relauncher::RelauncherMain(main_function_params);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool AtomMainDelegate::ShouldSendMachPort(const std::string& process_type) {
|
||||
return process_type != kRelauncherProcess;
|
||||
}
|
||||
|
||||
bool AtomMainDelegate::DelaySandboxInitialization(
|
||||
const std::string& process_type) {
|
||||
return process_type == kRelauncherProcess;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<brightray::ContentClient>
|
||||
AtomMainDelegate::CreateContentClient() {
|
||||
return std::make_unique<AtomContentClient>();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
58
atom/app/atom_main_delegate.h
Normal file
58
atom/app/atom_main_delegate.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_H_
|
||||
#define ATOM_APP_ATOM_MAIN_DELEGATE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "brightray/common/content_client.h"
|
||||
#include "brightray/common/main_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomMainDelegate : public brightray::MainDelegate {
|
||||
public:
|
||||
AtomMainDelegate();
|
||||
~AtomMainDelegate() override;
|
||||
|
||||
protected:
|
||||
// content::ContentMainDelegate:
|
||||
bool BasicStartupComplete(int* exit_code) override;
|
||||
void PreSandboxStartup() override;
|
||||
void PreContentInitialization() override;
|
||||
content::ContentBrowserClient* CreateContentBrowserClient() override;
|
||||
content::ContentRendererClient* CreateContentRendererClient() override;
|
||||
content::ContentUtilityClient* CreateContentUtilityClient() override;
|
||||
int RunProcess(
|
||||
const std::string& process_type,
|
||||
const content::MainFunctionParams& main_function_params) override;
|
||||
#if defined(OS_MACOSX)
|
||||
bool ShouldSendMachPort(const std::string& process_type) override;
|
||||
bool DelaySandboxInitialization(const std::string& process_type) override;
|
||||
#endif
|
||||
|
||||
// brightray::MainDelegate:
|
||||
std::unique_ptr<brightray::ContentClient> CreateContentClient() override;
|
||||
#if defined(OS_MACOSX)
|
||||
void OverrideChildProcessPath() override;
|
||||
void OverrideFrameworkBundlePath() override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
void SetUpBundleOverrides();
|
||||
#endif
|
||||
|
||||
std::unique_ptr<content::ContentBrowserClient> browser_client_;
|
||||
std::unique_ptr<content::ContentRendererClient> renderer_client_;
|
||||
std::unique_ptr<content::ContentUtilityClient> utility_client_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_ATOM_MAIN_DELEGATE_H_
|
||||
@@ -2,14 +2,14 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_ELECTRON_MAIN_DELEGATE_MAC_H_
|
||||
#define SHELL_APP_ELECTRON_MAIN_DELEGATE_MAC_H_
|
||||
#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_MAC_H_
|
||||
#define ATOM_APP_ATOM_MAIN_DELEGATE_MAC_H_
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
// Initializes NSApplication.
|
||||
void RegisterAtomCrApp();
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_APP_ELECTRON_MAIN_DELEGATE_MAC_H_
|
||||
#endif // ATOM_APP_ATOM_MAIN_DELEGATE_MAC_H_
|
||||
72
atom/app/atom_main_delegate_mac.mm
Normal file
72
atom/app/atom_main_delegate_mac.mm
Normal file
@@ -0,0 +1,72 @@
|
||||
// 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/app/atom_main_delegate.h"
|
||||
|
||||
#include "atom/browser/mac/atom_application.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "base/mac/scoped_nsautorelease_pool.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
#include "brightray/common/mac/main_application_bundle.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
base::FilePath GetFrameworksPath() {
|
||||
return brightray::MainApplicationBundlePath()
|
||||
.Append("Contents")
|
||||
.Append("Frameworks");
|
||||
}
|
||||
|
||||
base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
|
||||
const std::string& name) {
|
||||
return frameworks_path.Append(name + " Helper.app")
|
||||
.Append("Contents")
|
||||
.Append("MacOS")
|
||||
.Append(name + " Helper");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void AtomMainDelegate::OverrideFrameworkBundlePath() {
|
||||
base::mac::SetOverrideFrameworkBundlePath(
|
||||
GetFrameworksPath().Append(ATOM_PRODUCT_NAME " Framework.framework"));
|
||||
}
|
||||
|
||||
void AtomMainDelegate::OverrideChildProcessPath() {
|
||||
base::FilePath frameworks_path = GetFrameworksPath();
|
||||
base::FilePath helper_path =
|
||||
GetHelperAppPath(frameworks_path, ATOM_PRODUCT_NAME);
|
||||
if (!base::PathExists(helper_path))
|
||||
helper_path =
|
||||
GetHelperAppPath(frameworks_path, brightray::GetApplicationName());
|
||||
if (!base::PathExists(helper_path))
|
||||
LOG(FATAL) << "Unable to find helper app";
|
||||
base::PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
|
||||
}
|
||||
|
||||
void AtomMainDelegate::SetUpBundleOverrides() {
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
NSBundle* bundle = brightray::MainApplicationBundle();
|
||||
std::string base_bundle_id =
|
||||
base::SysNSStringToUTF8([bundle bundleIdentifier]);
|
||||
NSString* team_id = [bundle objectForInfoDictionaryKey:@"ElectronTeamID"];
|
||||
if (team_id)
|
||||
base_bundle_id = base::SysNSStringToUTF8(team_id) + "." + base_bundle_id;
|
||||
base::mac::SetBaseBundleID(base_bundle_id.c_str());
|
||||
}
|
||||
|
||||
void RegisterAtomCrApp() {
|
||||
// Force the NSApplication subclass to be used.
|
||||
[AtomApplication sharedApplication];
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/app/command_line_args.h"
|
||||
#include "atom/app/command_line_args.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -33,7 +33,7 @@ bool IsUrlArg(const base::CommandLine::CharType* arg) {
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) {
|
||||
const base::CommandLine::StringType dashdash(2, '-');
|
||||
@@ -50,4 +50,4 @@ bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,15 +2,15 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_COMMAND_LINE_ARGS_H_
|
||||
#define SHELL_APP_COMMAND_LINE_ARGS_H_
|
||||
#ifndef ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
#define ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
|
||||
#include "base/command_line.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv);
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_APP_COMMAND_LINE_ARGS_H_
|
||||
#endif // ATOM_APP_COMMAND_LINE_ARGS_H_
|
||||
120
atom/app/node_main.cc
Normal file
120
atom/app/node_main.cc
Normal file
@@ -0,0 +1,120 @@
|
||||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/app/node_main.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#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 "atom/common/node_bindings.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/task_scheduler/task_scheduler.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
#include "gin/v8_initializer.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
int NodeMain(int argc, char* argv[]) {
|
||||
base::CommandLine::Init(argc, argv);
|
||||
|
||||
int exit_code = 1;
|
||||
{
|
||||
// Feed gin::PerIsolateData with a task runner.
|
||||
argv = uv_setup_args(argc, argv);
|
||||
uv_loop_t* loop = uv_default_loop();
|
||||
scoped_refptr<UvTaskRunner> uv_task_runner(new UvTaskRunner(loop));
|
||||
base::ThreadTaskRunnerHandle handle(uv_task_runner);
|
||||
|
||||
// Initialize feature list.
|
||||
auto feature_list = std::make_unique<base::FeatureList>();
|
||||
feature_list->InitializeFromCommandLine("", "");
|
||||
base::FeatureList::SetInstance(std::move(feature_list));
|
||||
|
||||
gin::V8Initializer::LoadV8Snapshot(
|
||||
gin::V8Initializer::V8SnapshotFileType::kWithAdditionalContext);
|
||||
gin::V8Initializer::LoadV8Natives();
|
||||
|
||||
// V8 requires a task scheduler apparently
|
||||
base::TaskScheduler::CreateAndStartWithDefaultParams("Electron");
|
||||
|
||||
// Initialize gin::IsolateHolder.
|
||||
JavascriptEnvironment gin_env(loop);
|
||||
|
||||
// Explicitly register electron's builtin modules.
|
||||
NodeBindings::RegisterBuiltinModules();
|
||||
|
||||
int exec_argc;
|
||||
const char** exec_argv;
|
||||
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
|
||||
|
||||
node::Environment* env = node::CreateEnvironment(
|
||||
node::CreateIsolateData(gin_env.isolate(), loop, gin_env.platform()),
|
||||
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);
|
||||
|
||||
node::LoadEnvironment(env);
|
||||
|
||||
bool more;
|
||||
do {
|
||||
more = uv_run(env->event_loop(), UV_RUN_ONCE);
|
||||
gin_env.platform()->DrainTasks(env->isolate());
|
||||
if (more == false) {
|
||||
node::EmitBeforeExit(env);
|
||||
|
||||
// Emit `beforeExit` if the loop became alive either after emitting
|
||||
// event, or after running some callbacks.
|
||||
more = uv_loop_alive(env->event_loop());
|
||||
if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)
|
||||
more = true;
|
||||
}
|
||||
} while (more == true);
|
||||
|
||||
exit_code = node::EmitExit(env);
|
||||
node::RunAtExit(env);
|
||||
gin_env.platform()->DrainTasks(env->isolate());
|
||||
gin_env.platform()->CancelPendingDelayedTasks(env->isolate());
|
||||
gin_env.platform()->UnregisterIsolate(env->isolate());
|
||||
|
||||
node::FreeEnvironment(env);
|
||||
}
|
||||
|
||||
// According to "src/gin/shell/gin_main.cc":
|
||||
//
|
||||
// gin::IsolateHolder waits for tasks running in TaskScheduler in its
|
||||
// destructor and thus must be destroyed before TaskScheduler starts skipping
|
||||
// CONTINUE_ON_SHUTDOWN tasks.
|
||||
base::TaskScheduler::GetInstance()->Shutdown();
|
||||
|
||||
v8::V8::Dispose();
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
@@ -2,13 +2,13 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_NODE_MAIN_H_
|
||||
#define SHELL_APP_NODE_MAIN_H_
|
||||
#ifndef ATOM_APP_NODE_MAIN_H_
|
||||
#define ATOM_APP_NODE_MAIN_H_
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
int NodeMain(int argc, char* argv[]);
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_APP_NODE_MAIN_H_
|
||||
#endif // ATOM_APP_NODE_MAIN_H_
|
||||
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${ELECTRON_BUNDLE_ID}</string>
|
||||
<string>${ATOM_BUNDLE_ID}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
@@ -12,7 +12,5 @@
|
||||
<string>APPL</string>
|
||||
<key>LSBackgroundOnly</key>
|
||||
<true/>
|
||||
<key>LSRequiresNativeExecution</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "shell/app/uv_task_runner.h"
|
||||
#include "atom/app/uv_task_runner.h"
|
||||
|
||||
#include "base/stl_util.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
UvTaskRunner::UvTaskRunner(uv_loop_t* loop) : loop_(loop) {}
|
||||
|
||||
@@ -42,13 +42,12 @@ bool UvTaskRunner::PostNonNestableDelayedTask(const base::Location& from_here,
|
||||
|
||||
// static
|
||||
void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
|
||||
auto& tasks = static_cast<UvTaskRunner*>(timer->data)->tasks_;
|
||||
const auto iter = tasks.find(timer);
|
||||
if (iter == std::end(tasks))
|
||||
UvTaskRunner* self = static_cast<UvTaskRunner*>(timer->data);
|
||||
if (!ContainsKey(self->tasks_, timer))
|
||||
return;
|
||||
|
||||
std::move(iter->second).Run();
|
||||
tasks.erase(iter);
|
||||
std::move(self->tasks_[timer]).Run();
|
||||
self->tasks_.erase(timer);
|
||||
uv_timer_stop(timer);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(timer), UvTaskRunner::OnClose);
|
||||
}
|
||||
@@ -58,4 +57,4 @@ void UvTaskRunner::OnClose(uv_handle_t* handle) {
|
||||
delete reinterpret_cast<uv_timer_t*>(handle);
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,17 +2,17 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_APP_UV_TASK_RUNNER_H_
|
||||
#define SHELL_APP_UV_TASK_RUNNER_H_
|
||||
#ifndef ATOM_APP_UV_TASK_RUNNER_H_
|
||||
#define ATOM_APP_UV_TASK_RUNNER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/location.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "uv.h" // NOLINT(build/include_directory)
|
||||
#include "uv.h" // NOLINT(build/include)
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
// TaskRunner implementation that posts tasks into libuv's default loop.
|
||||
class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
@@ -40,6 +40,6 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
|
||||
DISALLOW_COPY_AND_ASSIGN(UvTaskRunner);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_APP_UV_TASK_RUNNER_H_
|
||||
#endif // ATOM_APP_UV_TASK_RUNNER_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_APP_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_APP_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -11,6 +11,13 @@
|
||||
#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 "atom/common/promise_util.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"
|
||||
@@ -19,16 +26,8 @@
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/base/completion_once_callback.h"
|
||||
#include "net/base/completion_repeating_callback.h"
|
||||
#include "net/base/completion_callback.h"
|
||||
#include "net/ssl/client_cert_identity.h"
|
||||
#include "shell/browser/api/event_emitter_deprecated.h"
|
||||
#include "shell/browser/api/process_metric.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/browser_observer.h"
|
||||
#include "shell/browser/electron_browser_client.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/promise_util.h"
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
#include "chrome/browser/certificate_manager_model.h"
|
||||
@@ -42,22 +41,33 @@ namespace mate {
|
||||
class Arguments;
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
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);
|
||||
~ProcessMetric();
|
||||
};
|
||||
|
||||
namespace api {
|
||||
|
||||
class App : public ElectronBrowserClient::Delegate,
|
||||
class App : public AtomBrowserClient::Delegate,
|
||||
public mate::EventEmitter<App>,
|
||||
public BrowserObserver,
|
||||
public content::GpuDataManagerObserver,
|
||||
public content::BrowserChildProcessObserver {
|
||||
public:
|
||||
using FileIconCallback =
|
||||
base::RepeatingCallback<void(v8::Local<v8::Value>, const gfx::Image&)>;
|
||||
base::Callback<void(v8::Local<v8::Value>, const gfx::Image&)>;
|
||||
|
||||
static mate::Handle<App> Create(v8::Isolate* isolate);
|
||||
|
||||
@@ -67,7 +77,7 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void OnCertificateManagerModelCreated(
|
||||
std::unique_ptr<base::DictionaryValue> options,
|
||||
net::CompletionOnceCallback callback,
|
||||
const net::CompletionCallback& callback,
|
||||
std::unique_ptr<CertificateManagerModel> model);
|
||||
#endif
|
||||
|
||||
@@ -90,6 +100,8 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
void OnActivate(bool has_visible_windows) override;
|
||||
void OnWillFinishLaunching() override;
|
||||
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
|
||||
void OnLogin(scoped_refptr<LoginHandler> login_handler,
|
||||
const base::DictionaryValue& request_details) override;
|
||||
void OnAccessibilitySupportChanged() override;
|
||||
void OnPreMainMessageLoopRun() override;
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -116,11 +128,12 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
int cert_error,
|
||||
const net::SSLInfo& ssl_info,
|
||||
const GURL& request_url,
|
||||
bool is_main_frame_request,
|
||||
content::ResourceType resource_type,
|
||||
bool strict_enforcement,
|
||||
base::OnceCallback<void(content::CertificateRequestResultType)> callback)
|
||||
override;
|
||||
base::OnceClosure SelectClientCertificate(
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(content::CertificateRequestResultType)>&
|
||||
callback) override;
|
||||
void SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
net::ClientCertIdentityList client_certs,
|
||||
@@ -128,7 +141,7 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
bool CanCreateWindow(content::RenderFrameHost* opener,
|
||||
const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
const url::Origin& source_origin,
|
||||
const GURL& source_origin,
|
||||
content::mojom::WindowContainerType container_type,
|
||||
const GURL& target_url,
|
||||
const content::Referrer& referrer,
|
||||
@@ -142,7 +155,6 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
bool* no_javascript_access) override;
|
||||
|
||||
// content::GpuDataManagerObserver:
|
||||
void OnGpuInfoUpdate() override;
|
||||
void OnGpuProcessCrashed(base::TerminationStatus status) override;
|
||||
|
||||
// content::BrowserChildProcessObserver:
|
||||
@@ -162,59 +174,44 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
void ChildProcessLaunched(int process_type, base::ProcessHandle handle);
|
||||
void ChildProcessDisconnected(base::ProcessId pid);
|
||||
|
||||
void SetAppLogsPath(gin_helper::ErrorThrower thrower,
|
||||
base::Optional<base::FilePath> custom_path);
|
||||
|
||||
// Get/Set the pre-defined path in PathService.
|
||||
base::FilePath GetPath(gin_helper::ErrorThrower thrower,
|
||||
const std::string& name);
|
||||
void SetPath(gin_helper::ErrorThrower thrower,
|
||||
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
|
||||
void SetPath(mate::Arguments* args,
|
||||
const std::string& name,
|
||||
const base::FilePath& path);
|
||||
|
||||
void SetDesktopName(const std::string& desktop_name);
|
||||
std::string GetLocale();
|
||||
std::string GetLocaleCountryCode();
|
||||
void OnSecondInstance(const base::CommandLine::StringVector& cmd,
|
||||
const base::FilePath& cwd);
|
||||
bool HasSingleInstanceLock() const;
|
||||
bool RequestSingleInstanceLock();
|
||||
void ReleaseSingleInstanceLock();
|
||||
bool Relaunch(mate::Arguments* args);
|
||||
void DisableHardwareAcceleration(gin_helper::ErrorThrower thrower);
|
||||
void DisableDomainBlockingFor3DAPIs(gin_helper::ErrorThrower thrower);
|
||||
void DisableHardwareAcceleration(mate::Arguments* args);
|
||||
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
|
||||
bool IsAccessibilitySupportEnabled();
|
||||
void SetAccessibilitySupportEnabled(gin_helper::ErrorThrower thrower,
|
||||
bool enabled);
|
||||
void SetAccessibilitySupportEnabled(bool enabled);
|
||||
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
|
||||
#if defined(USE_NSS_CERTS)
|
||||
void ImportCertificate(const base::DictionaryValue& options,
|
||||
net::CompletionRepeatingCallback callback);
|
||||
const net::CompletionCallback& callback);
|
||||
#endif
|
||||
v8::Local<v8::Promise> GetFileIcon(const base::FilePath& path,
|
||||
mate::Arguments* args);
|
||||
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);
|
||||
v8::Local<v8::Promise> GetGPUInfo(v8::Isolate* isolate,
|
||||
const std::string& info_type);
|
||||
void EnableSandbox(gin_helper::ErrorThrower thrower);
|
||||
void SetUserAgentFallback(const std::string& user_agent);
|
||||
std::string GetUserAgentFallback();
|
||||
void SetBrowserClientCanUseCustomSiteInstance(bool should_disable);
|
||||
bool CanBrowserClientUseCustomSiteInstance();
|
||||
bool CanBrowserClientUseCustomSiteInstanceIsDefaultValue();
|
||||
void EnableSandbox(mate::Arguments* args);
|
||||
void EnableMixedSandbox(mate::Arguments* args);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool MoveToApplicationsFolder(gin_helper::ErrorThrower,
|
||||
mate::Arguments* args);
|
||||
bool MoveToApplicationsFolder(mate::Arguments* args);
|
||||
bool IsInApplicationsFolder();
|
||||
v8::Local<v8::Value> GetDockAPI(v8::Isolate* isolate);
|
||||
v8::Global<v8::Value> dock_;
|
||||
#endif
|
||||
|
||||
#if defined(MAS_BUILD)
|
||||
base::RepeatingCallback<void()> StartAccessingSecurityScopedResource(
|
||||
base::Callback<void()> StartAccessingSecurityScopedResource(
|
||||
mate::Arguments* args);
|
||||
#endif
|
||||
|
||||
@@ -238,8 +235,7 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
base::FilePath app_path_;
|
||||
|
||||
using ProcessMetricMap =
|
||||
std::unordered_map<base::ProcessId,
|
||||
std::unique_ptr<electron::ProcessMetric>>;
|
||||
std::unordered_map<base::ProcessId, std::unique_ptr<atom::ProcessMetric>>;
|
||||
ProcessMetricMap app_metrics_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(App);
|
||||
@@ -247,6 +243,6 @@ class App : public ElectronBrowserClient::Delegate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_APP_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
@@ -2,15 +2,13 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_app.h"
|
||||
|
||||
#include <string>
|
||||
#include "atom/browser/api/atom_api_app.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -21,13 +19,13 @@ void OnStopAccessingSecurityScopedResource(NSURL* bookmarkUrl) {
|
||||
}
|
||||
|
||||
// Get base64 encoded NSData, create a bookmark for it and start accessing it.
|
||||
base::RepeatingCallback<void()> App::StartAccessingSecurityScopedResource(
|
||||
base::Callback<void()> App::StartAccessingSecurityScopedResource(
|
||||
mate::Arguments* args) {
|
||||
std::string data;
|
||||
args->GetNext(&data);
|
||||
NSString* base64str = base::SysUTF8ToNSString(data);
|
||||
NSData* bookmarkData = [[NSData alloc] initWithBase64EncodedString:base64str
|
||||
options:0];
|
||||
NSData* bookmarkData =
|
||||
[[NSData alloc] initWithBase64EncodedString:base64str options:0];
|
||||
|
||||
// Create bookmarkUrl from NSData.
|
||||
BOOL isStale = false;
|
||||
@@ -57,10 +55,9 @@ base::RepeatingCallback<void()> App::StartAccessingSecurityScopedResource(
|
||||
[bookmarkUrl retain];
|
||||
|
||||
// Return a js callback which will close the bookmark.
|
||||
return base::BindRepeating(&OnStopAccessingSecurityScopedResource,
|
||||
bookmarkUrl);
|
||||
return base::Bind(&OnStopAccessingSecurityScopedResource, bookmarkUrl);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
} // namespace atom
|
||||
|
||||
} // namespace electron
|
||||
} // namespace api
|
||||
@@ -2,19 +2,19 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_auto_updater.h"
|
||||
#include "atom/browser/api/atom_api_auto_updater.h"
|
||||
|
||||
#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"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
namespace gin {
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<base::Time> {
|
||||
@@ -29,9 +29,9 @@ struct Converter<base::Time> {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -47,8 +47,8 @@ AutoUpdater::~AutoUpdater() {
|
||||
void AutoUpdater::OnError(const std::string& message) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto error = v8::Exception::Error(gin::StringToV8(isolate(), message));
|
||||
gin_helper::EmitEvent(
|
||||
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||
mate::EmitEvent(
|
||||
isolate(), GetWrapper(), "error",
|
||||
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
|
||||
// Message is also emitted to keep compatibility with old code.
|
||||
@@ -60,23 +60,17 @@ void AutoUpdater::OnError(const std::string& message,
|
||||
const std::string& domain) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto error = v8::Exception::Error(gin::StringToV8(isolate(), message));
|
||||
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
|
||||
auto errorObject =
|
||||
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
auto context = isolate()->GetCurrentContext();
|
||||
|
||||
// add two new params for better error handling
|
||||
errorObject
|
||||
->Set(context, gin::StringToV8(isolate(), "code"),
|
||||
v8::Integer::New(isolate(), code))
|
||||
.Check();
|
||||
errorObject
|
||||
->Set(context, gin::StringToV8(isolate(), "domain"),
|
||||
gin::StringToV8(isolate(), domain))
|
||||
.Check();
|
||||
errorObject->Set(mate::StringToV8(isolate(), "code"),
|
||||
v8::Integer::New(isolate(), code));
|
||||
errorObject->Set(mate::StringToV8(isolate(), "domain"),
|
||||
mate::StringToV8(isolate(), domain));
|
||||
|
||||
gin_helper::EmitEvent(isolate(), GetWrapper(), "error", errorObject, message);
|
||||
mate::EmitEvent(isolate(), GetWrapper(), "error", errorObject, message);
|
||||
}
|
||||
|
||||
void AutoUpdater::OnCheckingForUpdate() {
|
||||
@@ -97,15 +91,14 @@ void AutoUpdater::OnUpdateDownloaded(const std::string& release_notes,
|
||||
const std::string& url) {
|
||||
Emit("update-downloaded", release_notes, release_name, release_date, url,
|
||||
// Keep compatibility with old APIs.
|
||||
base::BindRepeating(&AutoUpdater::QuitAndInstall,
|
||||
base::Unretained(this)));
|
||||
base::Bind(&AutoUpdater::QuitAndInstall, base::Unretained(this)));
|
||||
}
|
||||
|
||||
void AutoUpdater::OnWindowAllClosed() {
|
||||
QuitAndInstall();
|
||||
}
|
||||
|
||||
void AutoUpdater::SetFeedURL(gin_helper::Arguments* args) {
|
||||
void AutoUpdater::SetFeedURL(mate::Arguments* args) {
|
||||
auto_updater::AutoUpdater::SetFeedURL(args);
|
||||
}
|
||||
|
||||
@@ -124,15 +117,15 @@ void AutoUpdater::QuitAndInstall() {
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new AutoUpdater(isolate));
|
||||
mate::Handle<AutoUpdater> AutoUpdater::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new AutoUpdater(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void AutoUpdater::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "AutoUpdater"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "AutoUpdater"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
|
||||
.SetMethod("getFeedURL", &auto_updater::AutoUpdater::GetFeedURL)
|
||||
.SetMethod("setFeedURL", &AutoUpdater::SetFeedURL)
|
||||
@@ -141,24 +134,22 @@ void AutoUpdater::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::AutoUpdater;
|
||||
using atom::api::AutoUpdater;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("autoUpdater", AutoUpdater::Create(isolate));
|
||||
dict.Set("AutoUpdater", AutoUpdater::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
dict.Set("AutoUpdater", AutoUpdater::GetConstructor(isolate)->GetFunction());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
|
||||
@@ -2,27 +2,26 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_AUTO_UPDATER_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_AUTO_UPDATER_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gin/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "shell/browser/auto_updater.h"
|
||||
#include "shell/browser/window_list_observer.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/auto_updater.h"
|
||||
#include "atom/browser/window_list_observer.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class AutoUpdater
|
||||
: public gin_helper::EventEmitter<mate::Wrappable<AutoUpdater>>,
|
||||
public auto_updater::Delegate,
|
||||
public WindowListObserver {
|
||||
class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
|
||||
public auto_updater::Delegate,
|
||||
public WindowListObserver {
|
||||
public:
|
||||
static gin::Handle<AutoUpdater> Create(v8::Isolate* isolate);
|
||||
static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
@@ -49,7 +48,7 @@ class AutoUpdater
|
||||
|
||||
private:
|
||||
std::string GetFeedURL();
|
||||
void SetFeedURL(gin_helper::Arguments* args);
|
||||
void SetFeedURL(mate::Arguments* args);
|
||||
void QuitAndInstall();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);
|
||||
@@ -57,6 +56,6 @@ class AutoUpdater
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_AUTO_UPDATER_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
164
atom/browser/api/atom_api_browser_view.cc
Normal file
164
atom/browser/api/atom_api_browser_view.cc
Normal file
@@ -0,0 +1,164 @@
|
||||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_browser_view.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<atom::AutoResizeFlags> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
atom::AutoResizeFlags* auto_resize_flags) {
|
||||
mate::Dictionary params;
|
||||
if (!ConvertFromV8(isolate, val, ¶ms)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t flags = 0;
|
||||
bool width = false;
|
||||
if (params.Get("width", &width) && width) {
|
||||
flags |= atom::kAutoResizeWidth;
|
||||
}
|
||||
bool height = false;
|
||||
if (params.Get("height", &height) && height) {
|
||||
flags |= atom::kAutoResizeHeight;
|
||||
}
|
||||
|
||||
*auto_resize_flags = static_cast<atom::AutoResizeFlags>(flags);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
BrowserView::BrowserView(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options) {
|
||||
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()));
|
||||
|
||||
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_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)
|
||||
@@ -2,27 +2,26 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_BROWSER_VIEW_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_BROWSER_VIEW_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/browser/api/trackable_object.h"
|
||||
#include "shell/browser/native_browser_view.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
}
|
||||
|
||||
namespace gin_helper {
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
class Dictionary;
|
||||
}
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
class NativeBrowserView;
|
||||
|
||||
@@ -30,11 +29,9 @@ namespace api {
|
||||
|
||||
class WebContents;
|
||||
|
||||
class BrowserView : public mate::TrackableObject<BrowserView>,
|
||||
public content::WebContentsObserver {
|
||||
class BrowserView : public mate::TrackableObject<BrowserView> {
|
||||
public:
|
||||
static mate::WrappableBase* New(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args);
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
@@ -45,16 +42,18 @@ class BrowserView : public mate::TrackableObject<BrowserView>,
|
||||
int32_t ID() const;
|
||||
|
||||
protected:
|
||||
BrowserView(gin::Arguments* args, const gin_helper::Dictionary& options);
|
||||
BrowserView(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options);
|
||||
~BrowserView() override;
|
||||
|
||||
// content::WebContentsObserver:
|
||||
void WebContentsDestroyed() 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);
|
||||
gfx::Rect GetBounds();
|
||||
void SetBackgroundColor(const std::string& color_name);
|
||||
|
||||
v8::Local<v8::Value> GetWebContents();
|
||||
@@ -69,6 +68,6 @@ class BrowserView : public mate::TrackableObject<BrowserView>,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_BROWSER_VIEW_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
|
||||
@@ -2,40 +2,40 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_browser_window.h"
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/api/constructor.h"
|
||||
#include "atom/common/color_util.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h" // nogncheck
|
||||
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
|
||||
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "gin/converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/unresponsive_suppressor.h"
|
||||
#include "shell/browser/web_contents_preferences.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
#include "shell/common/api/constructor.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "shell/common/native_mate_converters/value_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "ui/gl/gpu_switching_manager.h"
|
||||
|
||||
namespace electron {
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
BrowserWindow::BrowserWindow(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options)
|
||||
: TopLevelWindow(args->isolate(), options), weak_factory_(this) {
|
||||
: TopLevelWindow(isolate, options), weak_factory_(this) {
|
||||
mate::Handle<class WebContents> web_contents;
|
||||
|
||||
// Use options.webPreferences in WebContents.
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
|
||||
@@ -44,21 +44,10 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
if (options.Get(options::kBackgroundColor, &value))
|
||||
web_preferences.Set(options::kBackgroundColor, value);
|
||||
|
||||
// Copy the transparent setting to webContents
|
||||
v8::Local<v8::Value> transparent;
|
||||
if (options.Get("transparent", &transparent))
|
||||
web_preferences.Set("transparent", transparent);
|
||||
|
||||
// Copy the show setting to webContents, but only if we don't want to paint
|
||||
// when initially hidden
|
||||
bool paint_when_initially_hidden = true;
|
||||
options.Get("paintWhenInitiallyHidden", &paint_when_initially_hidden);
|
||||
if (!paint_when_initially_hidden) {
|
||||
bool show = true;
|
||||
options.Get(options::kShow, &show);
|
||||
web_preferences.Set(options::kShow, show);
|
||||
}
|
||||
|
||||
if (options.Get("webContents", &web_contents) && !web_contents.IsEmpty()) {
|
||||
// Set webPreferences from options if using an existing webContents.
|
||||
// These preferences will be used when the webContent launches new
|
||||
@@ -77,7 +66,7 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
}
|
||||
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents->GetWeakPtr();
|
||||
api_web_contents_ = web_contents.get();
|
||||
api_web_contents_->AddObserver(this);
|
||||
Observe(api_web_contents_->web_contents());
|
||||
|
||||
@@ -85,6 +74,10 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
mate::Dictionary(isolate, web_contents->GetWrapper())
|
||||
.Set("browserWindowOptions", options);
|
||||
|
||||
// Tell the content module to initialize renderer widget with transparent
|
||||
// mode.
|
||||
ui::GpuSwitchingManager::SetTransparent(window()->transparent());
|
||||
|
||||
// Associate with BrowserWindow.
|
||||
web_contents->SetOwnerWindow(window());
|
||||
|
||||
@@ -92,10 +85,11 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
if (host)
|
||||
host->GetWidget()->AddInputEventObserver(this);
|
||||
|
||||
InitWithArgs(args);
|
||||
InitWith(isolate, wrapper);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
OverrideNSWindowContentView(web_contents->managed_web_contents());
|
||||
if (!window()->has_frame())
|
||||
OverrideNSWindowContentView(web_contents->managed_web_contents());
|
||||
#endif
|
||||
|
||||
// Init window after everything has been setup.
|
||||
@@ -103,9 +97,7 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
|
||||
}
|
||||
|
||||
BrowserWindow::~BrowserWindow() {
|
||||
// FIXME This is a hack rather than a proper fix preventing shutdown crashes.
|
||||
if (api_web_contents_)
|
||||
api_web_contents_->RemoveObserver(this);
|
||||
api_web_contents_->RemoveObserver(this);
|
||||
// Note that the OnWindowClosed will not be called after the destructor runs,
|
||||
// since the window object is managed by the TopLevelWindow class.
|
||||
if (web_contents())
|
||||
@@ -141,7 +133,7 @@ void BrowserWindow::RenderViewCreated(
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
if (impl)
|
||||
impl->owner_delegate()->SetBackgroundOpaque(false);
|
||||
impl->SetBackgroundOpaque(false);
|
||||
}
|
||||
|
||||
void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
|
||||
@@ -158,32 +150,12 @@ void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(
|
||||
[](base::WeakPtr<BrowserWindow> self) {
|
||||
if (self && !self->did_ready_to_show_fired_) {
|
||||
self->did_ready_to_show_fired_ = true;
|
||||
if (self)
|
||||
self->Emit("ready-to-show");
|
||||
}
|
||||
},
|
||||
GetWeakPtr()));
|
||||
}
|
||||
|
||||
void BrowserWindow::DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url) {
|
||||
// The DidFirstVisuallyNonEmptyPaint event is not very stable that, sometimes
|
||||
// on some machines it might not be fired, and the actual behavior depends on
|
||||
// the version of Chromium.
|
||||
// To work around this bug, we ensure the ready-to-show event is emitted if it
|
||||
// has not been emitted in did-finish-load event.
|
||||
// Note that we use did-finish-load event instead of dom-ready event because
|
||||
// the latter may actually be emitted before the ready-to-show event.
|
||||
// See also https://github.com/electron/electron/issues/7779.
|
||||
if (window()->IsVisible() || did_ready_to_show_fired_)
|
||||
return;
|
||||
if (render_frame_host->GetParent()) // child frame
|
||||
return;
|
||||
did_ready_to_show_fired_ = true;
|
||||
Emit("ready-to-show");
|
||||
}
|
||||
|
||||
void BrowserWindow::BeforeUnloadDialogCancelled() {
|
||||
WindowList::WindowCloseCancelled(window());
|
||||
// Cancel unresponsive event when window close is cancelled.
|
||||
@@ -201,15 +173,19 @@ void BrowserWindow::OnRendererUnresponsive(content::RenderProcessHost*) {
|
||||
ScheduleUnresponsiveEvent(50);
|
||||
}
|
||||
|
||||
bool BrowserWindow::OnMessageReceived(const IPC::Message& message,
|
||||
content::RenderFrameHost* rfh) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(BrowserWindow, message, rfh)
|
||||
IPC_MESSAGE_HANDLER(AtomFrameHostMsg_UpdateDraggableRegions,
|
||||
UpdateDraggableRegions)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
return handled;
|
||||
}
|
||||
|
||||
void BrowserWindow::OnCloseContents() {
|
||||
// On some machines it may happen that the window gets destroyed for twice,
|
||||
// checking web_contents() can effectively guard against that.
|
||||
// https://github.com/electron/electron/issues/16202.
|
||||
//
|
||||
// TODO(zcbenz): We should find out the root cause and improve the closing
|
||||
// procedure of BrowserWindow.
|
||||
if (!web_contents())
|
||||
return;
|
||||
DCHECK(web_contents());
|
||||
|
||||
// Close all child windows before closing current window.
|
||||
v8::Locker locker(isolate());
|
||||
@@ -236,11 +212,6 @@ void BrowserWindow::OnRendererResponsive() {
|
||||
Emit("responsive");
|
||||
}
|
||||
|
||||
void BrowserWindow::OnDraggableRegionsUpdated(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
UpdateDraggableRegions(regions);
|
||||
}
|
||||
|
||||
void BrowserWindow::RequestPreferredWidth(int* width) {
|
||||
*width = web_contents()->GetPreferredSize().width();
|
||||
}
|
||||
@@ -262,8 +233,8 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
|
||||
// Already closed by renderer
|
||||
return;
|
||||
|
||||
if (web_contents()->NeedToFireBeforeUnloadOrUnload())
|
||||
web_contents()->DispatchBeforeUnload(false /* auto_cancel */);
|
||||
if (web_contents()->NeedToFireBeforeUnload())
|
||||
web_contents()->DispatchBeforeUnload();
|
||||
else
|
||||
web_contents()->Close();
|
||||
}
|
||||
@@ -275,14 +246,22 @@ void BrowserWindow::OnWindowClosed() {
|
||||
|
||||
void BrowserWindow::OnWindowBlur() {
|
||||
web_contents()->StoreFocus();
|
||||
#if defined(OS_MACOSX)
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(false);
|
||||
#endif
|
||||
|
||||
TopLevelWindow::OnWindowBlur();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowFocus() {
|
||||
web_contents()->RestoreFocus();
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
#if defined(OS_MACOSX)
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(true);
|
||||
#else
|
||||
if (!api_web_contents_->IsDevToolsOpened())
|
||||
web_contents()->Focus();
|
||||
#endif
|
||||
@@ -290,18 +269,10 @@ void BrowserWindow::OnWindowFocus() {
|
||||
TopLevelWindow::OnWindowFocus();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowIsKeyChanged(bool is_key) {
|
||||
#if defined(OS_MACOSX)
|
||||
auto* rwhv = web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv)
|
||||
rwhv->SetActive(is_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowResize() {
|
||||
#if defined(OS_MACOSX)
|
||||
if (!draggable_regions_.empty())
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
TopLevelWindow::OnWindowResize();
|
||||
}
|
||||
@@ -333,50 +304,18 @@ void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
|
||||
auto* view = web_contents()->GetRenderWidgetHostView();
|
||||
if (view)
|
||||
view->SetBackgroundColor(ParseHexColor(color_name));
|
||||
// Also update the web preferences object otherwise the view will be reset on
|
||||
// the next load URL call
|
||||
if (api_web_contents_) {
|
||||
auto* web_preferences =
|
||||
WebContentsPreferences::From(api_web_contents_->web_contents());
|
||||
if (web_preferences) {
|
||||
web_preferences->preference()->SetStringKey(options::kBackgroundColor,
|
||||
color_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
|
||||
TopLevelWindow::ResetBrowserViews();
|
||||
TopLevelWindow::AddBrowserView(value);
|
||||
TopLevelWindow::SetBrowserView(value);
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::AddBrowserView(v8::Local<v8::Value> value) {
|
||||
TopLevelWindow::AddBrowserView(value);
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::RemoveBrowserView(v8::Local<v8::Value> value) {
|
||||
TopLevelWindow::RemoveBrowserView(value);
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::ResetBrowserViews() {
|
||||
TopLevelWindow::ResetBrowserViews();
|
||||
#if defined(OS_MACOSX)
|
||||
UpdateDraggableRegions(draggable_regions_);
|
||||
UpdateDraggableRegions(nullptr, draggable_regions_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> value) {
|
||||
std::string type = gin::V8ToString(isolate, value);
|
||||
std::string type = mate::V8ToString(value);
|
||||
|
||||
auto* render_view_host = web_contents()->GetRenderViewHost();
|
||||
if (render_view_host) {
|
||||
@@ -384,8 +323,7 @@ void BrowserWindow::SetVibrancy(v8::Isolate* isolate,
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
if (impl)
|
||||
impl->owner_delegate()->SetBackgroundOpaque(
|
||||
type.empty() ? !window_->transparent() : false);
|
||||
impl->SetBackgroundOpaque(type.empty() ? !window_->transparent() : false);
|
||||
}
|
||||
|
||||
TopLevelWindow::SetVibrancy(isolate, value);
|
||||
@@ -412,13 +350,13 @@ v8::Local<v8::Value> BrowserWindow::GetWebContents(v8::Isolate* isolate) {
|
||||
|
||||
// Convert draggable regions in raw format to SkRegion format.
|
||||
std::unique_ptr<SkRegion> BrowserWindow::DraggableRegionsToSkRegion(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
auto sk_region = std::make_unique<SkRegion>();
|
||||
for (const auto& region : regions) {
|
||||
for (const DraggableRegion& region : regions) {
|
||||
sk_region->op(
|
||||
{region->bounds.x(), region->bounds.y(), region->bounds.right(),
|
||||
region->bounds.bottom()},
|
||||
region->draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
|
||||
region.bounds.x(), region.bounds.y(), region.bounds.right(),
|
||||
region.bounds.bottom(),
|
||||
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
|
||||
}
|
||||
return sk_region;
|
||||
}
|
||||
@@ -427,8 +365,8 @@ void BrowserWindow::ScheduleUnresponsiveEvent(int ms) {
|
||||
if (!window_unresponsive_closure_.IsCancelled())
|
||||
return;
|
||||
|
||||
window_unresponsive_closure_.Reset(base::BindRepeating(
|
||||
&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr()));
|
||||
window_unresponsive_closure_.Reset(
|
||||
base::Bind(&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr()));
|
||||
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
|
||||
FROM_HERE, window_unresponsive_closure_.callback(),
|
||||
base::TimeDelta::FromMilliseconds(ms));
|
||||
@@ -447,27 +385,14 @@ void BrowserWindow::Cleanup() {
|
||||
if (host)
|
||||
host->GetWidget()->RemoveInputEventObserver(this);
|
||||
|
||||
// Destroy WebContents asynchronously unless app is shutting down,
|
||||
// because destroy() might be called inside WebContents's event handler.
|
||||
api_web_contents_->DestroyWebContents(!Browser::Get()->is_shutting_down());
|
||||
api_web_contents_->DestroyWebContents(true /* async */);
|
||||
Observe(nullptr);
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowShow() {
|
||||
web_contents()->WasShown();
|
||||
TopLevelWindow::OnWindowShow();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowHide() {
|
||||
web_contents()->WasOccluded();
|
||||
TopLevelWindow::OnWindowHide();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::WrappableBase* BrowserWindow::New(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args) {
|
||||
mate::WrappableBase* BrowserWindow::New(mate::Arguments* args) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
thrower.ThrowError("Cannot create BrowserWindow before app is ready");
|
||||
args->ThrowError("Cannot create BrowserWindow before app is ready");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -481,7 +406,7 @@ mate::WrappableBase* BrowserWindow::New(gin_helper::ErrorThrower thrower,
|
||||
options = mate::Dictionary::CreateEmpty(args->isolate());
|
||||
}
|
||||
|
||||
return new BrowserWindow(args, options);
|
||||
return new BrowserWindow(args->isolate(), args->GetThis(), options);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -507,12 +432,12 @@ v8::Local<v8::Value> BrowserWindow::From(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::BrowserWindow;
|
||||
using electron::api::TopLevelWindow;
|
||||
using atom::api::BrowserWindow;
|
||||
using atom::api::TopLevelWindow;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
@@ -520,11 +445,10 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("BrowserWindow",
|
||||
mate::CreateConstructor<BrowserWindow>(
|
||||
isolate, base::BindRepeating(&BrowserWindow::New)));
|
||||
dict.Set("BrowserWindow", mate::CreateConstructor<BrowserWindow>(
|
||||
isolate, base::Bind(&BrowserWindow::New)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)
|
||||
@@ -2,19 +2,18 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_BROWSER_WINDOW_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_BROWSER_WINDOW_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/atom_api_top_level_window.h"
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "base/cancelable_callback.h"
|
||||
#include "shell/browser/api/electron_api_top_level_window.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -23,8 +22,7 @@ class BrowserWindow : public TopLevelWindow,
|
||||
public content::WebContentsObserver,
|
||||
public ExtendedWebContentsObserver {
|
||||
public:
|
||||
static mate::WrappableBase* New(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args);
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
@@ -38,7 +36,9 @@ class BrowserWindow : public TopLevelWindow,
|
||||
}
|
||||
|
||||
protected:
|
||||
BrowserWindow(gin::Arguments* args, const mate::Dictionary& options);
|
||||
BrowserWindow(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options);
|
||||
~BrowserWindow() override;
|
||||
|
||||
// content::RenderWidgetHost::InputEventObserver:
|
||||
@@ -49,21 +49,18 @@ class BrowserWindow : public TopLevelWindow,
|
||||
content::RenderViewHost* new_host) override;
|
||||
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
||||
void DidFirstVisuallyNonEmptyPaint() override;
|
||||
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url) override;
|
||||
void BeforeUnloadDialogCancelled() override;
|
||||
void OnRendererUnresponsive(content::RenderProcessHost*) override;
|
||||
bool OnMessageReceived(const IPC::Message& message,
|
||||
content::RenderFrameHost* rfh) override;
|
||||
|
||||
// ExtendedWebContentsObserver:
|
||||
void OnCloseContents() override;
|
||||
void OnRendererResponsive() override;
|
||||
void OnDraggableRegionsUpdated(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) override;
|
||||
|
||||
// NativeWindowObserver:
|
||||
void RequestPreferredWidth(int* width) override;
|
||||
void OnCloseButtonClicked(bool* prevent_default) override;
|
||||
void OnWindowIsKeyChanged(bool is_key) override;
|
||||
|
||||
// TopLevelWindow:
|
||||
void OnWindowClosed() override;
|
||||
@@ -75,12 +72,7 @@ class BrowserWindow : public TopLevelWindow,
|
||||
void Blur() override;
|
||||
void SetBackgroundColor(const std::string& color_name) override;
|
||||
void SetBrowserView(v8::Local<v8::Value> value) override;
|
||||
void AddBrowserView(v8::Local<v8::Value> value) override;
|
||||
void RemoveBrowserView(v8::Local<v8::Value> value) override;
|
||||
void ResetBrowserViews() override;
|
||||
void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) override;
|
||||
void OnWindowShow() override;
|
||||
void OnWindowHide() override;
|
||||
|
||||
// BrowserWindow APIs.
|
||||
void FocusOnWebView();
|
||||
@@ -90,18 +82,18 @@ class BrowserWindow : public TopLevelWindow,
|
||||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
void OverrideNSWindowContentView(InspectableWebContents* iwc);
|
||||
void OverrideNSWindowContentView(brightray::InspectableWebContents* iwc);
|
||||
#endif
|
||||
|
||||
// Helpers.
|
||||
|
||||
// Called when the window needs to update its draggable region.
|
||||
void UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions);
|
||||
void UpdateDraggableRegions(content::RenderFrameHost* rfh,
|
||||
const std::vector<DraggableRegion>& regions);
|
||||
|
||||
// Convert draggable regions in raw format to SkRegion format.
|
||||
std::unique_ptr<SkRegion> DraggableRegionsToSkRegion(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions);
|
||||
const std::vector<DraggableRegion>& regions);
|
||||
|
||||
// Schedule a notification unresponsive event.
|
||||
void ScheduleUnresponsiveEvent(int ms);
|
||||
@@ -116,14 +108,12 @@ class BrowserWindow : public TopLevelWindow,
|
||||
// it should be cancelled when we can prove that the window is responsive.
|
||||
base::CancelableClosure window_unresponsive_closure_;
|
||||
|
||||
bool did_ready_to_show_fired_ = false;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
std::vector<mojom::DraggableRegionPtr> draggable_regions_;
|
||||
std::vector<DraggableRegion> draggable_regions_;
|
||||
#endif
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
base::WeakPtr<api::WebContents> api_web_contents_;
|
||||
api::WebContents* api_web_contents_;
|
||||
|
||||
base::WeakPtrFactory<BrowserWindow> weak_factory_;
|
||||
|
||||
@@ -132,6 +122,6 @@ class BrowserWindow : public TopLevelWindow,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_BROWSER_WINDOW_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_WINDOW_H_
|
||||
@@ -2,17 +2,15 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_browser_window.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "atom/browser/native_window_mac.h"
|
||||
#include "atom/common/draggable_region.h"
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "shell/browser/native_browser_view.h"
|
||||
#include "shell/browser/native_window_mac.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||
#include "brightray/browser/inspectable_web_contents_view.h"
|
||||
|
||||
@interface NSView (WebContentsView)
|
||||
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
|
||||
@@ -33,7 +31,7 @@
|
||||
|
||||
@end
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -47,7 +45,7 @@ std::vector<gfx::Rect> CalculateNonDraggableRegions(
|
||||
int height) {
|
||||
std::vector<gfx::Rect> result;
|
||||
SkRegion non_draggable;
|
||||
non_draggable.op({0, 0, width, height}, SkRegion::kUnion_Op);
|
||||
non_draggable.op(0, 0, width, height, SkRegion::kUnion_Op);
|
||||
non_draggable.op(*draggable, SkRegion::kDifference_Op);
|
||||
for (SkRegion::Iterator it(non_draggable); !it.done(); it.next()) {
|
||||
result.push_back(gfx::SkIRectToRect(it.rect()));
|
||||
@@ -57,35 +55,28 @@ std::vector<gfx::Rect> CalculateNonDraggableRegions(
|
||||
|
||||
} // namespace
|
||||
|
||||
void BrowserWindow::OverrideNSWindowContentView(InspectableWebContents* iwc) {
|
||||
void BrowserWindow::OverrideNSWindowContentView(
|
||||
brightray::InspectableWebContents* iwc) {
|
||||
// Make NativeWindow use a NSView as content view.
|
||||
static_cast<NativeWindowMac*>(window())->OverrideNSWindowContentView();
|
||||
// Add webview to contentView.
|
||||
NSView* webView = iwc->GetView()->GetNativeView().GetNativeNSView();
|
||||
NSView* contentView =
|
||||
[window()->GetNativeWindow().GetNativeNSWindow() contentView];
|
||||
NSView* webView = iwc->GetView()->GetNativeView();
|
||||
NSView* contentView = [window()->GetNativeWindow() contentView];
|
||||
[webView setFrame:[contentView bounds]];
|
||||
|
||||
// ensure that buttons view is floated to top of view hierarchy
|
||||
NSArray* subviews = [contentView subviews];
|
||||
NSView* last = subviews.lastObject;
|
||||
[contentView addSubview:webView positioned:NSWindowBelow relativeTo:last];
|
||||
|
||||
[contentView addSubview:webView];
|
||||
[contentView viewDidMoveToWindow];
|
||||
}
|
||||
|
||||
void BrowserWindow::UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
content::RenderFrameHost* rfh,
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
if (window_->has_frame())
|
||||
return;
|
||||
|
||||
if (!web_contents())
|
||||
return;
|
||||
|
||||
// All ControlRegionViews should be added as children of the WebContentsView,
|
||||
// because WebContentsView will be removed and re-added when entering and
|
||||
// leaving fullscreen mode.
|
||||
NSView* webView = web_contents()->GetNativeView().GetNativeNSView();
|
||||
NSView* webView = web_contents()->GetNativeView();
|
||||
NSInteger webViewWidth = NSWidth([webView bounds]);
|
||||
NSInteger webViewHeight = NSHeight([webView bounds]);
|
||||
|
||||
@@ -104,11 +95,7 @@ void BrowserWindow::UpdateDraggableRegions(
|
||||
|
||||
// Draggable regions is implemented by having the whole web view draggable
|
||||
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
|
||||
if (&draggable_regions_ != ®ions) {
|
||||
draggable_regions_.clear();
|
||||
for (const auto& r : regions)
|
||||
draggable_regions_.push_back(r.Clone());
|
||||
}
|
||||
draggable_regions_ = regions;
|
||||
std::vector<gfx::Rect> drag_exclude_rects;
|
||||
if (regions.empty()) {
|
||||
drag_exclude_rects.push_back(gfx::Rect(0, 0, webViewWidth, webViewHeight));
|
||||
@@ -117,10 +104,8 @@ void BrowserWindow::UpdateDraggableRegions(
|
||||
DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight);
|
||||
}
|
||||
|
||||
auto browser_views = window_->browser_views();
|
||||
for (NativeBrowserView* view : browser_views) {
|
||||
view->UpdateDraggableRegions(drag_exclude_rects);
|
||||
}
|
||||
if (window_->browser_view())
|
||||
window_->browser_view()->UpdateDraggableRegions(drag_exclude_rects);
|
||||
|
||||
// Create and add a ControlRegionView for each region that needs to be
|
||||
// excluded from the dragging.
|
||||
@@ -142,4 +127,4 @@ void BrowserWindow::UpdateDraggableRegions(
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,16 +2,17 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_browser_window.h"
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
void BrowserWindow::UpdateDraggableRegions(
|
||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||
content::RenderFrameHost* rfh,
|
||||
const std::vector<DraggableRegion>& regions) {
|
||||
if (window_->has_frame())
|
||||
return;
|
||||
static_cast<NativeWindowViews*>(window_.get())
|
||||
@@ -20,4 +21,4 @@ void BrowserWindow::UpdateDraggableRegions(
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
79
atom/browser/api/atom_api_content_tracing.cc
Normal file
79
atom/browser/api/atom_api_content_tracing.cc
Normal file
@@ -0,0 +1,79 @@
|
||||
// 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 <set>
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.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 {
|
||||
|
||||
template <>
|
||||
struct Converter<base::trace_event::TraceConfig> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
base::trace_event::TraceConfig* out) {
|
||||
Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
std::string category_filter, trace_options;
|
||||
if (!options.Get("categoryFilter", &category_filter) ||
|
||||
!options.Get("traceOptions", &trace_options))
|
||||
return false;
|
||||
*out = base::trace_event::TraceConfig(category_filter, trace_options);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
using CompletionCallback = base::Callback<void(const base::FilePath&)>;
|
||||
|
||||
scoped_refptr<TracingController::TraceDataEndpoint> GetTraceDataEndpoint(
|
||||
const base::FilePath& path,
|
||||
const CompletionCallback& callback) {
|
||||
base::FilePath result_file_path = path;
|
||||
if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path))
|
||||
LOG(ERROR) << "Creating temporary file failed";
|
||||
|
||||
return TracingController::CreateFileEndpoint(
|
||||
result_file_path, base::Bind(callback, result_file_path));
|
||||
}
|
||||
|
||||
void StopRecording(const base::FilePath& path,
|
||||
const CompletionCallback& callback) {
|
||||
TracingController::GetInstance()->StopTracing(
|
||||
GetTraceDataEndpoint(path, callback));
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
auto controller = base::Unretained(TracingController::GetInstance());
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("getCategories",
|
||||
base::Bind(&TracingController::GetCategories, controller));
|
||||
dict.SetMethod("startRecording",
|
||||
base::Bind(&TracingController::StartTracing, controller));
|
||||
dict.SetMethod("stopRecording", &StopRecording);
|
||||
dict.SetMethod(
|
||||
"getTraceBufferUsage",
|
||||
base::Bind(&TracingController::GetTraceBufferUsage, controller));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)
|
||||
331
atom/browser/api/atom_api_cookies.cc
Normal file
331
atom/browser/api/atom_api_cookies.cc
Normal file
@@ -0,0 +1,331 @@
|
||||
// Copyright (c) 2015 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_cookies.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/cookie_change_notifier.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
#include "net/cookies/cookie_store.h"
|
||||
#include "net/cookies/cookie_util.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<atom::api::Cookies::Error> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
atom::api::Cookies::Error val) {
|
||||
if (val == atom::api::Cookies::SUCCESS)
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return v8::Exception::Error(StringToV8(isolate, "Setting cookie failed"));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<net::CanonicalCookie> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const net::CanonicalCookie& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("name", val.Name());
|
||||
dict.Set("value", val.Value());
|
||||
dict.Set("domain", val.Domain());
|
||||
dict.Set("hostOnly", net::cookie_util::DomainIsHostOnly(val.Domain()));
|
||||
dict.Set("path", val.Path());
|
||||
dict.Set("secure", val.IsSecure());
|
||||
dict.Set("httpOnly", val.IsHttpOnly());
|
||||
dict.Set("session", !val.IsPersistent());
|
||||
if (val.IsPersistent())
|
||||
dict.Set("expirationDate", val.ExpiryDate().ToDoubleT());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<network::mojom::CookieChangeCause> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const network::mojom::CookieChangeCause& val) {
|
||||
switch (val) {
|
||||
case network::mojom::CookieChangeCause::INSERTED:
|
||||
case network::mojom::CookieChangeCause::EXPLICIT:
|
||||
return mate::StringToV8(isolate, "explicit");
|
||||
case network::mojom::CookieChangeCause::OVERWRITE:
|
||||
return mate::StringToV8(isolate, "overwrite");
|
||||
case network::mojom::CookieChangeCause::EXPIRED:
|
||||
return mate::StringToV8(isolate, "expired");
|
||||
case network::mojom::CookieChangeCause::EVICTED:
|
||||
return mate::StringToV8(isolate, "evicted");
|
||||
case network::mojom::CookieChangeCause::EXPIRED_OVERWRITE:
|
||||
return mate::StringToV8(isolate, "expired-overwrite");
|
||||
default:
|
||||
return mate::StringToV8(isolate, "unknown");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Returns whether |domain| matches |filter|.
|
||||
bool MatchesDomain(std::string filter, const std::string& domain) {
|
||||
// Add a leading '.' character to the filter domain if it doesn't exist.
|
||||
if (net::cookie_util::DomainIsHostOnly(filter))
|
||||
filter.insert(0, ".");
|
||||
|
||||
std::string sub_domain(domain);
|
||||
// Strip any leading '.' character from the input cookie domain.
|
||||
if (!net::cookie_util::DomainIsHostOnly(sub_domain))
|
||||
sub_domain = sub_domain.substr(1);
|
||||
|
||||
// Now check whether the domain argument is a subdomain of the filter domain.
|
||||
for (sub_domain.insert(0, "."); sub_domain.length() >= filter.length();) {
|
||||
if (sub_domain == filter)
|
||||
return true;
|
||||
const size_t next_dot = sub_domain.find('.', 1); // Skip over leading dot.
|
||||
sub_domain.erase(0, next_dot);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns whether |cookie| matches |filter|.
|
||||
bool MatchesCookie(const base::DictionaryValue* filter,
|
||||
const net::CanonicalCookie& cookie) {
|
||||
std::string str;
|
||||
bool b;
|
||||
if (filter->GetString("name", &str) && str != cookie.Name())
|
||||
return false;
|
||||
if (filter->GetString("path", &str) && str != cookie.Path())
|
||||
return false;
|
||||
if (filter->GetString("domain", &str) && !MatchesDomain(str, cookie.Domain()))
|
||||
return false;
|
||||
if (filter->GetBoolean("secure", &b) && b != cookie.IsSecure())
|
||||
return false;
|
||||
if (filter->GetBoolean("session", &b) && b != !cookie.IsPersistent())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper to returns the CookieStore.
|
||||
inline net::CookieStore* GetCookieStore(
|
||||
scoped_refptr<net::URLRequestContextGetter> getter) {
|
||||
return getter->GetURLRequestContext()->cookie_store();
|
||||
}
|
||||
|
||||
// Run |callback| on UI thread.
|
||||
void RunCallbackInUI(const base::Closure& callback) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
|
||||
}
|
||||
|
||||
// Remove cookies from |list| not matching |filter|, and pass it to |callback|.
|
||||
void FilterCookies(std::unique_ptr<base::DictionaryValue> filter,
|
||||
const Cookies::GetCallback& callback,
|
||||
const net::CookieList& list) {
|
||||
net::CookieList result;
|
||||
for (const auto& cookie : list) {
|
||||
if (MatchesCookie(filter.get(), cookie))
|
||||
result.push_back(cookie);
|
||||
}
|
||||
RunCallbackInUI(base::Bind(callback, Cookies::SUCCESS, result));
|
||||
}
|
||||
|
||||
// Receives cookies matching |filter| in IO thread.
|
||||
void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::unique_ptr<base::DictionaryValue> filter,
|
||||
const Cookies::GetCallback& callback) {
|
||||
std::string url;
|
||||
filter->GetString("url", &url);
|
||||
|
||||
auto filtered_callback =
|
||||
base::Bind(FilterCookies, base::Passed(&filter), callback);
|
||||
|
||||
// Empty url will match all url cookies.
|
||||
if (url.empty())
|
||||
GetCookieStore(getter)->GetAllCookiesAsync(filtered_callback);
|
||||
else
|
||||
GetCookieStore(getter)->GetAllCookiesForURLAsync(GURL(url),
|
||||
filtered_callback);
|
||||
}
|
||||
|
||||
// Removes cookie with |url| and |name| in IO thread.
|
||||
void RemoveCookieOnIOThread(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const GURL& url,
|
||||
const std::string& name,
|
||||
const base::Closure& callback) {
|
||||
GetCookieStore(getter)->DeleteCookieAsync(
|
||||
url, name, base::BindOnce(RunCallbackInUI, callback));
|
||||
}
|
||||
|
||||
// Callback of SetCookie.
|
||||
void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
|
||||
RunCallbackInUI(
|
||||
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::BindOnce(RunCallbackInUI, callback));
|
||||
}
|
||||
|
||||
// Sets cookie with |details| in IO thread.
|
||||
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::unique_ptr<base::DictionaryValue> details,
|
||||
const Cookies::SetCallback& callback) {
|
||||
std::string url, name, value, domain, path;
|
||||
bool secure = false;
|
||||
bool http_only = false;
|
||||
double creation_date;
|
||||
double expiration_date;
|
||||
double last_access_date;
|
||||
details->GetString("url", &url);
|
||||
details->GetString("name", &name);
|
||||
details->GetString("value", &value);
|
||||
details->GetString("domain", &domain);
|
||||
details->GetString("path", &path);
|
||||
details->GetBoolean("secure", &secure);
|
||||
details->GetBoolean("httpOnly", &http_only);
|
||||
|
||||
base::Time creation_time;
|
||||
if (details->GetDouble("creationDate", &creation_date)) {
|
||||
creation_time = (creation_date == 0)
|
||||
? base::Time::UnixEpoch()
|
||||
: base::Time::FromDoubleT(creation_date);
|
||||
}
|
||||
|
||||
base::Time expiration_time;
|
||||
if (details->GetDouble("expirationDate", &expiration_date)) {
|
||||
expiration_time = (expiration_date == 0)
|
||||
? base::Time::UnixEpoch()
|
||||
: base::Time::FromDoubleT(expiration_date);
|
||||
}
|
||||
|
||||
base::Time last_access_time;
|
||||
if (details->GetDouble("lastAccessDate", &last_access_date)) {
|
||||
last_access_time = (last_access_date == 0)
|
||||
? base::Time::UnixEpoch()
|
||||
: base::Time::FromDoubleT(last_access_date);
|
||||
}
|
||||
|
||||
std::unique_ptr<net::CanonicalCookie> canonical_cookie(
|
||||
net::CanonicalCookie::CreateSanitizedCookie(
|
||||
GURL(url), name, value, domain, path, creation_time, expiration_time,
|
||||
last_access_time, secure, http_only,
|
||||
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT));
|
||||
auto completion_callback = base::BindOnce(OnSetCookie, callback);
|
||||
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
return;
|
||||
}
|
||||
if (url.empty()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
return;
|
||||
}
|
||||
if (name.empty()) {
|
||||
std::move(completion_callback).Run(false);
|
||||
return;
|
||||
}
|
||||
GetCookieStore(getter)->SetCanonicalCookieAsync(
|
||||
std::move(canonical_cookie), secure, http_only,
|
||||
std::move(completion_callback));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
Init(isolate);
|
||||
cookie_change_subscription_ =
|
||||
browser_context_->cookie_change_notifier()->RegisterCookieChangeCallback(
|
||||
base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
|
||||
}
|
||||
|
||||
Cookies::~Cookies() {}
|
||||
|
||||
void Cookies::Get(const base::DictionaryValue& filter,
|
||||
const GetCallback& callback) {
|
||||
auto copy = base::DictionaryValue::From(
|
||||
base::Value::ToUniquePtrValue(filter.Clone()));
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(GetCookiesOnIO, base::RetainedRef(getter), std::move(copy),
|
||||
callback));
|
||||
}
|
||||
|
||||
void Cookies::Remove(const GURL& url,
|
||||
const std::string& name,
|
||||
const base::Closure& callback) {
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(RemoveCookieOnIOThread, base::RetainedRef(getter), url,
|
||||
name, callback));
|
||||
}
|
||||
|
||||
void Cookies::Set(const base::DictionaryValue& details,
|
||||
const SetCallback& callback) {
|
||||
auto copy = base::DictionaryValue::From(
|
||||
base::Value::ToUniquePtrValue(details.Clone()));
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(SetCookieOnIO, base::RetainedRef(getter), std::move(copy),
|
||||
callback));
|
||||
}
|
||||
|
||||
void Cookies::FlushStore(const base::Closure& callback) {
|
||||
auto* getter = browser_context_->GetRequestContext();
|
||||
content::BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(FlushCookieStoreOnIOThread, base::RetainedRef(getter),
|
||||
callback));
|
||||
}
|
||||
|
||||
void Cookies::OnCookieChanged(const CookieDetails* details) {
|
||||
Emit("changed", *(details->cookie), details->cause, details->removed);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Cookies> Cookies::Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
void Cookies::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Cookies"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("get", &Cookies::Get)
|
||||
.SetMethod("remove", &Cookies::Remove)
|
||||
.SetMethod("set", &Cookies::Set)
|
||||
.SetMethod("flushStore", &Cookies::FlushStore);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
74
atom/browser/api/atom_api_cookies.h
Normal file
74
atom/browser/api/atom_api_cookies.h
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2015 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_COOKIES_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_COOKIES_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/net/cookie_details.h"
|
||||
#include "base/callback_list.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class URLRequestContextGetter;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Cookies : public mate::TrackableObject<Cookies> {
|
||||
public:
|
||||
enum Error {
|
||||
SUCCESS,
|
||||
FAILED,
|
||||
};
|
||||
|
||||
using GetCallback = base::Callback<void(Error, const net::CookieList&)>;
|
||||
using SetCallback = base::Callback<void(Error)>;
|
||||
|
||||
static mate::Handle<Cookies> Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
protected:
|
||||
Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Cookies() override;
|
||||
|
||||
void Get(const base::DictionaryValue& filter, const GetCallback& callback);
|
||||
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);
|
||||
|
||||
// CookieChangeNotifier subscription:
|
||||
void OnCookieChanged(const CookieDetails*);
|
||||
|
||||
private:
|
||||
std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
|
||||
cookie_change_subscription_;
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_COOKIES_H_
|
||||
@@ -2,23 +2,25 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_debugger.h"
|
||||
#include "atom/browser/api/atom_api_debugger.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.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 "shell/common/native_mate_converters/value_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::DevToolsAgentHost;
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -27,7 +29,7 @@ Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents)
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
Debugger::~Debugger() = default;
|
||||
Debugger::~Debugger() {}
|
||||
|
||||
void Debugger::AgentHostClosed(DevToolsAgentHost* agent_host) {
|
||||
DCHECK(agent_host == agent_host_);
|
||||
@@ -43,8 +45,7 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
std::unique_ptr<base::Value> parsed_message =
|
||||
base::JSONReader::ReadDeprecated(message);
|
||||
std::unique_ptr<base::Value> parsed_message = base::JSONReader::Read(message);
|
||||
if (!parsed_message || !parsed_message->is_dict())
|
||||
return;
|
||||
base::DictionaryValue* dict =
|
||||
@@ -54,35 +55,29 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
|
||||
std::string method;
|
||||
if (!dict->GetString("method", &method))
|
||||
return;
|
||||
std::string session_id;
|
||||
dict->GetString("sessionId", &session_id);
|
||||
base::DictionaryValue* params_value = nullptr;
|
||||
base::DictionaryValue params;
|
||||
if (dict->GetDictionary("params", ¶ms_value))
|
||||
params.Swap(params_value);
|
||||
Emit("message", method, params, session_id);
|
||||
Emit("message", method, params);
|
||||
} else {
|
||||
auto it = pending_requests_.find(id);
|
||||
if (it == pending_requests_.end())
|
||||
auto send_command_callback = pending_requests_[id];
|
||||
pending_requests_.erase(id);
|
||||
if (send_command_callback.is_null())
|
||||
return;
|
||||
|
||||
electron::util::Promise<base::DictionaryValue> promise =
|
||||
std::move(it->second);
|
||||
pending_requests_.erase(it);
|
||||
|
||||
base::DictionaryValue* error = nullptr;
|
||||
if (dict->GetDictionary("error", &error)) {
|
||||
std::string message;
|
||||
error->GetString("message", &message);
|
||||
promise.RejectWithErrorMessage(message);
|
||||
} else {
|
||||
base::DictionaryValue* result_body = nullptr;
|
||||
base::DictionaryValue result;
|
||||
if (dict->GetDictionary("result", &result_body)) {
|
||||
result.Swap(result_body);
|
||||
}
|
||||
promise.Resolve(result);
|
||||
base::DictionaryValue* error_body = nullptr;
|
||||
base::DictionaryValue error;
|
||||
bool has_error;
|
||||
if ((has_error = dict->GetDictionary("error", &error_body))) {
|
||||
error.Swap(error_body);
|
||||
}
|
||||
|
||||
base::DictionaryValue* result_body = nullptr;
|
||||
base::DictionaryValue result;
|
||||
if (dict->GetDictionary("result", &result_body))
|
||||
result.Swap(result_body);
|
||||
send_command_callback.Run(has_error ? error.Clone() : base::Value(),
|
||||
result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,54 +125,42 @@ void Debugger::Detach() {
|
||||
AgentHostClosed(agent_host_.get());
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> Debugger::SendCommand(mate::Arguments* args) {
|
||||
electron::util::Promise<base::DictionaryValue> promise(isolate());
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (!agent_host_) {
|
||||
promise.RejectWithErrorMessage("No target available");
|
||||
return handle;
|
||||
}
|
||||
void Debugger::SendCommand(mate::Arguments* args) {
|
||||
if (!agent_host_)
|
||||
return;
|
||||
|
||||
std::string method;
|
||||
if (!args->GetNext(&method)) {
|
||||
promise.RejectWithErrorMessage("Invalid method");
|
||||
return handle;
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
|
||||
base::DictionaryValue command_params;
|
||||
args->GetNext(&command_params);
|
||||
|
||||
std::string session_id;
|
||||
if (args->GetNext(&session_id) && session_id.empty()) {
|
||||
promise.RejectWithErrorMessage("Empty session id is not allowed");
|
||||
return handle;
|
||||
}
|
||||
SendCommandCallback callback;
|
||||
args->GetNext(&callback);
|
||||
|
||||
base::DictionaryValue request;
|
||||
int request_id = ++previous_request_id_;
|
||||
pending_requests_.emplace(request_id, std::move(promise));
|
||||
pending_requests_[request_id] = callback;
|
||||
request.SetInteger("id", request_id);
|
||||
request.SetString("method", method);
|
||||
if (!command_params.empty()) {
|
||||
if (!command_params.empty())
|
||||
request.Set("params",
|
||||
base::Value::ToUniquePtrValue(command_params.Clone()));
|
||||
}
|
||||
|
||||
if (!session_id.empty()) {
|
||||
request.SetString("sessionId", session_id);
|
||||
}
|
||||
|
||||
std::string json_args;
|
||||
base::JSONWriter::Write(request, &json_args);
|
||||
agent_host_->DispatchProtocolMessage(this, json_args);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Debugger::ClearPendingRequests() {
|
||||
for (auto& it : pending_requests_)
|
||||
it.second.RejectWithErrorMessage("target closed while handling command");
|
||||
if (pending_requests_.empty())
|
||||
return;
|
||||
base::Value error(base::Value::Type::DICTIONARY);
|
||||
base::Value error_msg("target closed while handling command");
|
||||
error.SetKey("message", std::move(error_msg));
|
||||
for (const auto& it : pending_requests_)
|
||||
it.second.Run(error, base::Value());
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -199,11 +182,11 @@ void Debugger::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::Debugger;
|
||||
using atom::api::Debugger;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
@@ -211,11 +194,9 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary(isolate, exports)
|
||||
.Set("Debugger", Debugger::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
.Set("Debugger", Debugger::GetConstructor(isolate)->GetFunction());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize);
|
||||
@@ -2,19 +2,18 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_DEBUGGER_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_DEBUGGER_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/devtools_agent_host_client.h"
|
||||
#include "content/public/browser/web_contents_observer.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "shell/browser/api/trackable_object.h"
|
||||
#include "shell/common/promise_util.h"
|
||||
|
||||
namespace content {
|
||||
class DevToolsAgentHost;
|
||||
@@ -25,7 +24,7 @@ namespace mate {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -33,6 +32,9 @@ class Debugger : public mate::TrackableObject<Debugger>,
|
||||
public content::DevToolsAgentHostClient,
|
||||
public content::WebContentsObserver {
|
||||
public:
|
||||
using SendCommandCallback =
|
||||
base::Callback<void(const base::Value&, const base::Value&)>;
|
||||
|
||||
static mate::Handle<Debugger> Create(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents);
|
||||
|
||||
@@ -54,13 +56,12 @@ class Debugger : public mate::TrackableObject<Debugger>,
|
||||
content::RenderFrameHost* new_rfh) override;
|
||||
|
||||
private:
|
||||
using PendingRequestMap =
|
||||
std::map<int, electron::util::Promise<base::DictionaryValue>>;
|
||||
using PendingRequestMap = std::map<int, SendCommandCallback>;
|
||||
|
||||
void Attach(mate::Arguments* args);
|
||||
bool IsAttached();
|
||||
void Detach();
|
||||
v8::Local<v8::Promise> SendCommand(mate::Arguments* args);
|
||||
void SendCommand(mate::Arguments* args);
|
||||
void ClearPendingRequests();
|
||||
|
||||
content::WebContents* web_contents_; // Weak Reference.
|
||||
@@ -74,6 +75,6 @@ class Debugger : public mate::TrackableObject<Debugger>,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_DEBUGGER_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DEBUGGER_H_
|
||||
@@ -2,23 +2,20 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_desktop_capturer.h"
|
||||
#include "atom/browser/api/atom_api_desktop_capturer.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/browser/media/webrtc/desktop_media_list.h"
|
||||
#include "chrome/browser/media/webrtc/window_icon_util.h"
|
||||
#include "content/public/browser/desktop_capture.h"
|
||||
#include "shell/common/api/electron_api_native_image.h"
|
||||
#include "shell/common/gin_converters/gfx_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.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"
|
||||
|
||||
@@ -28,34 +25,30 @@
|
||||
#include "ui/display/win/display_info.h"
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
namespace gin {
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<electron::api::DesktopCapturer::Source> {
|
||||
struct Converter<atom::api::DesktopCapturer::Source> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const electron::api::DesktopCapturer::Source& source) {
|
||||
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
const atom::api::DesktopCapturer::Source& source) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
content::DesktopMediaID id = source.media_list_source.id;
|
||||
dict.Set("name", base::UTF16ToUTF8(source.media_list_source.name));
|
||||
dict.Set("id", id.ToString());
|
||||
dict.Set("thumbnail",
|
||||
electron::api::NativeImage::Create(
|
||||
atom::api::NativeImage::Create(
|
||||
isolate, gfx::Image(source.media_list_source.thumbnail)));
|
||||
dict.Set("display_id", source.display_id);
|
||||
if (source.fetch_icon) {
|
||||
dict.Set(
|
||||
"appIcon",
|
||||
electron::api::NativeImage::Create(
|
||||
isolate, gfx::Image(GetWindowIcon(source.media_list_source.id))));
|
||||
}
|
||||
return ConvertToV8(isolate, dict);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -63,13 +56,11 @@ DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
DesktopCapturer::~DesktopCapturer() = default;
|
||||
DesktopCapturer::~DesktopCapturer() {}
|
||||
|
||||
void DesktopCapturer::StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size,
|
||||
bool fetch_window_icons) {
|
||||
fetch_window_icons_ = fetch_window_icons;
|
||||
const gfx::Size& thumbnail_size) {
|
||||
#if defined(OS_WIN)
|
||||
if (content::desktop_capture::CreateDesktopCaptureOptions()
|
||||
.allow_directx_capturer()) {
|
||||
@@ -88,57 +79,73 @@ void DesktopCapturer::StartHandling(bool capture_window,
|
||||
capture_screen_ = capture_screen;
|
||||
|
||||
{
|
||||
// Remove this once
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=795340 is fixed.
|
||||
base::ScopedAllowBaseSyncPrimitivesForTesting
|
||||
scoped_allow_base_sync_primitives;
|
||||
// Initialize the source list.
|
||||
// Apply the new thumbnail size and restart capture.
|
||||
if (capture_window) {
|
||||
window_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
window_capturer_.reset(new NativeDesktopMediaList(
|
||||
content::DesktopMediaID::TYPE_WINDOW,
|
||||
content::desktop_capture::CreateWindowCapturer());
|
||||
content::desktop_capture::CreateWindowCapturer()));
|
||||
window_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
window_capturer_->AddObserver(this);
|
||||
window_capturer_->Update(base::BindOnce(
|
||||
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
|
||||
window_capturer_.get()));
|
||||
window_capturer_->StartUpdating();
|
||||
}
|
||||
|
||||
if (capture_screen) {
|
||||
screen_capturer_ = std::make_unique<NativeDesktopMediaList>(
|
||||
screen_capturer_.reset(new NativeDesktopMediaList(
|
||||
content::DesktopMediaID::TYPE_SCREEN,
|
||||
content::desktop_capture::CreateScreenCapturer());
|
||||
content::desktop_capture::CreateScreenCapturer()));
|
||||
screen_capturer_->SetThumbnailSize(thumbnail_size);
|
||||
screen_capturer_->AddObserver(this);
|
||||
screen_capturer_->Update(base::BindOnce(
|
||||
&DesktopCapturer::UpdateSourcesList, weak_ptr_factory_.GetWeakPtr(),
|
||||
screen_capturer_.get()));
|
||||
screen_capturer_->StartUpdating();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DesktopCapturer::OnSourceAdded(DesktopMediaList* list, int index) {}
|
||||
|
||||
void DesktopCapturer::OnSourceRemoved(DesktopMediaList* list, int index) {}
|
||||
|
||||
void DesktopCapturer::OnSourceMoved(DesktopMediaList* list,
|
||||
int old_index,
|
||||
int new_index) {}
|
||||
|
||||
void DesktopCapturer::OnSourceNameChanged(DesktopMediaList* list, int index) {}
|
||||
|
||||
void DesktopCapturer::OnSourceThumbnailChanged(DesktopMediaList* list,
|
||||
int index) {}
|
||||
|
||||
void DesktopCapturer::OnSourceUnchanged(DesktopMediaList* list) {
|
||||
UpdateSourcesList(list);
|
||||
}
|
||||
|
||||
bool DesktopCapturer::ShouldScheduleNextRefresh(DesktopMediaList* list) {
|
||||
UpdateSourcesList(list);
|
||||
return false;
|
||||
}
|
||||
|
||||
void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
std::vector<DesktopCapturer::Source> window_sources;
|
||||
if (capture_window_ &&
|
||||
list->GetMediaListType() == content::DesktopMediaID::TYPE_WINDOW) {
|
||||
capture_window_ = false;
|
||||
const auto& media_list_sources = list->GetSources();
|
||||
std::vector<DesktopCapturer::Source> window_sources;
|
||||
window_sources.reserve(media_list_sources.size());
|
||||
for (const auto& media_list_source : media_list_sources) {
|
||||
window_sources.emplace_back(DesktopCapturer::Source{
|
||||
media_list_source, std::string(), fetch_window_icons_});
|
||||
window_sources.emplace_back(
|
||||
DesktopCapturer::Source{media_list_source, std::string()});
|
||||
}
|
||||
std::move(window_sources.begin(), window_sources.end(),
|
||||
std::back_inserter(captured_sources_));
|
||||
}
|
||||
|
||||
std::vector<DesktopCapturer::Source> screen_sources;
|
||||
if (capture_screen_ &&
|
||||
list->GetMediaListType() == content::DesktopMediaID::TYPE_SCREEN) {
|
||||
capture_screen_ = false;
|
||||
const auto& media_list_sources = list->GetSources();
|
||||
std::vector<DesktopCapturer::Source> screen_sources;
|
||||
screen_sources.reserve(media_list_sources.size());
|
||||
for (const auto& media_list_source : media_list_sources) {
|
||||
screen_sources.emplace_back(
|
||||
DesktopCapturer::Source{media_list_source, std::string()});
|
||||
@@ -152,12 +159,8 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
std::vector<std::string> device_names;
|
||||
// Crucially, this list of device names will be in the same order as
|
||||
// |media_list_sources|.
|
||||
if (!webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
|
||||
&device_names)) {
|
||||
Emit("error", "Failed to get sources.");
|
||||
return;
|
||||
}
|
||||
|
||||
webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
|
||||
&device_names);
|
||||
int device_name_index = 0;
|
||||
for (auto& source : screen_sources) {
|
||||
const auto& device_name = device_names[device_name_index++];
|
||||
@@ -167,13 +170,13 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
const int64_t device_id =
|
||||
display::win::DisplayInfo::DeviceIdFromDeviceName(
|
||||
wide_device_name.c_str());
|
||||
source.display_id = base::NumberToString(device_id);
|
||||
source.display_id = base::Int64ToString(device_id);
|
||||
}
|
||||
}
|
||||
#elif defined(OS_MACOSX)
|
||||
// On Mac, the IDs across the APIs match.
|
||||
for (auto& source : screen_sources) {
|
||||
source.display_id = base::NumberToString(source.media_list_source.id.id);
|
||||
source.display_id = base::Int64ToString(source.media_list_source.id.id);
|
||||
}
|
||||
#endif // defined(OS_WIN)
|
||||
// TODO(ajmacd): Add Linux support. The IDs across APIs differ but Chrome
|
||||
@@ -184,26 +187,26 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
|
||||
}
|
||||
|
||||
if (!capture_window_ && !capture_screen_)
|
||||
Emit("finished", captured_sources_, fetch_window_icons_);
|
||||
Emit("finished", captured_sources_);
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new DesktopCapturer(isolate));
|
||||
mate::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new DesktopCapturer(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void DesktopCapturer::BuildPrototype(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "DesktopCapturer"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "DesktopCapturer"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -211,11 +214,11 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
gin_helper::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("createDesktopCapturer",
|
||||
&electron::api::DesktopCapturer::Create);
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("desktopCapturer", atom::api::DesktopCapturer::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize);
|
||||
@@ -2,61 +2,54 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_DESKTOP_CAPTURER_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_DESKTOP_CAPTURER_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
|
||||
#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/browser/api/trackable_object.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class DesktopCapturer
|
||||
: public mate::TrackableObject<
|
||||
DesktopCapturer,
|
||||
gin_helper::EventEmitter<mate::Wrappable<DesktopCapturer>>>,
|
||||
public DesktopMediaListObserver {
|
||||
class DesktopCapturer : public mate::EventEmitter<DesktopCapturer>,
|
||||
public DesktopMediaListObserver {
|
||||
public:
|
||||
struct Source {
|
||||
DesktopMediaList::Source media_list_source;
|
||||
// Will be an empty string if not available.
|
||||
std::string display_id;
|
||||
|
||||
// Whether or not this source should provide an icon.
|
||||
bool fetch_icon = false;
|
||||
};
|
||||
|
||||
static gin::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||
static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
void StartHandling(bool capture_window,
|
||||
bool capture_screen,
|
||||
const gfx::Size& thumbnail_size,
|
||||
bool fetch_window_icons);
|
||||
const gfx::Size& thumbnail_size);
|
||||
|
||||
protected:
|
||||
explicit DesktopCapturer(v8::Isolate* isolate);
|
||||
~DesktopCapturer() override;
|
||||
|
||||
// DesktopMediaListObserver:
|
||||
void OnSourceAdded(DesktopMediaList* list, int index) override {}
|
||||
void OnSourceRemoved(DesktopMediaList* list, int index) override {}
|
||||
// DesktopMediaListObserver overrides.
|
||||
void OnSourceAdded(DesktopMediaList* list, int index) override;
|
||||
void OnSourceRemoved(DesktopMediaList* list, int index) override;
|
||||
void OnSourceMoved(DesktopMediaList* list,
|
||||
int old_index,
|
||||
int new_index) override {}
|
||||
void OnSourceNameChanged(DesktopMediaList* list, int index) override {}
|
||||
void OnSourceThumbnailChanged(DesktopMediaList* list, int index) override {}
|
||||
int new_index) override;
|
||||
void OnSourceNameChanged(DesktopMediaList* list, int index) override;
|
||||
void OnSourceThumbnailChanged(DesktopMediaList* list, int index) override;
|
||||
void OnSourceUnchanged(DesktopMediaList* list) override;
|
||||
bool ShouldScheduleNextRefresh(DesktopMediaList* list) override;
|
||||
|
||||
private:
|
||||
void UpdateSourcesList(DesktopMediaList* list);
|
||||
@@ -66,18 +59,15 @@ class DesktopCapturer
|
||||
std::vector<DesktopCapturer::Source> captured_sources_;
|
||||
bool capture_window_ = false;
|
||||
bool capture_screen_ = false;
|
||||
bool fetch_window_icons_ = false;
|
||||
#if defined(OS_WIN)
|
||||
bool using_directx_capturer_ = false;
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
base::WeakPtrFactory<DesktopCapturer> weak_ptr_factory_{this};
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_DESKTOP_CAPTURER_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
|
||||
142
atom/browser/api/atom_api_dialog.cc
Normal file
142
atom/browser/api/atom_api_dialog.cc
Normal file
@@ -0,0 +1,142 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/atom_api_browser_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"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<file_dialog::Filter> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::Filter* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
if (!dict.Get("name", &(out->first)))
|
||||
return false;
|
||||
if (!dict.Get("extensions", &(out->second)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<file_dialog::DialogSettings> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
file_dialog::DialogSettings* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
dict.Get("window", &(out->parent_window));
|
||||
dict.Get("title", &(out->title));
|
||||
dict.Get("message", &(out->message));
|
||||
dict.Get("buttonLabel", &(out->button_label));
|
||||
dict.Get("nameFieldLabel", &(out->name_field_label));
|
||||
dict.Get("defaultPath", &(out->default_path));
|
||||
dict.Get("filters", &(out->filters));
|
||||
dict.Get("properties", &(out->properties));
|
||||
dict.Get("showsTagField", &(out->shows_tag_field));
|
||||
#if defined(MAS_BUILD)
|
||||
dict.Get("securityScopedBookmarks", &(out->security_scoped_bookmarks));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
void ShowMessageBox(int type,
|
||||
const std::vector<std::string>& buttons,
|
||||
int default_id,
|
||||
int cancel_id,
|
||||
int options,
|
||||
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) {
|
||||
v8::Local<v8::Value> peek = args->PeekNext();
|
||||
atom::MessageBoxCallback callback;
|
||||
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);
|
||||
} else {
|
||||
int chosen = atom::ShowMessageBox(
|
||||
window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
|
||||
cancel_id, options, title, message, detail, icon);
|
||||
args->Return(chosen);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowOpenDialog(const file_dialog::DialogSettings& settings,
|
||||
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);
|
||||
} else {
|
||||
std::vector<base::FilePath> paths;
|
||||
if (file_dialog::ShowOpenDialog(settings, &paths))
|
||||
args->Return(paths);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowSaveDialog(const file_dialog::DialogSettings& settings,
|
||||
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);
|
||||
} else {
|
||||
base::FilePath path;
|
||||
if (file_dialog::ShowSaveDialog(settings, &path))
|
||||
args->Return(path);
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("showMessageBox", &ShowMessageBox);
|
||||
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
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)
|
||||
@@ -2,19 +2,20 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_download_item.h"
|
||||
#include "atom/browser/api/atom_api_download_item.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "atom/browser/atom_browser_main_parts.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/gurl_converter.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 "shell/browser/electron_browser_main_parts.h"
|
||||
#include "shell/common/native_mate_converters/file_dialog_converter.h"
|
||||
#include "shell/common/native_mate_converters/file_path_converter.h"
|
||||
#include "shell/common/native_mate_converters/gurl_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
@@ -46,7 +47,7 @@ struct Converter<download::DownloadItem::DownloadState> {
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -101,7 +102,7 @@ bool DownloadItem::IsPaused() const {
|
||||
}
|
||||
|
||||
void DownloadItem::Resume() {
|
||||
download_item_->Resume(true /* user_gesture */);
|
||||
download_item_->Resume();
|
||||
}
|
||||
|
||||
bool DownloadItem::CanResume() const {
|
||||
@@ -164,15 +165,6 @@ base::FilePath DownloadItem::GetSavePath() const {
|
||||
return save_path_;
|
||||
}
|
||||
|
||||
file_dialog::DialogSettings DownloadItem::GetSaveDialogOptions() const {
|
||||
return dialog_options_;
|
||||
}
|
||||
|
||||
void DownloadItem::SetSaveDialogOptions(
|
||||
const file_dialog::DialogSettings& options) {
|
||||
dialog_options_ = options;
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetLastModifiedTime() const {
|
||||
return download_item_->GetLastModifiedTime();
|
||||
}
|
||||
@@ -189,8 +181,8 @@ double DownloadItem::GetStartTime() const {
|
||||
void DownloadItem::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "DownloadItem"));
|
||||
gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("pause", &DownloadItem::Pause)
|
||||
.SetMethod("isPaused", &DownloadItem::IsPaused)
|
||||
.SetMethod("resume", &DownloadItem::Resume)
|
||||
@@ -208,10 +200,6 @@ void DownloadItem::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("isDone", &DownloadItem::IsDone)
|
||||
.SetMethod("setSavePath", &DownloadItem::SetSavePath)
|
||||
.SetMethod("getSavePath", &DownloadItem::GetSavePath)
|
||||
.SetProperty("savePath", &DownloadItem::GetSavePath,
|
||||
&DownloadItem::SetSavePath)
|
||||
.SetMethod("setSaveDialogOptions", &DownloadItem::SetSaveDialogOptions)
|
||||
.SetMethod("getSaveDialogOptions", &DownloadItem::GetSaveDialogOptions)
|
||||
.SetMethod("getLastModifiedTime", &DownloadItem::GetLastModifiedTime)
|
||||
.SetMethod("getETag", &DownloadItem::GetETag)
|
||||
.SetMethod("getStartTime", &DownloadItem::GetStartTime);
|
||||
@@ -234,7 +222,7 @@ mate::Handle<DownloadItem> DownloadItem::Create(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -244,11 +232,10 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary(isolate, exports)
|
||||
.Set("DownloadItem", electron::api::DownloadItem::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
.Set("DownloadItem",
|
||||
atom::api::DownloadItem::GetConstructor(isolate)->GetFunction());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize);
|
||||
@@ -2,20 +2,19 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_DOWNLOAD_ITEM_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_DOWNLOAD_ITEM_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
|
||||
#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"
|
||||
#include "components/download/public/common/download_item.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "shell/browser/api/trackable_object.h"
|
||||
#include "shell/browser/ui/file_dialog.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -45,8 +44,6 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
bool IsDone() const;
|
||||
void SetSavePath(const base::FilePath& path);
|
||||
base::FilePath GetSavePath() const;
|
||||
file_dialog::DialogSettings GetSaveDialogOptions() const;
|
||||
void SetSaveDialogOptions(const file_dialog::DialogSettings& options);
|
||||
std::string GetLastModifiedTime() const;
|
||||
std::string GetETag() const;
|
||||
double GetStartTime() const;
|
||||
@@ -61,7 +58,6 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
|
||||
private:
|
||||
base::FilePath save_path_;
|
||||
file_dialog::DialogSettings dialog_options_;
|
||||
download::DownloadItem* download_item_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
|
||||
@@ -69,6 +65,6 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_DOWNLOAD_ITEM_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
|
||||
@@ -2,19 +2,15 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/browser/api/event_emitter_deprecated.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
namespace {
|
||||
|
||||
v8::Local<v8::Object> CreateWithSender(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> sender) {
|
||||
return mate::internal::CreateJSEvent(isolate, sender, nullptr, base::nullopt);
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> CreateEmpty(v8::Isolate* isolate) {
|
||||
return mate::internal::CreateEmptyJSEvent(isolate);
|
||||
return mate::internal::CreateJSEvent(isolate, sender, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
@@ -23,9 +19,8 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("createWithSender", &CreateWithSender);
|
||||
dict.SetMethod("createEmpty", &CreateEmpty);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_event, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_event, Initialize)
|
||||
@@ -2,51 +2,20 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_global_shortcut.h"
|
||||
#include "atom/browser/api/atom_api_global_shortcut.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "shell/browser/api/electron_api_system_preferences.h"
|
||||
#include "shell/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "shell/common/native_mate_converters/callback_converter_deprecated.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "base/mac/mac_util.h"
|
||||
#endif
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using extensions::GlobalShortcutListener;
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool RegisteringMediaKeyForUntrustedClient(const ui::Accelerator& accelerator) {
|
||||
if (base::mac::IsAtLeastOS10_14()) {
|
||||
constexpr ui::KeyboardCode mediaKeys[] = {
|
||||
ui::VKEY_MEDIA_PLAY_PAUSE, ui::VKEY_MEDIA_NEXT_TRACK,
|
||||
ui::VKEY_MEDIA_PREV_TRACK, ui::VKEY_MEDIA_STOP,
|
||||
ui::VKEY_VOLUME_UP, ui::VKEY_VOLUME_DOWN,
|
||||
ui::VKEY_VOLUME_MUTE};
|
||||
|
||||
if (std::find(std::begin(mediaKeys), std::end(mediaKeys),
|
||||
accelerator.key_code()) != std::end(mediaKeys)) {
|
||||
bool trusted =
|
||||
electron::api::SystemPreferences::IsTrustedAccessibilityClient(false);
|
||||
if (!trusted)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -61,38 +30,16 @@ GlobalShortcut::~GlobalShortcut() {
|
||||
void GlobalShortcut::OnKeyPressed(const ui::Accelerator& accelerator) {
|
||||
if (accelerator_callback_map_.find(accelerator) ==
|
||||
accelerator_callback_map_.end()) {
|
||||
// This should never occur, because if it does, GlobalShortcutListener
|
||||
// notifies us with wrong accelerator.
|
||||
// This should never occur, because if it does, GlobalGlobalShortcutListener
|
||||
// notifes us with wrong accelerator.
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
accelerator_callback_map_[accelerator].Run();
|
||||
}
|
||||
|
||||
bool GlobalShortcut::RegisterAll(
|
||||
const std::vector<ui::Accelerator>& accelerators,
|
||||
const base::Closure& callback) {
|
||||
std::vector<ui::Accelerator> registered;
|
||||
|
||||
for (auto& accelerator : accelerators) {
|
||||
if (!Register(accelerator, callback)) {
|
||||
// unregister all shortcuts if any failed
|
||||
UnregisterSome(registered);
|
||||
return false;
|
||||
}
|
||||
|
||||
registered.push_back(accelerator);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
|
||||
const base::Closure& callback) {
|
||||
#if defined(OS_MACOSX)
|
||||
if (RegisteringMediaKeyForUntrustedClient(accelerator))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator(accelerator,
|
||||
this)) {
|
||||
return false;
|
||||
@@ -103,22 +50,16 @@ bool GlobalShortcut::Register(const ui::Accelerator& accelerator,
|
||||
}
|
||||
|
||||
void GlobalShortcut::Unregister(const ui::Accelerator& accelerator) {
|
||||
if (accelerator_callback_map_.erase(accelerator) == 0)
|
||||
if (!ContainsKey(accelerator_callback_map_, accelerator))
|
||||
return;
|
||||
|
||||
accelerator_callback_map_.erase(accelerator);
|
||||
GlobalShortcutListener::GetInstance()->UnregisterAccelerator(accelerator,
|
||||
this);
|
||||
}
|
||||
|
||||
void GlobalShortcut::UnregisterSome(
|
||||
const std::vector<ui::Accelerator>& accelerators) {
|
||||
for (auto& accelerator : accelerators) {
|
||||
Unregister(accelerator);
|
||||
}
|
||||
}
|
||||
|
||||
bool GlobalShortcut::IsRegistered(const ui::Accelerator& accelerator) {
|
||||
return base::Contains(accelerator_callback_map_, accelerator);
|
||||
return ContainsKey(accelerator_callback_map_, accelerator);
|
||||
}
|
||||
|
||||
void GlobalShortcut::UnregisterAll() {
|
||||
@@ -136,7 +77,6 @@ void GlobalShortcut::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "GlobalShortcut"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("registerAll", &GlobalShortcut::RegisterAll)
|
||||
.SetMethod("register", &GlobalShortcut::Register)
|
||||
.SetMethod("isRegistered", &GlobalShortcut::IsRegistered)
|
||||
.SetMethod("unregister", &GlobalShortcut::Unregister)
|
||||
@@ -145,7 +85,7 @@ void GlobalShortcut::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -155,9 +95,9 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("globalShortcut", electron::api::GlobalShortcut::Create(isolate));
|
||||
dict.Set("globalShortcut", atom::api::GlobalShortcut::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
|
||||
@@ -2,20 +2,19 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_GLOBAL_SHORTCUT_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_GLOBAL_SHORTCUT_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/callback.h"
|
||||
#include "chrome/browser/extensions/global_shortcut_listener.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "shell/browser/api/trackable_object.h"
|
||||
#include "ui/base/accelerators/accelerator.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -34,13 +33,10 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||
private:
|
||||
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;
|
||||
|
||||
bool RegisterAll(const std::vector<ui::Accelerator>& accelerators,
|
||||
const base::Closure& callback);
|
||||
bool Register(const ui::Accelerator& accelerator,
|
||||
const base::Closure& callback);
|
||||
bool IsRegistered(const ui::Accelerator& accelerator);
|
||||
void Unregister(const ui::Accelerator& accelerator);
|
||||
void UnregisterSome(const std::vector<ui::Accelerator>& accelerators);
|
||||
void UnregisterAll();
|
||||
|
||||
// GlobalShortcutListener::Observer implementation.
|
||||
@@ -53,6 +49,6 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_GLOBAL_SHORTCUT_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_GLOBAL_SHORTCUT_H_
|
||||
@@ -2,23 +2,24 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_in_app_purchase.h"
|
||||
#include "atom/browser/api/atom_api_in_app_purchase.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
namespace gin {
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<in_app_purchase::Payment> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const in_app_purchase::Payment& payment) {
|
||||
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("productIdentifier", payment.productIdentifier);
|
||||
dict.Set("quantity", payment.quantity);
|
||||
@@ -30,7 +31,7 @@ template <>
|
||||
struct Converter<in_app_purchase::Transaction> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const in_app_purchase::Transaction& val) {
|
||||
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("transactionIdentifier", val.transactionIdentifier);
|
||||
dict.Set("transactionDate", val.transactionDate);
|
||||
@@ -48,7 +49,7 @@ template <>
|
||||
struct Converter<in_app_purchase::Product> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const in_app_purchase::Product& val) {
|
||||
gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.SetHidden("simple", true);
|
||||
dict.Set("productIdentifier", val.productIdentifier);
|
||||
dict.Set("localizedDescription", val.localizedDescription);
|
||||
@@ -61,29 +62,29 @@ struct Converter<in_app_purchase::Product> {
|
||||
dict.Set("formattedPrice", val.formattedPrice);
|
||||
|
||||
// Downloadable Content Information
|
||||
dict.Set("isDownloadable", val.isDownloadable);
|
||||
dict.Set("isDownloadable", val.downloadable);
|
||||
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// static
|
||||
gin::Handle<InAppPurchase> InAppPurchase::Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new InAppPurchase(isolate));
|
||||
mate::Handle<InAppPurchase> InAppPurchase::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new InAppPurchase(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "InAppPurchase"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "InAppPurchase"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("canMakePayments", &in_app_purchase::CanMakePayments)
|
||||
.SetMethod("getReceiptURL", &in_app_purchase::GetReceiptURL)
|
||||
.SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct)
|
||||
@@ -91,7 +92,7 @@ void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
|
||||
&in_app_purchase::FinishAllTransactions)
|
||||
.SetMethod("finishTransactionByDate",
|
||||
&in_app_purchase::FinishTransactionByDate)
|
||||
.SetMethod("getProducts", &InAppPurchase::GetProducts);
|
||||
.SetMethod("getProducts", &in_app_purchase::GetProducts);
|
||||
}
|
||||
|
||||
InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
|
||||
@@ -100,38 +101,13 @@ InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
|
||||
|
||||
InAppPurchase::~InAppPurchase() {}
|
||||
|
||||
v8::Local<v8::Promise> InAppPurchase::PurchaseProduct(
|
||||
const std::string& product_id,
|
||||
gin::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
electron::util::Promise<bool> promise(isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
void InAppPurchase::PurchaseProduct(const std::string& product_id,
|
||||
mate::Arguments* args) {
|
||||
int quantity = 1;
|
||||
in_app_purchase::InAppPurchaseCallback callback;
|
||||
args->GetNext(&quantity);
|
||||
|
||||
in_app_purchase::PurchaseProduct(
|
||||
product_id, quantity,
|
||||
base::BindOnce(util::Promise<bool>::ResolvePromise, std::move(promise)));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise> InAppPurchase::GetProducts(
|
||||
const std::vector<std::string>& productIDs,
|
||||
gin::Arguments* args) {
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
electron::util::Promise<std::vector<in_app_purchase::Product>> promise(
|
||||
isolate);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
in_app_purchase::GetProducts(
|
||||
productIDs,
|
||||
base::BindOnce(
|
||||
util::Promise<std::vector<in_app_purchase::Product>>::ResolvePromise,
|
||||
std::move(promise)));
|
||||
|
||||
return handle;
|
||||
args->GetNext(&callback);
|
||||
in_app_purchase::PurchaseProduct(product_id, quantity, callback);
|
||||
}
|
||||
|
||||
void InAppPurchase::OnTransactionsUpdated(
|
||||
@@ -142,11 +118,11 @@ void InAppPurchase::OnTransactionsUpdated(
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::InAppPurchase;
|
||||
using atom::api::InAppPurchase;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
@@ -154,14 +130,13 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
void* priv) {
|
||||
#if defined(OS_MACOSX)
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("inAppPurchase", InAppPurchase::Create(isolate));
|
||||
dict.Set("InAppPurchase", InAppPurchase::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
dict.Set("InAppPurchase",
|
||||
InAppPurchase::GetConstructor(isolate)->GetFunction());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)
|
||||
47
atom/browser/api/atom_api_in_app_purchase.h
Normal file
47
atom/browser/api/atom_api_in_app_purchase.h
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2017 Amaplex Software, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/mac/in_app_purchase.h"
|
||||
#include "atom/browser/mac/in_app_purchase_observer.h"
|
||||
#include "atom/browser/mac/in_app_purchase_product.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class InAppPurchase : public mate::EventEmitter<InAppPurchase>,
|
||||
public in_app_purchase::TransactionObserver {
|
||||
public:
|
||||
static mate::Handle<InAppPurchase> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit InAppPurchase(v8::Isolate* isolate);
|
||||
~InAppPurchase() override;
|
||||
|
||||
void PurchaseProduct(const std::string& product_id, mate::Arguments* args);
|
||||
|
||||
// TransactionObserver:
|
||||
void OnTransactionsUpdated(
|
||||
const std::vector<in_app_purchase::Transaction>& transactions) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(InAppPurchase);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_IN_APP_PURCHASE_H_
|
||||
@@ -2,35 +2,26 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_menu.h"
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/image_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/native_mate_converters/accelerator_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
namespace {
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
// We need this map to keep references to currently opened menus.
|
||||
// Without this menus would be destroyed by js garbage collector
|
||||
// even when they are still displayed.
|
||||
std::map<uint32_t, v8::Global<v8::Object>> g_menus;
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Menu::Menu(gin::Arguments* args) : model_(new ElectronMenuModel(this)) {
|
||||
InitWithArgs(args);
|
||||
Menu::Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||
: model_(new AtomMenuModel(this)) {
|
||||
InitWith(isolate, wrapper);
|
||||
model_->AddObserver(this);
|
||||
}
|
||||
|
||||
@@ -41,18 +32,15 @@ Menu::~Menu() {
|
||||
}
|
||||
|
||||
void Menu::AfterInit(v8::Isolate* isolate) {
|
||||
gin::Dictionary wrappable(isolate, GetWrapper());
|
||||
gin::Dictionary delegate(nullptr);
|
||||
mate::Dictionary wrappable(isolate, GetWrapper());
|
||||
mate::Dictionary delegate;
|
||||
if (!wrappable.Get("delegate", &delegate))
|
||||
return;
|
||||
|
||||
delegate.Get("isCommandIdChecked", &is_checked_);
|
||||
delegate.Get("isCommandIdEnabled", &is_enabled_);
|
||||
delegate.Get("isCommandIdVisible", &is_visible_);
|
||||
delegate.Get("shouldCommandIdWorkWhenHidden", &works_when_hidden_);
|
||||
delegate.Get("getAcceleratorForCommandId", &get_accelerator_);
|
||||
delegate.Get("shouldRegisterAcceleratorForCommandId",
|
||||
&should_register_accelerator_);
|
||||
delegate.Get("executeCommand", &execute_command_);
|
||||
delegate.Get("menuWillShow", &menu_will_show_);
|
||||
}
|
||||
@@ -75,12 +63,6 @@ bool Menu::IsCommandIdVisible(int command_id) const {
|
||||
return is_visible_.Run(GetWrapper(), command_id);
|
||||
}
|
||||
|
||||
bool Menu::ShouldCommandIdWorkWhenHidden(int command_id) const {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return works_when_hidden_.Run(GetWrapper(), command_id);
|
||||
}
|
||||
|
||||
bool Menu::GetAcceleratorForCommandIdWithParams(
|
||||
int command_id,
|
||||
bool use_default_accelerator,
|
||||
@@ -92,12 +74,6 @@ bool Menu::GetAcceleratorForCommandIdWithParams(
|
||||
return mate::ConvertFromV8(isolate(), val, accelerator);
|
||||
}
|
||||
|
||||
bool Menu::ShouldRegisterAcceleratorForCommandId(int command_id) const {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
return should_register_accelerator_.Run(GetWrapper(), command_id);
|
||||
}
|
||||
|
||||
void Menu::ExecuteCommand(int command_id, int flags) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
@@ -106,7 +82,7 @@ void Menu::ExecuteCommand(int command_id, int flags) {
|
||||
command_id);
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillShow(ui::SimpleMenuModel* source) {
|
||||
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
menu_will_show_.Run(GetWrapper());
|
||||
@@ -151,10 +127,6 @@ void Menu::SetSublabel(int index, const base::string16& sublabel) {
|
||||
model_->SetSublabel(index, sublabel);
|
||||
}
|
||||
|
||||
void Menu::SetToolTip(int index, const base::string16& toolTip) {
|
||||
model_->SetToolTip(index, toolTip);
|
||||
}
|
||||
|
||||
void Menu::SetRole(int index, const base::string16& role) {
|
||||
model_->SetRole(index, role);
|
||||
}
|
||||
@@ -183,16 +155,6 @@ base::string16 Menu::GetSublabelAt(int index) const {
|
||||
return model_->GetSublabelAt(index);
|
||||
}
|
||||
|
||||
base::string16 Menu::GetToolTipAt(int index) const {
|
||||
return model_->GetToolTipAt(index);
|
||||
}
|
||||
|
||||
base::string16 Menu::GetAcceleratorTextAt(int index) const {
|
||||
ui::Accelerator accelerator;
|
||||
model_->GetAcceleratorAtWithParams(index, true, &accelerator);
|
||||
return accelerator.GetShortcutText();
|
||||
}
|
||||
|
||||
bool Menu::IsItemCheckedAt(int index) const {
|
||||
return model_->IsItemCheckedAt(index);
|
||||
}
|
||||
@@ -205,36 +167,20 @@ bool Menu::IsVisibleAt(int index) const {
|
||||
return model_->IsVisibleAt(index);
|
||||
}
|
||||
|
||||
bool Menu::WorksWhenHiddenAt(int index) const {
|
||||
return model_->WorksWhenHiddenAt(index);
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillClose() {
|
||||
g_menus.erase(weak_map_id());
|
||||
Emit("menu-will-close");
|
||||
}
|
||||
|
||||
void Menu::OnMenuWillShow() {
|
||||
g_menus[weak_map_id()] = v8::Global<v8::Object>(isolate(), GetWrapper());
|
||||
Emit("menu-will-show");
|
||||
}
|
||||
|
||||
base::OnceClosure Menu::BindSelfToClosure(base::OnceClosure callback) {
|
||||
// return ((callback, ref) => { callback() }).bind(null, callback, this)
|
||||
v8::Global<v8::Value> ref(isolate(), GetWrapper());
|
||||
return base::BindOnce(
|
||||
[](base::OnceClosure callback, v8::Global<v8::Value> ref) {
|
||||
std::move(callback).Run();
|
||||
},
|
||||
std::move(callback), std::move(ref));
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "Menu"));
|
||||
gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Menu"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("insertItem", &Menu::InsertItemAt)
|
||||
.SetMethod("insertCheckItem", &Menu::InsertCheckItemAt)
|
||||
.SetMethod("insertRadioItem", &Menu::InsertRadioItemAt)
|
||||
@@ -242,7 +188,6 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("insertSubMenu", &Menu::InsertSubMenuAt)
|
||||
.SetMethod("setIcon", &Menu::SetIcon)
|
||||
.SetMethod("setSublabel", &Menu::SetSublabel)
|
||||
.SetMethod("setToolTip", &Menu::SetToolTip)
|
||||
.SetMethod("setRole", &Menu::SetRole)
|
||||
.SetMethod("clear", &Menu::Clear)
|
||||
.SetMethod("getIndexOfCommandId", &Menu::GetIndexOfCommandId)
|
||||
@@ -250,11 +195,8 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getCommandIdAt", &Menu::GetCommandIdAt)
|
||||
.SetMethod("getLabelAt", &Menu::GetLabelAt)
|
||||
.SetMethod("getSublabelAt", &Menu::GetSublabelAt)
|
||||
.SetMethod("getToolTipAt", &Menu::GetToolTipAt)
|
||||
.SetMethod("getAcceleratorTextAt", &Menu::GetAcceleratorTextAt)
|
||||
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
|
||||
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
|
||||
.SetMethod("worksWhenHiddenAt", &Menu::WorksWhenHiddenAt)
|
||||
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
|
||||
.SetMethod("popupAt", &Menu::PopupAt)
|
||||
.SetMethod("closePopupAt", &Menu::ClosePopupAt);
|
||||
@@ -262,23 +204,21 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::Menu;
|
||||
using atom::api::Menu;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
Menu::SetConstructor(isolate, base::BindRepeating(&Menu::New));
|
||||
Menu::SetConstructor(isolate, base::Bind(&Menu::New));
|
||||
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
dict.Set(
|
||||
"Menu",
|
||||
Menu::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Menu", Menu::GetConstructor(isolate)->GetFunction());
|
||||
#if defined(OS_MACOSX)
|
||||
dict.SetMethod("setApplicationMenu", &Menu::SetApplicationMenu);
|
||||
dict.SetMethod("sendActionToFirstResponder",
|
||||
@@ -288,4 +228,4 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
|
||||
@@ -2,27 +2,26 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_MENU_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_MENU_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/atom_api_top_level_window.h"
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/ui/atom_menu_model.h"
|
||||
#include "base/callback.h"
|
||||
#include "gin/arguments.h"
|
||||
#include "shell/browser/api/electron_api_top_level_window.h"
|
||||
#include "shell/browser/api/trackable_object.h"
|
||||
#include "shell/browser/ui/electron_menu_model.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Menu : public mate::TrackableObject<Menu>,
|
||||
public ElectronMenuModel::Delegate,
|
||||
public ElectronMenuModel::Observer {
|
||||
public AtomMenuModel::Delegate,
|
||||
public AtomMenuModel::Observer {
|
||||
public:
|
||||
static mate::WrappableBase* New(gin::Arguments* args);
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
@@ -35,10 +34,10 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
static void SendActionToFirstResponder(const std::string& action);
|
||||
#endif
|
||||
|
||||
ElectronMenuModel* model() const { return model_.get(); }
|
||||
AtomMenuModel* model() const { return model_.get(); }
|
||||
|
||||
protected:
|
||||
explicit Menu(gin::Arguments* args);
|
||||
Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
~Menu() override;
|
||||
|
||||
// mate::Wrappable:
|
||||
@@ -48,34 +47,27 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
bool IsCommandIdChecked(int command_id) const override;
|
||||
bool IsCommandIdEnabled(int command_id) const override;
|
||||
bool IsCommandIdVisible(int command_id) const override;
|
||||
bool ShouldCommandIdWorkWhenHidden(int command_id) const override;
|
||||
bool GetAcceleratorForCommandIdWithParams(
|
||||
int command_id,
|
||||
bool use_default_accelerator,
|
||||
ui::Accelerator* accelerator) const override;
|
||||
bool ShouldRegisterAcceleratorForCommandId(int command_id) const override;
|
||||
void ExecuteCommand(int command_id, int event_flags) override;
|
||||
void OnMenuWillShow(ui::SimpleMenuModel* source) override;
|
||||
void MenuWillShow(ui::SimpleMenuModel* source) override;
|
||||
|
||||
virtual void PopupAt(TopLevelWindow* window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) = 0;
|
||||
const base::Closure& callback) = 0;
|
||||
virtual void ClosePopupAt(int32_t window_id) = 0;
|
||||
|
||||
std::unique_ptr<ElectronMenuModel> model_;
|
||||
std::unique_ptr<AtomMenuModel> model_;
|
||||
Menu* parent_ = nullptr;
|
||||
|
||||
// Observable:
|
||||
void OnMenuWillClose() override;
|
||||
void OnMenuWillShow() override;
|
||||
|
||||
protected:
|
||||
// Returns a new callback which keeps references of the JS wrapper until the
|
||||
// passed |callback| is called.
|
||||
base::OnceClosure BindSelfToClosure(base::OnceClosure callback);
|
||||
|
||||
private:
|
||||
void InsertItemAt(int index, int command_id, const base::string16& label);
|
||||
void InsertSeparatorAt(int index);
|
||||
@@ -92,7 +84,6 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
Menu* menu);
|
||||
void SetIcon(int index, const gfx::Image& image);
|
||||
void SetSublabel(int index, const base::string16& sublabel);
|
||||
void SetToolTip(int index, const base::string16& toolTip);
|
||||
void SetRole(int index, const base::string16& role);
|
||||
void Clear();
|
||||
int GetIndexOfCommandId(int command_id);
|
||||
@@ -100,48 +91,42 @@ class Menu : public mate::TrackableObject<Menu>,
|
||||
int GetCommandIdAt(int index) const;
|
||||
base::string16 GetLabelAt(int index) const;
|
||||
base::string16 GetSublabelAt(int index) const;
|
||||
base::string16 GetToolTipAt(int index) const;
|
||||
base::string16 GetAcceleratorTextAt(int index) const;
|
||||
bool IsItemCheckedAt(int index) const;
|
||||
bool IsEnabledAt(int index) const;
|
||||
bool IsVisibleAt(int index) const;
|
||||
bool WorksWhenHiddenAt(int index) const;
|
||||
|
||||
// Stored delegate methods.
|
||||
base::RepeatingCallback<bool(v8::Local<v8::Value>, int)> is_checked_;
|
||||
base::RepeatingCallback<bool(v8::Local<v8::Value>, int)> is_enabled_;
|
||||
base::RepeatingCallback<bool(v8::Local<v8::Value>, int)> is_visible_;
|
||||
base::RepeatingCallback<bool(v8::Local<v8::Value>, int)> works_when_hidden_;
|
||||
base::RepeatingCallback<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)>
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_checked_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_enabled_;
|
||||
base::Callback<bool(v8::Local<v8::Value>, int)> is_visible_;
|
||||
base::Callback<v8::Local<v8::Value>(v8::Local<v8::Value>, int, bool)>
|
||||
get_accelerator_;
|
||||
base::RepeatingCallback<bool(v8::Local<v8::Value>, int)>
|
||||
should_register_accelerator_;
|
||||
base::RepeatingCallback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)>
|
||||
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>, int)>
|
||||
execute_command_;
|
||||
base::RepeatingCallback<void(v8::Local<v8::Value>)> menu_will_show_;
|
||||
base::Callback<void(v8::Local<v8::Value>)> menu_will_show_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Menu);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<electron::ElectronMenuModel*> {
|
||||
struct Converter<atom::AtomMenuModel*> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
electron::ElectronMenuModel** out) {
|
||||
atom::AtomMenuModel** out) {
|
||||
// null would be tranfered to NULL.
|
||||
if (val->IsNull()) {
|
||||
*out = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
electron::api::Menu* menu;
|
||||
if (!Converter<electron::api::Menu*>::FromV8(isolate, val, &menu))
|
||||
atom::api::Menu* menu;
|
||||
if (!Converter<atom::api::Menu*>::FromV8(isolate, val, &menu))
|
||||
return false;
|
||||
*out = menu->model();
|
||||
return true;
|
||||
@@ -150,4 +135,4 @@ struct Converter<electron::ElectronMenuModel*> {
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_MENU_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
@@ -2,50 +2,49 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_MENU_MAC_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_MENU_MAC_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
|
||||
#include "shell/browser/api/electron_api_menu.h"
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#import "shell/browser/ui/cocoa/electron_menu_controller.h"
|
||||
#import "atom/browser/ui/cocoa/atom_menu_controller.h"
|
||||
|
||||
using base::scoped_nsobject;
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuMac : public Menu {
|
||||
protected:
|
||||
explicit MenuMac(gin::Arguments* args);
|
||||
MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
~MenuMac() override;
|
||||
|
||||
void PopupAt(TopLevelWindow* window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) override;
|
||||
const base::Closure& callback) override;
|
||||
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
int32_t window_id,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback);
|
||||
base::Closure callback);
|
||||
void ClosePopupAt(int32_t window_id) override;
|
||||
void ClosePopupOnUI(int32_t window_id);
|
||||
|
||||
private:
|
||||
friend class Menu;
|
||||
|
||||
void OnClosed(int32_t window_id, base::OnceClosure callback);
|
||||
void OnClosed(int32_t window_id, base::Closure callback);
|
||||
|
||||
scoped_nsobject<ElectronMenuController> menu_controller_;
|
||||
scoped_nsobject<AtomMenuController> menu_controller_;
|
||||
|
||||
// window ID -> open context menu
|
||||
std::map<int32_t, scoped_nsobject<ElectronMenuController>> popup_controllers_;
|
||||
std::map<int32_t, scoped_nsobject<AtomMenuController>> popup_controllers_;
|
||||
|
||||
base::WeakPtrFactory<MenuMac> weak_factory_;
|
||||
|
||||
@@ -54,6 +53,6 @@ class MenuMac : public Menu {
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_MENU_MAC_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
@@ -2,21 +2,17 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "shell/browser/api/electron_api_menu_mac.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#import "atom/browser/api/atom_api_menu_mac.h"
|
||||
|
||||
#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_current.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "shell/browser/native_window.h"
|
||||
#include "shell/browser/unresponsive_suppressor.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
@@ -26,11 +22,12 @@ static scoped_nsobject<NSMenu> applicationMenu_;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuMac::MenuMac(gin::Arguments* args) : Menu(args), weak_factory_(this) {}
|
||||
MenuMac::MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||
: Menu(isolate, wrapper), weak_factory_(this) {}
|
||||
|
||||
MenuMac::~MenuMac() = default;
|
||||
|
||||
@@ -38,20 +35,15 @@ void MenuMac::PopupAt(TopLevelWindow* window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) {
|
||||
const base::Closure& callback) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
return;
|
||||
|
||||
// Make sure the Menu object would not be garbage-collected until the callback
|
||||
// has run.
|
||||
base::OnceClosure callback_with_ref = BindSelfToClosure(std::move(callback));
|
||||
|
||||
auto popup =
|
||||
base::BindOnce(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
|
||||
native_window->GetWeakPtr(), window->weak_map_id(), x, y,
|
||||
positioning_item, std::move(callback_with_ref));
|
||||
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(popup));
|
||||
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
|
||||
native_window->GetWeakPtr(), window->weak_map_id(), x,
|
||||
y, positioning_item, callback);
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
|
||||
}
|
||||
|
||||
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
@@ -59,17 +51,16 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) {
|
||||
base::Closure callback) {
|
||||
if (!native_window)
|
||||
return;
|
||||
NSWindow* nswindow = native_window->GetNativeWindow().GetNativeNSWindow();
|
||||
NSWindow* nswindow = native_window->GetNativeWindow();
|
||||
|
||||
base::OnceClosure close_callback =
|
||||
base::BindOnce(&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id,
|
||||
std::move(callback));
|
||||
popup_controllers_[window_id] = base::scoped_nsobject<ElectronMenuController>(
|
||||
[[ElectronMenuController alloc] initWithModel:model()
|
||||
useDefaultAccelerator:NO]);
|
||||
auto close_callback = base::Bind(
|
||||
&MenuMac::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||
popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>([
|
||||
[AtomMenuController alloc] initWithModel:model()
|
||||
useDefaultAccelerator:NO]);
|
||||
NSMenu* menu = [popup_controllers_[window_id] menu];
|
||||
NSView* view = [nswindow contentView];
|
||||
|
||||
@@ -104,9 +95,9 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
if (rightmostMenuPoint > screenRight)
|
||||
position.x = position.x - [menu size].width;
|
||||
|
||||
[popup_controllers_[window_id] setCloseCallback:std::move(close_callback)];
|
||||
[popup_controllers_[window_id] setCloseCallback:close_callback];
|
||||
// Make sure events can be pumped while the menu is up.
|
||||
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
|
||||
base::MessageLoop::ScopedNestableTaskAllower allow;
|
||||
|
||||
// One of the events that could be pumped is |window.close()|.
|
||||
// User-initiated event-tracking loops protect against this by
|
||||
@@ -116,18 +107,11 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
base::mac::ScopedSendingEvent sendingEventScoper;
|
||||
|
||||
// Don't emit unresponsive event when showing menu.
|
||||
electron::UnresponsiveSuppressor suppressor;
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
|
||||
}
|
||||
|
||||
void MenuMac::ClosePopupAt(int32_t window_id) {
|
||||
auto close_popup = base::BindOnce(&MenuMac::ClosePopupOnUI,
|
||||
weak_factory_.GetWeakPtr(), window_id);
|
||||
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
|
||||
std::move(close_popup));
|
||||
}
|
||||
|
||||
void MenuMac::ClosePopupOnUI(int32_t window_id) {
|
||||
auto controller = popup_controllers_.find(window_id);
|
||||
if (controller != popup_controllers_.end()) {
|
||||
// Close the controller for the window.
|
||||
@@ -142,17 +126,17 @@ void MenuMac::ClosePopupOnUI(int32_t window_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void MenuMac::OnClosed(int32_t window_id, base::OnceClosure callback) {
|
||||
void MenuMac::OnClosed(int32_t window_id, base::Closure callback) {
|
||||
popup_controllers_.erase(window_id);
|
||||
std::move(callback).Run();
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::SetApplicationMenu(Menu* base_menu) {
|
||||
MenuMac* menu = static_cast<MenuMac*>(base_menu);
|
||||
base::scoped_nsobject<ElectronMenuController> menu_controller(
|
||||
[[ElectronMenuController alloc] initWithModel:menu->model_.get()
|
||||
useDefaultAccelerator:YES]);
|
||||
base::scoped_nsobject<AtomMenuController> menu_controller([
|
||||
[AtomMenuController alloc] initWithModel:menu->model_.get()
|
||||
useDefaultAccelerator:YES]);
|
||||
|
||||
NSRunLoop* currentRunLoop = [NSRunLoop currentRunLoop];
|
||||
[currentRunLoop cancelPerformSelector:@selector(setMainMenu:)
|
||||
@@ -177,10 +161,10 @@ void Menu::SendActionToFirstResponder(const std::string& action) {
|
||||
}
|
||||
|
||||
// static
|
||||
mate::WrappableBase* Menu::New(gin::Arguments* args) {
|
||||
return new MenuMac(args);
|
||||
mate::WrappableBase* Menu::New(mate::Arguments* args) {
|
||||
return new MenuMac(args->isolate(), args->GetThis());
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,22 +2,22 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_menu_views.h"
|
||||
#include "atom/browser/api/atom_api_menu_views.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "shell/browser/unresponsive_suppressor.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "atom/browser/unresponsive_suppressor.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
using views::MenuRunner;
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuViews::MenuViews(gin::Arguments* args) : Menu(args), weak_factory_(this) {}
|
||||
MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
|
||||
: Menu(isolate, wrapper), weak_factory_(this) {}
|
||||
|
||||
MenuViews::~MenuViews() = default;
|
||||
|
||||
@@ -25,7 +25,7 @@ void MenuViews::PopupAt(TopLevelWindow* window,
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) {
|
||||
const base::Closure& callback) {
|
||||
auto* native_window = static_cast<NativeWindowViews*>(window->window());
|
||||
if (!native_window)
|
||||
return;
|
||||
@@ -42,26 +42,17 @@ void MenuViews::PopupAt(TopLevelWindow* window,
|
||||
int flags = MenuRunner::CONTEXT_MENU | MenuRunner::HAS_MNEMONICS;
|
||||
|
||||
// Don't emit unresponsive event when showing menu.
|
||||
electron::UnresponsiveSuppressor suppressor;
|
||||
|
||||
// Make sure the Menu object would not be garbage-collected until the callback
|
||||
// has run.
|
||||
base::OnceClosure callback_with_ref = BindSelfToClosure(std::move(callback));
|
||||
atom::UnresponsiveSuppressor suppressor;
|
||||
|
||||
// Show the menu.
|
||||
//
|
||||
// Note that while views::MenuRunner accepts RepeatingCallback as close
|
||||
// callback, it is fine passing OnceCallback to it because we reset the
|
||||
// menu runner immediately when the menu is closed.
|
||||
int32_t window_id = window->weak_map_id();
|
||||
auto close_callback = base::AdaptCallbackForRepeating(
|
||||
base::BindOnce(&MenuViews::OnClosed, weak_factory_.GetWeakPtr(),
|
||||
window_id, std::move(callback_with_ref)));
|
||||
auto close_callback = base::Bind(
|
||||
&MenuViews::OnClosed, weak_factory_.GetWeakPtr(), window_id, callback);
|
||||
menu_runners_[window_id] =
|
||||
std::make_unique<MenuRunner>(model(), flags, std::move(close_callback));
|
||||
std::make_unique<MenuRunner>(model(), flags, close_callback);
|
||||
menu_runners_[window_id]->RunMenuAt(
|
||||
native_window->widget(), nullptr, gfx::Rect(location, gfx::Size()),
|
||||
views::MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_MOUSE);
|
||||
native_window->widget(), NULL, gfx::Rect(location, gfx::Size()),
|
||||
views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE);
|
||||
}
|
||||
|
||||
void MenuViews::ClosePopupAt(int32_t window_id) {
|
||||
@@ -78,16 +69,16 @@ void MenuViews::ClosePopupAt(int32_t window_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void MenuViews::OnClosed(int32_t window_id, base::OnceClosure callback) {
|
||||
void MenuViews::OnClosed(int32_t window_id, base::Closure callback) {
|
||||
menu_runners_.erase(window_id);
|
||||
std::move(callback).Run();
|
||||
callback.Run();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::WrappableBase* Menu::New(gin::Arguments* args) {
|
||||
return new MenuViews(args);
|
||||
mate::WrappableBase* Menu::New(mate::Arguments* args) {
|
||||
return new MenuViews(args->isolate(), args->GetThis());
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,24 +2,24 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_MENU_VIEWS_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_MENU_VIEWS_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "shell/browser/api/electron_api_menu.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/views/controls/menu/menu_runner.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuViews : public Menu {
|
||||
public:
|
||||
explicit MenuViews(gin::Arguments* args);
|
||||
MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
~MenuViews() override;
|
||||
|
||||
protected:
|
||||
@@ -27,11 +27,11 @@ class MenuViews : public Menu {
|
||||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
base::OnceClosure callback) override;
|
||||
const base::Closure& callback) override;
|
||||
void ClosePopupAt(int32_t window_id) override;
|
||||
|
||||
private:
|
||||
void OnClosed(int32_t window_id, base::OnceClosure callback);
|
||||
void OnClosed(int32_t window_id, base::Closure callback);
|
||||
|
||||
// window ID -> open context menu
|
||||
std::map<int32_t, std::unique_ptr<views::MenuRunner>> menu_runners_;
|
||||
@@ -43,6 +43,6 @@ class MenuViews : public Menu {
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_MENU_VIEWS_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
|
||||
61
atom/browser/api/atom_api_net.cc
Normal file
61
atom/browser/api/atom_api_net.cc
Normal file
@@ -0,0 +1,61 @@
|
||||
// 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_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)
|
||||
@@ -2,12 +2,12 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_NET_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_NET_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_NET_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_NET_H_
|
||||
|
||||
#include "shell/browser/api/event_emitter_deprecated.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -18,7 +18,7 @@ class Net : public mate::EventEmitter<Net> {
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
v8::Local<v8::Value> URLLoader(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> URLRequest(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
explicit Net(v8::Isolate* isolate);
|
||||
@@ -30,6 +30,6 @@ class Net : public mate::EventEmitter<Net> {
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_NET_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_NET_H_
|
||||
138
atom/browser/api/atom_api_net_log.cc
Normal file
138
atom/browser/api/atom_api_net_log.cc
Normal file
@@ -0,0 +1,138 @@
|
||||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_net_log.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "base/command_line.h"
|
||||
#include "components/net_log/chrome_net_log.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
NetLog::NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
Init(isolate);
|
||||
|
||||
net_log_writer_ =
|
||||
atom::AtomBrowserMainParts::Get()->net_log()->net_export_file_writer();
|
||||
net_log_writer_->AddObserver(this);
|
||||
}
|
||||
|
||||
NetLog::~NetLog() {
|
||||
net_log_writer_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void NetLog::StartLogging(mate::Arguments* args) {
|
||||
base::FilePath log_path;
|
||||
if (!args->GetNext(&log_path) || log_path.empty()) {
|
||||
args->ThrowError("The first parameter must be a valid string");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* network_context =
|
||||
content::BrowserContext::GetDefaultStoragePartition(browser_context_)
|
||||
->GetNetworkContext();
|
||||
|
||||
// TODO(deepak1556): Provide more flexibility to this module
|
||||
// by allowing customizations on the capturing options.
|
||||
net_log_writer_->StartNetLog(
|
||||
log_path, net::NetLogCaptureMode::Default(),
|
||||
net_log::NetExportFileWriter::kNoLimit /* file size limit */,
|
||||
base::CommandLine::ForCurrentProcess()->GetCommandLineString(),
|
||||
std::string(), network_context);
|
||||
}
|
||||
|
||||
std::string NetLog::GetLoggingState() const {
|
||||
if (!net_log_state_)
|
||||
return std::string();
|
||||
const base::Value* current_log_state =
|
||||
net_log_state_->FindKeyOfType("state", base::Value::Type::STRING);
|
||||
if (!current_log_state)
|
||||
return std::string();
|
||||
return current_log_state->GetString();
|
||||
}
|
||||
|
||||
bool NetLog::IsCurrentlyLogging() const {
|
||||
const std::string log_state = GetLoggingState();
|
||||
return (log_state == "STARTING_LOG") || (log_state == "LOGGING");
|
||||
}
|
||||
|
||||
std::string NetLog::GetCurrentlyLoggingPath() const {
|
||||
// Net log exporter has a default path which will be used
|
||||
// when no log path is provided, but since we don't allow
|
||||
// net log capture without user provided file path, this
|
||||
// check is completely safe.
|
||||
if (IsCurrentlyLogging()) {
|
||||
const base::Value* current_log_path =
|
||||
net_log_state_->FindKeyOfType("file", base::Value::Type::STRING);
|
||||
if (current_log_path)
|
||||
return current_log_path->GetString();
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void NetLog::StopLogging(mate::Arguments* args) {
|
||||
net_log::NetExportFileWriter::FilePathCallback callback;
|
||||
if (!args->GetNext(&callback)) {
|
||||
args->ThrowError("Invalid callback function");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsCurrentlyLogging()) {
|
||||
stop_callback_queue_.emplace_back(callback);
|
||||
net_log_writer_->StopNetLog(nullptr);
|
||||
} else {
|
||||
callback.Run(base::FilePath());
|
||||
}
|
||||
}
|
||||
|
||||
void NetLog::OnNewState(const base::DictionaryValue& state) {
|
||||
net_log_state_ = state.CreateDeepCopy();
|
||||
|
||||
if (stop_callback_queue_.empty())
|
||||
return;
|
||||
|
||||
if (GetLoggingState() == "NOT_LOGGING") {
|
||||
for (auto& callback : stop_callback_queue_) {
|
||||
if (!callback.is_null())
|
||||
net_log_writer_->GetFilePathToCompletedLog(callback);
|
||||
}
|
||||
stop_callback_queue_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<NetLog> NetLog::Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new NetLog(isolate, browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
void NetLog::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "NetLog"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetProperty("currentlyLogging", &NetLog::IsCurrentlyLogging)
|
||||
.SetProperty("currentlyLoggingPath", &NetLog::GetCurrentlyLoggingPath)
|
||||
.SetMethod("startLogging", &NetLog::StartLogging)
|
||||
.SetMethod("stopLogging", &NetLog::StopLogging);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
60
atom/browser/api/atom_api_net_log.h
Normal file
60
atom/browser/api/atom_api_net_log.h
Normal file
@@ -0,0 +1,60 @@
|
||||
// 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_BROWSER_API_ATOM_API_NET_LOG_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/values.h"
|
||||
#include "components/net_log/net_export_file_writer.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
|
||||
namespace api {
|
||||
|
||||
class NetLog : public mate::TrackableObject<NetLog>,
|
||||
public net_log::NetExportFileWriter::StateObserver {
|
||||
public:
|
||||
static mate::Handle<NetLog> Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
void StartLogging(mate::Arguments* args);
|
||||
std::string GetLoggingState() const;
|
||||
bool IsCurrentlyLogging() const;
|
||||
std::string GetCurrentlyLoggingPath() const;
|
||||
void StopLogging(mate::Arguments* args);
|
||||
|
||||
protected:
|
||||
explicit NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~NetLog() override;
|
||||
|
||||
// net_log::NetExportFileWriter::StateObserver implementation
|
||||
void OnNewState(const base::DictionaryValue& state) override;
|
||||
|
||||
private:
|
||||
AtomBrowserContext* browser_context_;
|
||||
net_log::NetExportFileWriter* net_log_writer_;
|
||||
std::list<net_log::NetExportFileWriter::FilePathCallback>
|
||||
stop_callback_queue_;
|
||||
std::unique_ptr<base::DictionaryValue> net_log_state_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NetLog);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
|
||||
@@ -2,28 +2,31 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_notification.h"
|
||||
#include "atom/browser/api/atom_api_notification.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_menu.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "brightray/browser/browser_client.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "shell/browser/api/electron_api_menu.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/electron_browser_client.h"
|
||||
#include "shell/common/gin_converters/image_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "url/gurl.h"
|
||||
// Must be the last in the includes list.
|
||||
// See https://github.com/electron/electron/issues/10363
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
namespace mate {
|
||||
template <>
|
||||
struct Converter<electron::NotificationAction> {
|
||||
struct Converter<brightray::NotificationAction> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
electron::NotificationAction* out) {
|
||||
gin::Dictionary dict(isolate);
|
||||
brightray::NotificationAction* out) {
|
||||
mate::Dictionary dict;
|
||||
if (!ConvertFromV8(isolate, val, &dict))
|
||||
return false;
|
||||
|
||||
@@ -35,27 +38,27 @@ struct Converter<electron::NotificationAction> {
|
||||
}
|
||||
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
electron::NotificationAction val) {
|
||||
gin::Dictionary dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
brightray::NotificationAction val) {
|
||||
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("text", val.text);
|
||||
dict.Set("type", val.type);
|
||||
return ConvertToV8(isolate, dict);
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
} // namespace mate
|
||||
|
||||
} // namespace gin
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
Notification::Notification(gin::Arguments* args) {
|
||||
InitWithArgs(args);
|
||||
Notification::Notification(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
mate::Arguments* args) {
|
||||
InitWith(isolate, wrapper);
|
||||
|
||||
presenter_ = static_cast<ElectronBrowserClient*>(ElectronBrowserClient::Get())
|
||||
->GetNotificationPresenter();
|
||||
presenter_ = brightray::BrowserClient::Get()->GetNotificationPresenter();
|
||||
|
||||
gin::Dictionary opts(nullptr);
|
||||
mate::Dictionary opts;
|
||||
if (args->GetNext(&opts)) {
|
||||
opts.Get("title", &title_);
|
||||
opts.Get("subtitle", &subtitle_);
|
||||
@@ -66,9 +69,7 @@ Notification::Notification(gin::Arguments* args) {
|
||||
}
|
||||
opts.Get("silent", &silent_);
|
||||
opts.Get("replyPlaceholder", &reply_placeholder_);
|
||||
opts.Get("urgency", &urgency_);
|
||||
opts.Get("hasReply", &has_reply_);
|
||||
opts.Get("timeoutType", &timeout_type_);
|
||||
opts.Get("actions", &actions_);
|
||||
opts.Get("sound", &sound_);
|
||||
opts.Get("closeButtonText", &close_button_text_);
|
||||
@@ -81,13 +82,12 @@ Notification::~Notification() {
|
||||
}
|
||||
|
||||
// static
|
||||
mate::WrappableBase* Notification::New(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args) {
|
||||
mate::WrappableBase* Notification::New(mate::Arguments* args) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
thrower.ThrowError("Cannot create Notification before app is ready");
|
||||
args->ThrowError("Cannot create Notification before app is ready");
|
||||
return nullptr;
|
||||
}
|
||||
return new Notification(args);
|
||||
return new Notification(args->isolate(), args->GetThis(), args);
|
||||
}
|
||||
|
||||
// Getters
|
||||
@@ -111,10 +111,6 @@ bool Notification::GetHasReply() const {
|
||||
return has_reply_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetTimeoutType() const {
|
||||
return timeout_type_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetReplyPlaceholder() const {
|
||||
return reply_placeholder_;
|
||||
}
|
||||
@@ -123,11 +119,7 @@ base::string16 Notification::GetSound() const {
|
||||
return sound_;
|
||||
}
|
||||
|
||||
base::string16 Notification::GetUrgency() const {
|
||||
return urgency_;
|
||||
}
|
||||
|
||||
std::vector<electron::NotificationAction> Notification::GetActions() const {
|
||||
std::vector<brightray::NotificationAction> Notification::GetActions() const {
|
||||
return actions_;
|
||||
}
|
||||
|
||||
@@ -156,10 +148,6 @@ void Notification::SetHasReply(bool new_has_reply) {
|
||||
has_reply_ = new_has_reply;
|
||||
}
|
||||
|
||||
void Notification::SetTimeoutType(const base::string16& new_timeout_type) {
|
||||
timeout_type_ = new_timeout_type;
|
||||
}
|
||||
|
||||
void Notification::SetReplyPlaceholder(const base::string16& new_placeholder) {
|
||||
reply_placeholder_ = new_placeholder;
|
||||
}
|
||||
@@ -168,12 +156,8 @@ void Notification::SetSound(const base::string16& new_sound) {
|
||||
sound_ = new_sound;
|
||||
}
|
||||
|
||||
void Notification::SetUrgency(const base::string16& new_urgency) {
|
||||
urgency_ = new_urgency;
|
||||
}
|
||||
|
||||
void Notification::SetActions(
|
||||
const std::vector<electron::NotificationAction>& actions) {
|
||||
const std::vector<brightray::NotificationAction>& actions) {
|
||||
actions_ = actions;
|
||||
}
|
||||
|
||||
@@ -206,7 +190,6 @@ void Notification::NotificationClosed() {
|
||||
void Notification::Close() {
|
||||
if (notification_) {
|
||||
notification_->Dismiss();
|
||||
notification_->set_delegate(nullptr);
|
||||
notification_.reset();
|
||||
}
|
||||
}
|
||||
@@ -217,7 +200,7 @@ void Notification::Show() {
|
||||
if (presenter_) {
|
||||
notification_ = presenter_->CreateNotification(this, base::GenerateGUID());
|
||||
if (notification_) {
|
||||
electron::NotificationOptions options;
|
||||
brightray::NotificationOptions options;
|
||||
options.title = title_;
|
||||
options.subtitle = subtitle_;
|
||||
options.msg = body_;
|
||||
@@ -225,28 +208,25 @@ void Notification::Show() {
|
||||
options.icon = icon_.AsBitmap();
|
||||
options.silent = silent_;
|
||||
options.has_reply = has_reply_;
|
||||
options.timeout_type = timeout_type_;
|
||||
options.reply_placeholder = reply_placeholder_;
|
||||
options.actions = actions_;
|
||||
options.sound = sound_;
|
||||
options.close_button_text = close_button_text_;
|
||||
options.urgency = urgency_;
|
||||
notification_->Show(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Notification::IsSupported() {
|
||||
return !!static_cast<ElectronBrowserClient*>(ElectronBrowserClient::Get())
|
||||
->GetNotificationPresenter();
|
||||
return !!brightray::BrowserClient::Get()->GetNotificationPresenter();
|
||||
}
|
||||
|
||||
// static
|
||||
void Notification::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "Notification"));
|
||||
gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
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)
|
||||
@@ -256,12 +236,8 @@ void Notification::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetProperty("silent", &Notification::GetSilent, &Notification::SetSilent)
|
||||
.SetProperty("hasReply", &Notification::GetHasReply,
|
||||
&Notification::SetHasReply)
|
||||
.SetProperty("timeoutType", &Notification::GetTimeoutType,
|
||||
&Notification::SetTimeoutType)
|
||||
.SetProperty("replyPlaceholder", &Notification::GetReplyPlaceholder,
|
||||
&Notification::SetReplyPlaceholder)
|
||||
.SetProperty("urgency", &Notification::GetUrgency,
|
||||
&Notification::SetUrgency)
|
||||
.SetProperty("sound", &Notification::GetSound, &Notification::SetSound)
|
||||
.SetProperty("actions", &Notification::GetActions,
|
||||
&Notification::SetActions)
|
||||
@@ -271,28 +247,26 @@ void Notification::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::Notification;
|
||||
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::BindRepeating(&Notification::New));
|
||||
Notification::SetConstructor(isolate, base::Bind(&Notification::New));
|
||||
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
dict.Set("Notification", Notification::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Notification",
|
||||
Notification::GetConstructor(isolate)->GetFunction());
|
||||
|
||||
dict.SetMethod("isSupported", &Notification::IsSupported);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)
|
||||
@@ -2,34 +2,29 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_NOTIFICATION_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_NOTIFICATION_H_
|
||||
#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 "shell/browser/api/trackable_object.h"
|
||||
#include "shell/browser/notifications/notification.h"
|
||||
#include "shell/browser/notifications/notification_delegate.h"
|
||||
#include "shell/browser/notifications/notification_presenter.h"
|
||||
#include "shell/common/gin_helper/error_thrower.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 gin {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Notification : public mate::TrackableObject<Notification>,
|
||||
public NotificationDelegate {
|
||||
public brightray::NotificationDelegate {
|
||||
public:
|
||||
static mate::WrappableBase* New(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args);
|
||||
static mate::WrappableBase* New(mate::Arguments* args);
|
||||
static bool IsSupported();
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
@@ -44,7 +39,9 @@ class Notification : public mate::TrackableObject<Notification>,
|
||||
void NotificationClosed() override;
|
||||
|
||||
protected:
|
||||
explicit Notification(gin::Arguments* args);
|
||||
Notification(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
mate::Arguments* args);
|
||||
~Notification() override;
|
||||
|
||||
void Show();
|
||||
@@ -56,11 +53,9 @@ class Notification : public mate::TrackableObject<Notification>,
|
||||
base::string16 GetBody() const;
|
||||
bool GetSilent() const;
|
||||
bool GetHasReply() const;
|
||||
base::string16 GetTimeoutType() const;
|
||||
base::string16 GetReplyPlaceholder() const;
|
||||
base::string16 GetUrgency() const;
|
||||
base::string16 GetSound() const;
|
||||
std::vector<electron::NotificationAction> GetActions() const;
|
||||
std::vector<brightray::NotificationAction> GetActions() const;
|
||||
base::string16 GetCloseButtonText() const;
|
||||
|
||||
// Prop Setters
|
||||
@@ -69,11 +64,9 @@ class Notification : public mate::TrackableObject<Notification>,
|
||||
void SetBody(const base::string16& new_body);
|
||||
void SetSilent(bool new_silent);
|
||||
void SetHasReply(bool new_has_reply);
|
||||
void SetUrgency(const base::string16& new_urgency);
|
||||
void SetTimeoutType(const base::string16& new_timeout_type);
|
||||
void SetReplyPlaceholder(const base::string16& new_reply_placeholder);
|
||||
void SetSound(const base::string16& sound);
|
||||
void SetActions(const std::vector<electron::NotificationAction>& actions);
|
||||
void SetActions(const std::vector<brightray::NotificationAction>& actions);
|
||||
void SetCloseButtonText(const base::string16& text);
|
||||
|
||||
private:
|
||||
@@ -85,22 +78,20 @@ class Notification : public mate::TrackableObject<Notification>,
|
||||
bool has_icon_ = false;
|
||||
bool silent_ = false;
|
||||
bool has_reply_ = false;
|
||||
base::string16 timeout_type_;
|
||||
base::string16 reply_placeholder_;
|
||||
base::string16 sound_;
|
||||
base::string16 urgency_;
|
||||
std::vector<electron::NotificationAction> actions_;
|
||||
std::vector<brightray::NotificationAction> actions_;
|
||||
base::string16 close_button_text_;
|
||||
|
||||
electron::NotificationPresenter* presenter_;
|
||||
brightray::NotificationPresenter* presenter_;
|
||||
|
||||
base::WeakPtr<electron::Notification> notification_;
|
||||
base::WeakPtr<brightray::Notification> notification_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Notification);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_NOTIFICATION_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_
|
||||
@@ -2,14 +2,15 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_power_monitor.h"
|
||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "base/power_monitor/power_monitor.h"
|
||||
#include "base/power_monitor/power_monitor_device_source.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
template <>
|
||||
@@ -31,19 +32,19 @@ struct Converter<ui::IdleState> {
|
||||
};
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
|
||||
#if defined(OS_LINUX)
|
||||
SetShutdownHandler(base::BindRepeating(&PowerMonitor::ShouldShutdown,
|
||||
base::Unretained(this)));
|
||||
SetShutdownHandler(
|
||||
base::Bind(&PowerMonitor::ShouldShutdown, base::Unretained(this)));
|
||||
#elif defined(OS_MACOSX)
|
||||
Browser::Get()->SetShutdownHandler(base::BindRepeating(
|
||||
&PowerMonitor::ShouldShutdown, base::Unretained(this)));
|
||||
Browser::Get()->SetShutdownHandler(
|
||||
base::Bind(&PowerMonitor::ShouldShutdown, base::Unretained(this)));
|
||||
#endif
|
||||
base::PowerMonitor::AddObserver(this);
|
||||
base::PowerMonitor::Get()->AddObserver(this);
|
||||
Init(isolate);
|
||||
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||
InitPlatformSpecificMonitors();
|
||||
@@ -51,7 +52,7 @@ PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
|
||||
}
|
||||
|
||||
PowerMonitor::~PowerMonitor() {
|
||||
base::PowerMonitor::RemoveObserver(this);
|
||||
base::PowerMonitor::Get()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
bool PowerMonitor::ShouldShutdown() {
|
||||
@@ -83,28 +84,27 @@ void PowerMonitor::OnResume() {
|
||||
Emit("resume");
|
||||
}
|
||||
|
||||
ui::IdleState PowerMonitor::GetSystemIdleState(v8::Isolate* isolate,
|
||||
int idle_threshold) {
|
||||
void PowerMonitor::QuerySystemIdleState(v8::Isolate* isolate,
|
||||
int idle_threshold,
|
||||
const ui::IdleCallback& callback) {
|
||||
if (idle_threshold > 0) {
|
||||
return ui::CalculateIdleState(idle_threshold);
|
||||
ui::CalculateIdleState(idle_threshold, callback);
|
||||
} else {
|
||||
isolate->ThrowException(v8::Exception::TypeError(mate::StringToV8(
|
||||
isolate, "Invalid idle threshold, must be greater than 0")));
|
||||
return ui::IDLE_STATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
int PowerMonitor::GetSystemIdleTime() {
|
||||
return ui::CalculateIdleTime();
|
||||
void PowerMonitor::QuerySystemIdleTime(const ui::IdleTimeCallback& callback) {
|
||||
ui::CalculateIdleTime(callback);
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(
|
||||
mate::StringToV8(isolate,
|
||||
"The 'powerMonitor' module can't be used before the "
|
||||
"app 'ready' event")));
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate,
|
||||
"Cannot require \"powerMonitor\" module before app is ready")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
@@ -115,36 +115,36 @@ v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
void PowerMonitor::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "PowerMonitor"));
|
||||
gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
|
||||
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
#if defined(OS_LINUX)
|
||||
.SetMethod("blockShutdown", &PowerMonitor::BlockShutdown)
|
||||
.SetMethod("unblockShutdown", &PowerMonitor::UnblockShutdown)
|
||||
#endif
|
||||
.SetMethod("getSystemIdleState", &PowerMonitor::GetSystemIdleState)
|
||||
.SetMethod("getSystemIdleTime", &PowerMonitor::GetSystemIdleTime);
|
||||
.SetMethod("querySystemIdleState", &PowerMonitor::QuerySystemIdleState)
|
||||
.SetMethod("querySystemIdleTime", &PowerMonitor::QuerySystemIdleTime);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::PowerMonitor;
|
||||
using atom::api::PowerMonitor;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin::Dictionary dict(isolate, exports);
|
||||
dict.Set("createPowerMonitor", base::BindRepeating(&PowerMonitor::Create));
|
||||
dict.Set("PowerMonitor", PowerMonitor::GetConstructor(isolate)
|
||||
->GetFunction(context)
|
||||
.ToLocalChecked());
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
|
||||
dict.Set("PowerMonitor",
|
||||
PowerMonitor::GetConstructor(isolate)->GetFunction());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
|
||||
@@ -2,16 +2,16 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_POWER_MONITOR_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_POWER_MONITOR_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/lib/power_observer.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "shell/browser/api/trackable_object.h"
|
||||
#include "shell/browser/lib/power_observer.h"
|
||||
#include "ui/base/idle/idle.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -46,8 +46,10 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
||||
void OnResume() override;
|
||||
|
||||
private:
|
||||
ui::IdleState GetSystemIdleState(v8::Isolate* isolate, int idle_threshold);
|
||||
int GetSystemIdleTime();
|
||||
void QuerySystemIdleState(v8::Isolate* isolate,
|
||||
int idle_threshold,
|
||||
const ui::IdleCallback& callback);
|
||||
void QuerySystemIdleTime(const ui::IdleTimeCallback& callback);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Static callback invoked when a message comes in to our messaging window.
|
||||
@@ -76,6 +78,6 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_POWER_MONITOR_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
@@ -2,19 +2,17 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_power_monitor.h"
|
||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface MacLockMonitor : NSObject {
|
||||
@private
|
||||
std::vector<electron::api::PowerMonitor*> emitters;
|
||||
std::vector<atom::api::PowerMonitor*> emitters;
|
||||
}
|
||||
|
||||
- (void)addEmitter:(electron::api::PowerMonitor*)monitor_;
|
||||
- (void)addEmitter:(atom::api::PowerMonitor*)monitor_;
|
||||
|
||||
@end
|
||||
|
||||
@@ -24,27 +22,14 @@
|
||||
if ((self = [super init])) {
|
||||
NSDistributedNotificationCenter* distCenter =
|
||||
[NSDistributedNotificationCenter defaultCenter];
|
||||
// A notification that the screen was locked.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(onScreenLocked:)
|
||||
name:@"com.apple.screenIsLocked"
|
||||
object:nil];
|
||||
// A notification that the screen was unlocked by the user.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(onScreenUnlocked:)
|
||||
name:@"com.apple.screenIsUnlocked"
|
||||
object:nil];
|
||||
// A notification that the workspace posts before the machine goes to sleep.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(isSuspending:)
|
||||
name:NSWorkspaceWillSleepNotification
|
||||
object:nil];
|
||||
// A notification that the workspace posts when the machine wakes from
|
||||
// sleep.
|
||||
[distCenter addObserver:self
|
||||
selector:@selector(isResuming:)
|
||||
name:NSWorkspaceDidWakeNotification
|
||||
object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -54,37 +39,25 @@
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)addEmitter:(electron::api::PowerMonitor*)monitor_ {
|
||||
- (void)addEmitter:(atom::api::PowerMonitor*)monitor_ {
|
||||
self->emitters.push_back(monitor_);
|
||||
}
|
||||
|
||||
- (void)isSuspending:(NSNotification*)notify {
|
||||
for (auto* emitter : self->emitters) {
|
||||
emitter->Emit("suspend");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)isResuming:(NSNotification*)notify {
|
||||
for (auto* emitter : self->emitters) {
|
||||
emitter->Emit("resume");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onScreenLocked:(NSNotification*)notification {
|
||||
for (auto* emitter : self->emitters) {
|
||||
for (auto*& emitter : self->emitters) {
|
||||
emitter->Emit("lock-screen");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onScreenUnlocked:(NSNotification*)notification {
|
||||
for (auto* emitter : self->emitters) {
|
||||
for (auto*& emitter : self->emitters) {
|
||||
emitter->Emit("unlock-screen");
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -98,4 +71,4 @@ void PowerMonitor::InitPlatformSpecificMonitors() {
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_power_monitor.h"
|
||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <wtsapi32.h>
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/gfx/win/hwnd_util.h"
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -39,18 +39,6 @@ void PowerMonitor::InitPlatformSpecificMonitors() {
|
||||
|
||||
// Tel windows we want to be notified with session events
|
||||
WTSRegisterSessionNotification(window_, NOTIFY_FOR_THIS_SESSION);
|
||||
|
||||
// For Windows 8 and later, a new "connected standy" mode has been added and
|
||||
// we must explicitly register for its notifications.
|
||||
auto RegisterSuspendResumeNotification =
|
||||
reinterpret_cast<decltype(&::RegisterSuspendResumeNotification)>(
|
||||
GetProcAddress(GetModuleHandle(L"user32.dll"),
|
||||
"RegisterSuspendResumeNotification"));
|
||||
|
||||
if (RegisterSuspendResumeNotification) {
|
||||
RegisterSuspendResumeNotification(static_cast<HANDLE>(window_),
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK PowerMonitor::WndProcStatic(HWND hwnd,
|
||||
@@ -75,16 +63,10 @@ LRESULT CALLBACK PowerMonitor::WndProc(HWND hwnd,
|
||||
} else if (wparam == WTS_SESSION_UNLOCK) {
|
||||
Emit("unlock-screen");
|
||||
}
|
||||
} else if (message == WM_POWERBROADCAST) {
|
||||
if (wparam == PBT_APMRESUMEAUTOMATIC) {
|
||||
Emit("resume");
|
||||
} else if (wparam == PBT_APMSUSPEND) {
|
||||
Emit("suspend");
|
||||
}
|
||||
}
|
||||
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
135
atom/browser/api/atom_api_power_save_blocker.cc
Normal file
135
atom/browser/api/atom_api_power_save_blocker.cc
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright (c) 2015 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_power_save_blocker.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/task_scheduler/post_task.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<device::mojom::WakeLockType> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
device::mojom::WakeLockType* out) {
|
||||
std::string type;
|
||||
if (!ConvertFromV8(isolate, val, &type))
|
||||
return false;
|
||||
if (type == "prevent-app-suspension")
|
||||
*out = device::mojom::WakeLockType::kPreventAppSuspension;
|
||||
else if (type == "prevent-display-sleep")
|
||||
*out = device::mojom::WakeLockType::kPreventDisplaySleep;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
|
||||
: current_blocker_type_(
|
||||
device::mojom::WakeLockType::kPreventAppSuspension) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
PowerSaveBlocker::~PowerSaveBlocker() {}
|
||||
|
||||
void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||
if (power_save_blocker_types_.empty()) {
|
||||
power_save_blocker_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
// |WakeLockType::kPreventAppSuspension| keeps system active, but allows
|
||||
// screen to be turned off.
|
||||
// |WakeLockType::kPreventDisplaySleep| keeps system and screen active, has a
|
||||
// higher precedence level than |WakeLockType::kPreventAppSuspension|.
|
||||
//
|
||||
// Only the highest-precedence blocker type takes effect.
|
||||
device::mojom::WakeLockType new_blocker_type =
|
||||
device::mojom::WakeLockType::kPreventAppSuspension;
|
||||
for (const auto& element : power_save_blocker_types_) {
|
||||
if (element.second == device::mojom::WakeLockType::kPreventDisplaySleep) {
|
||||
new_blocker_type = device::mojom::WakeLockType::kPreventDisplaySleep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
|
||||
auto new_blocker = std::make_unique<device::PowerSaveBlocker>(
|
||||
new_blocker_type, device::mojom::WakeLockReason::kOther,
|
||||
ATOM_PRODUCT_NAME, base::ThreadTaskRunnerHandle::Get(),
|
||||
// This task runner may be used by some device service
|
||||
// implementation bits to interface with dbus client code, which in
|
||||
// turn imposes some subtle thread affinity on the clients. We
|
||||
// therefore require a single-thread runner.
|
||||
base::CreateSingleThreadTaskRunnerWithTraits(
|
||||
{base::MayBlock(), base::TaskPriority::BACKGROUND}));
|
||||
power_save_blocker_.swap(new_blocker);
|
||||
current_blocker_type_ = new_blocker_type;
|
||||
}
|
||||
}
|
||||
|
||||
int PowerSaveBlocker::Start(device::mojom::WakeLockType type) {
|
||||
static int count = 0;
|
||||
power_save_blocker_types_[count] = type;
|
||||
UpdatePowerSaveBlocker();
|
||||
return count++;
|
||||
}
|
||||
|
||||
bool PowerSaveBlocker::Stop(int id) {
|
||||
bool success = power_save_blocker_types_.erase(id) > 0;
|
||||
UpdatePowerSaveBlocker();
|
||||
return success;
|
||||
}
|
||||
|
||||
bool PowerSaveBlocker::IsStarted(int id) {
|
||||
return power_save_blocker_types_.find(id) != power_save_blocker_types_.end();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new PowerSaveBlocker(isolate));
|
||||
}
|
||||
|
||||
// static
|
||||
void PowerSaveBlocker::BuildPrototype(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "PowerSaveBlocker"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("start", &PowerSaveBlocker::Start)
|
||||
.SetMethod("stop", &PowerSaveBlocker::Stop)
|
||||
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("powerSaveBlocker", atom::api::PowerSaveBlocker::Create(isolate));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize);
|
||||
56
atom/browser/api/atom_api_power_save_blocker.h
Normal file
56
atom/browser/api/atom_api_power_save_blocker.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2015 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_POWER_SAVE_BLOCKER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "services/device/wake_lock/power_save_blocker/power_save_blocker.h"
|
||||
|
||||
namespace mate {
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
|
||||
public:
|
||||
static mate::Handle<PowerSaveBlocker> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
protected:
|
||||
explicit PowerSaveBlocker(v8::Isolate* isolate);
|
||||
~PowerSaveBlocker() override;
|
||||
|
||||
private:
|
||||
void UpdatePowerSaveBlocker();
|
||||
int Start(device::mojom::WakeLockType type);
|
||||
bool Stop(int id);
|
||||
bool IsStarted(int id);
|
||||
|
||||
std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_;
|
||||
|
||||
// Current blocker type used by |power_save_blocker_|
|
||||
device::mojom::WakeLockType current_blocker_type_;
|
||||
|
||||
// Map from id to the corresponding blocker type for each request.
|
||||
using WakeLockTypeMap = std::map<int, device::mojom::WakeLockType>;
|
||||
WakeLockTypeMap power_save_blocker_types_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
|
||||
248
atom/browser/api/atom_api_protocol.cc
Normal file
248
atom/browser/api/atom_api_protocol.cc
Normal file
@@ -0,0 +1,248 @@
|
||||
// Copyright (c) 2013 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_protocol.h"
|
||||
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#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"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "url/url_util.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// List of registered custom standard schemes.
|
||||
std::vector<std::string> g_standard_schemes;
|
||||
|
||||
} // namespace
|
||||
|
||||
std::vector<std::string> GetStandardSchemes() {
|
||||
return g_standard_schemes;
|
||||
}
|
||||
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args) {
|
||||
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_WITH_HOST);
|
||||
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)
|
||||
: browser_context_(browser_context), weak_factory_(this) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
Protocol::~Protocol() {}
|
||||
|
||||
void Protocol::RegisterServiceWorkerSchemes(
|
||||
const std::vector<std::string>& schemes) {
|
||||
atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
|
||||
}
|
||||
|
||||
void Protocol::UnregisterProtocol(const std::string& scheme,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&Protocol::UnregisterProtocolInIO,
|
||||
base::RetainedRef(getter), scheme),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
}
|
||||
|
||||
// static
|
||||
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme) {
|
||||
auto* job_factory = request_context_getter->job_factory();
|
||||
if (!job_factory->HasProtocolHandler(scheme))
|
||||
return PROTOCOL_NOT_REGISTERED;
|
||||
job_factory->SetProtocolHandler(scheme, nullptr);
|
||||
return PROTOCOL_OK;
|
||||
}
|
||||
|
||||
void Protocol::IsProtocolHandled(const std::string& scheme,
|
||||
const BooleanCallback& callback) {
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&Protocol::IsProtocolHandledInIO, base::RetainedRef(getter),
|
||||
scheme),
|
||||
callback);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Protocol::IsProtocolHandledInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme) {
|
||||
return request_context_getter->job_factory()->IsHandledProtocol(scheme);
|
||||
}
|
||||
|
||||
void Protocol::UninterceptProtocol(const std::string& scheme,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&Protocol::UninterceptProtocolInIO,
|
||||
base::RetainedRef(getter), scheme),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
}
|
||||
|
||||
// static
|
||||
Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme) {
|
||||
return request_context_getter->job_factory()->UninterceptProtocol(scheme)
|
||||
? PROTOCOL_OK
|
||||
: PROTOCOL_NOT_INTERCEPTED;
|
||||
}
|
||||
|
||||
void Protocol::OnIOCompleted(const CompletionCallback& callback,
|
||||
ProtocolError error) {
|
||||
// The completion callback is optional.
|
||||
if (callback.is_null())
|
||||
return;
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
if (error == PROTOCOL_OK) {
|
||||
callback.Run(v8::Null(isolate()));
|
||||
} else {
|
||||
std::string str = ErrorCodeToString(error);
|
||||
callback.Run(v8::Exception::Error(mate::StringToV8(isolate(), str)));
|
||||
}
|
||||
}
|
||||
|
||||
std::string Protocol::ErrorCodeToString(ProtocolError error) {
|
||||
switch (error) {
|
||||
case PROTOCOL_FAIL:
|
||||
return "Failed to manipulate protocol factory";
|
||||
case PROTOCOL_REGISTERED:
|
||||
return "The scheme has been registered";
|
||||
case PROTOCOL_NOT_REGISTERED:
|
||||
return "The scheme has not been registered";
|
||||
case PROTOCOL_INTERCEPTED:
|
||||
return "The scheme has been intercepted";
|
||||
case PROTOCOL_NOT_INTERCEPTED:
|
||||
return "The scheme has not been intercepted";
|
||||
default:
|
||||
return "Unexpected error";
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Protocol> Protocol::Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {
|
||||
return mate::CreateHandle(isolate, new Protocol(isolate, browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
void Protocol::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Protocol"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("registerServiceWorkerSchemes",
|
||||
&Protocol::RegisterServiceWorkerSchemes)
|
||||
.SetMethod("registerStringProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStringJob>)
|
||||
.SetMethod("registerBufferProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("registerFileProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("registerHttpProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("registerStreamProtocol",
|
||||
&Protocol::RegisterProtocol<URLRequestStreamJob>)
|
||||
.SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol)
|
||||
.SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled)
|
||||
.SetMethod("interceptStringProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestStringJob>)
|
||||
.SetMethod("interceptBufferProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestBufferJob>)
|
||||
.SetMethod("interceptFileProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestAsyncAsarJob>)
|
||||
.SetMethod("interceptHttpProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestFetchJob>)
|
||||
.SetMethod("interceptStreamProtocol",
|
||||
&Protocol::InterceptProtocol<URLRequestStreamJob>)
|
||||
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args) {
|
||||
if (atom::Browser::Get()->is_ready()) {
|
||||
args->ThrowError(
|
||||
"protocol.registerStandardSchemes should be called before "
|
||||
"app is ready");
|
||||
return;
|
||||
}
|
||||
|
||||
atom::api::RegisterStandardSchemes(schemes, args);
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("registerStandardSchemes", &RegisterStandardSchemes);
|
||||
dict.SetMethod("getStandardSchemes", &atom::api::GetStandardSchemes);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)
|
||||
201
atom/browser/api/atom_api_protocol.h
Normal file
201
atom/browser/api/atom_api_protocol.h
Normal file
@@ -0,0 +1,201 @@
|
||||
// Copyright (c) 2013 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_PROTOCOL_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
std::vector<std::string> GetStandardSchemes();
|
||||
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
|
||||
mate::Arguments* args);
|
||||
|
||||
class Protocol : public mate::TrackableObject<Protocol> {
|
||||
public:
|
||||
using Handler =
|
||||
base::Callback<void(const base::DictionaryValue&, v8::Local<v8::Value>)>;
|
||||
using CompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
using BooleanCallback = base::Callback<void(bool)>;
|
||||
|
||||
static mate::Handle<Protocol> Create(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
protected:
|
||||
Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Protocol() override;
|
||||
|
||||
private:
|
||||
// Possible errors.
|
||||
enum ProtocolError {
|
||||
PROTOCOL_OK, // no error
|
||||
PROTOCOL_FAIL, // operation failed, should never occur
|
||||
PROTOCOL_REGISTERED,
|
||||
PROTOCOL_NOT_REGISTERED,
|
||||
PROTOCOL_INTERCEPTED,
|
||||
PROTOCOL_NOT_INTERCEPTED,
|
||||
};
|
||||
|
||||
// The protocol handler that will create a protocol handler for certain
|
||||
// request job.
|
||||
template <typename RequestJob>
|
||||
class CustomProtocolHandler
|
||||
: public net::URLRequestJobFactory::ProtocolHandler {
|
||||
public:
|
||||
CustomProtocolHandler(v8::Isolate* isolate,
|
||||
net::URLRequestContextGetter* request_context,
|
||||
const Handler& handler)
|
||||
: isolate_(isolate),
|
||||
request_context_(request_context),
|
||||
handler_(handler) {}
|
||||
~CustomProtocolHandler() override {}
|
||||
|
||||
net::URLRequestJob* MaybeCreateJob(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const override {
|
||||
RequestJob* request_job = new RequestJob(request, network_delegate);
|
||||
request_job->SetHandlerInfo(isolate_, request_context_, handler_);
|
||||
return request_job;
|
||||
}
|
||||
|
||||
private:
|
||||
v8::Isolate* isolate_;
|
||||
net::URLRequestContextGetter* request_context_;
|
||||
Protocol::Handler handler_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
|
||||
};
|
||||
|
||||
// Register schemes that can handle service worker.
|
||||
void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
|
||||
|
||||
// Register the protocol with certain request job.
|
||||
template <typename RequestJob>
|
||||
void RegisterProtocol(const std::string& scheme,
|
||||
const Handler& handler,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&Protocol::RegisterProtocolInIO<RequestJob>,
|
||||
base::RetainedRef(getter), isolate(), scheme, handler),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
}
|
||||
template <typename RequestJob>
|
||||
static ProtocolError RegisterProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const Handler& handler) {
|
||||
auto* job_factory = request_context_getter->job_factory();
|
||||
if (job_factory->IsHandledProtocol(scheme))
|
||||
return PROTOCOL_REGISTERED;
|
||||
auto protocol_handler = std::make_unique<CustomProtocolHandler<RequestJob>>(
|
||||
isolate, request_context_getter.get(), handler);
|
||||
if (job_factory->SetProtocolHandler(scheme, std::move(protocol_handler)))
|
||||
return PROTOCOL_OK;
|
||||
else
|
||||
return PROTOCOL_FAIL;
|
||||
}
|
||||
|
||||
// Unregister the protocol handler that handles |scheme|.
|
||||
void UnregisterProtocol(const std::string& scheme, mate::Arguments* args);
|
||||
static ProtocolError UnregisterProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme);
|
||||
|
||||
// Whether the protocol has handler registered.
|
||||
void IsProtocolHandled(const std::string& scheme,
|
||||
const BooleanCallback& callback);
|
||||
static bool IsProtocolHandledInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme);
|
||||
|
||||
// Replace the protocol handler with a new one.
|
||||
template <typename RequestJob>
|
||||
void InterceptProtocol(const std::string& scheme,
|
||||
const Handler& handler,
|
||||
mate::Arguments* args) {
|
||||
CompletionCallback callback;
|
||||
args->GetNext(&callback);
|
||||
auto* getter = static_cast<URLRequestContextGetter*>(
|
||||
browser_context_->GetRequestContext());
|
||||
content::BrowserThread::PostTaskAndReplyWithResult(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&Protocol::InterceptProtocolInIO<RequestJob>,
|
||||
base::RetainedRef(getter), isolate(), scheme, handler),
|
||||
base::BindOnce(&Protocol::OnIOCompleted, GetWeakPtr(), callback));
|
||||
}
|
||||
template <typename RequestJob>
|
||||
static ProtocolError InterceptProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
v8::Isolate* isolate,
|
||||
const std::string& scheme,
|
||||
const Handler& handler) {
|
||||
auto* job_factory = request_context_getter->job_factory();
|
||||
if (!job_factory->IsHandledProtocol(scheme))
|
||||
return PROTOCOL_NOT_REGISTERED;
|
||||
// It is possible a protocol is handled but can not be intercepted.
|
||||
if (!job_factory->HasProtocolHandler(scheme))
|
||||
return PROTOCOL_FAIL;
|
||||
auto protocol_handler = std::make_unique<CustomProtocolHandler<RequestJob>>(
|
||||
isolate, request_context_getter.get(), handler);
|
||||
if (!job_factory->InterceptProtocol(scheme, std::move(protocol_handler)))
|
||||
return PROTOCOL_INTERCEPTED;
|
||||
return PROTOCOL_OK;
|
||||
}
|
||||
|
||||
// Restore the |scheme| to its original protocol handler.
|
||||
void UninterceptProtocol(const std::string& scheme, mate::Arguments* args);
|
||||
static ProtocolError UninterceptProtocolInIO(
|
||||
scoped_refptr<URLRequestContextGetter> request_context_getter,
|
||||
const std::string& scheme);
|
||||
|
||||
// Convert error code to JS exception and call the callback.
|
||||
void OnIOCompleted(const CompletionCallback& callback, ProtocolError error);
|
||||
|
||||
// Convert error code to string.
|
||||
std::string ErrorCodeToString(ProtocolError error);
|
||||
|
||||
base::WeakPtr<Protocol> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
|
||||
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
base::WeakPtrFactory<Protocol> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Protocol);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_
|
||||
91
atom/browser/api/atom_api_render_process_preferences.cc
Normal file
91
atom/browser/api/atom_api_render_process_preferences.cc
Normal file
@@ -0,0 +1,91 @@
|
||||
// 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_render_process_preferences.h"
|
||||
|
||||
#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 "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 {
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsWebContents(v8::Isolate* isolate, content::RenderProcessHost* process) {
|
||||
content::WebContents* web_contents =
|
||||
static_cast<AtomBrowserClient*>(AtomBrowserClient::Get())
|
||||
->GetWebContentsFromProcessID(process->GetID());
|
||||
if (!web_contents)
|
||||
return false;
|
||||
|
||||
auto api_web_contents = WebContents::CreateFrom(isolate, web_contents);
|
||||
auto type = api_web_contents->GetType();
|
||||
return type == WebContents::Type::BROWSER_WINDOW ||
|
||||
type == WebContents::Type::WEB_VIEW;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RenderProcessPreferences::RenderProcessPreferences(
|
||||
v8::Isolate* isolate,
|
||||
const atom::RenderProcessPreferences::Predicate& predicate)
|
||||
: preferences_(predicate) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
RenderProcessPreferences::~RenderProcessPreferences() {}
|
||||
|
||||
int RenderProcessPreferences::AddEntry(const base::DictionaryValue& entry) {
|
||||
return preferences_.AddEntry(entry);
|
||||
}
|
||||
|
||||
void RenderProcessPreferences::RemoveEntry(int id) {
|
||||
preferences_.RemoveEntry(id);
|
||||
}
|
||||
|
||||
// static
|
||||
void RenderProcessPreferences::BuildPrototype(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(
|
||||
mate::StringToV8(isolate, "RenderProcessPreferences"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("addEntry", &RenderProcessPreferences::AddEntry)
|
||||
.SetMethod("removeEntry", &RenderProcessPreferences::RemoveEntry);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<RenderProcessPreferences>
|
||||
RenderProcessPreferences::ForAllWebContents(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate,
|
||||
new RenderProcessPreferences(
|
||||
isolate, base::Bind(&IsWebContents, isolate)));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("forAllWebContents",
|
||||
&atom::api::RenderProcessPreferences::ForAllWebContents);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
|
||||
Initialize)
|
||||
44
atom/browser/api/atom_api_render_process_preferences.h
Normal file
44
atom/browser/api/atom_api_render_process_preferences.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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_RENDER_PROCESS_PREFERENCES_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_RENDER_PROCESS_PREFERENCES_H_
|
||||
|
||||
#include "atom/browser/render_process_preferences.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class RenderProcessPreferences
|
||||
: public mate::Wrappable<RenderProcessPreferences> {
|
||||
public:
|
||||
static mate::Handle<RenderProcessPreferences> ForAllWebContents(
|
||||
v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
int AddEntry(const base::DictionaryValue& entry);
|
||||
void RemoveEntry(int id);
|
||||
|
||||
protected:
|
||||
RenderProcessPreferences(
|
||||
v8::Isolate* isolate,
|
||||
const atom::RenderProcessPreferences::Predicate& predicate);
|
||||
~RenderProcessPreferences() override;
|
||||
|
||||
private:
|
||||
atom::RenderProcessPreferences preferences_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RenderProcessPreferences);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_RENDER_PROCESS_PREFERENCES_H_
|
||||
@@ -2,21 +2,17 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/api/electron_api_screen.h"
|
||||
#include "atom/browser/api/atom_api_screen.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/atom_api_browser_window.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/gfx_converter.h"
|
||||
#include "shell/common/gin_converters/native_window_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
@@ -25,7 +21,9 @@
|
||||
#include "ui/display/win/screen_win.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -44,29 +42,16 @@ typename T::iterator FindById(T* container, int id) {
|
||||
std::vector<std::string> MetricsToArray(uint32_t metrics) {
|
||||
std::vector<std::string> array;
|
||||
if (metrics & display::DisplayObserver::DISPLAY_METRIC_BOUNDS)
|
||||
array.emplace_back("bounds");
|
||||
array.push_back("bounds");
|
||||
if (metrics & display::DisplayObserver::DISPLAY_METRIC_WORK_AREA)
|
||||
array.emplace_back("workArea");
|
||||
array.push_back("workArea");
|
||||
if (metrics & display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR)
|
||||
array.emplace_back("scaleFactor");
|
||||
array.push_back("scaleFactor");
|
||||
if (metrics & display::DisplayObserver::DISPLAY_METRIC_ROTATION)
|
||||
array.emplace_back("rotation");
|
||||
array.push_back("rotation");
|
||||
return array;
|
||||
}
|
||||
|
||||
void DelayEmit(Screen* screen,
|
||||
base::StringPiece name,
|
||||
const display::Display& display) {
|
||||
screen->Emit(name, display);
|
||||
}
|
||||
|
||||
void DelayEmitWithMetrics(Screen* screen,
|
||||
base::StringPiece name,
|
||||
const display::Display& display,
|
||||
const std::vector<std::string>& metrics) {
|
||||
screen->Emit(name, display, metrics);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Screen::Screen(v8::Isolate* isolate, display::Screen* screen)
|
||||
@@ -101,13 +86,13 @@ display::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
static gfx::Rect ScreenToDIPRect(electron::NativeWindow* window,
|
||||
static gfx::Rect ScreenToDIPRect(atom::NativeWindow* window,
|
||||
const gfx::Rect& rect) {
|
||||
HWND hwnd = window ? window->GetAcceleratedWidget() : nullptr;
|
||||
return display::win::ScreenWin::ScreenToDIPRect(hwnd, rect);
|
||||
}
|
||||
|
||||
static gfx::Rect DIPToScreenRect(electron::NativeWindow* window,
|
||||
static gfx::Rect DIPToScreenRect(atom::NativeWindow* window,
|
||||
const gfx::Rect& rect) {
|
||||
HWND hwnd = window ? window->GetAcceleratedWidget() : nullptr;
|
||||
return display::win::ScreenWin::DIPToScreenRect(hwnd, rect);
|
||||
@@ -116,49 +101,41 @@ static gfx::Rect DIPToScreenRect(electron::NativeWindow* window,
|
||||
#endif
|
||||
|
||||
void Screen::OnDisplayAdded(const display::Display& new_display) {
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this), "display-added",
|
||||
new_display));
|
||||
Emit("display-added", new_display);
|
||||
}
|
||||
|
||||
void Screen::OnDisplayRemoved(const display::Display& old_display) {
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this),
|
||||
"display-removed", old_display));
|
||||
Emit("display-removed", old_display);
|
||||
}
|
||||
|
||||
void Screen::OnDisplayMetricsChanged(const display::Display& display,
|
||||
uint32_t changed_metrics) {
|
||||
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
|
||||
FROM_HERE, base::Bind(&DelayEmitWithMetrics, base::Unretained(this),
|
||||
"display-metrics-changed", display,
|
||||
MetricsToArray(changed_metrics)));
|
||||
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Screen::Create(gin_helper::ErrorThrower error_thrower) {
|
||||
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
error_thrower.ThrowError(
|
||||
"The 'screen' module can't be used before the app 'ready' event");
|
||||
return v8::Null(error_thrower.isolate());
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate, "Cannot require \"screen\" module before app is ready")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
display::Screen* screen = display::Screen::GetScreen();
|
||||
if (!screen) {
|
||||
error_thrower.ThrowError("Failed to get screen information");
|
||||
return v8::Null(error_thrower.isolate());
|
||||
isolate->ThrowException(v8::Exception::Error(
|
||||
mate::StringToV8(isolate, "Failed to get screen information")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
return gin::CreateHandle(error_thrower.isolate(),
|
||||
new Screen(error_thrower.isolate(), screen))
|
||||
.ToV8();
|
||||
return mate::CreateHandle(isolate, new Screen(isolate, screen)).ToV8();
|
||||
}
|
||||
|
||||
// static
|
||||
void Screen::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(gin::StringToV8(isolate, "Screen"));
|
||||
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Screen"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
|
||||
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
|
||||
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
|
||||
@@ -174,24 +151,22 @@ void Screen::BuildPrototype(v8::Isolate* isolate,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using electron::api::Screen;
|
||||
using atom::api::Screen;
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
gin_helper::Dictionary dict(isolate, exports);
|
||||
dict.SetMethod("createScreen", base::BindRepeating(&Screen::Create));
|
||||
dict.Set(
|
||||
"Screen",
|
||||
Screen::GetConstructor(isolate)->GetFunction(context).ToLocalChecked());
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("screen", Screen::Create(isolate));
|
||||
dict.Set("Screen", Screen::GetConstructor(isolate)->GetFunction());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
|
||||
@@ -2,14 +2,13 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_SCREEN_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_SCREEN_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/gin_helper/event_emitter.h"
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "ui/display/display_observer.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
@@ -19,14 +18,14 @@ class Rect;
|
||||
class Screen;
|
||||
} // namespace gfx
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Screen : public gin_helper::EventEmitter<mate::Wrappable<Screen>>,
|
||||
class Screen : public mate::EventEmitter<Screen>,
|
||||
public display::DisplayObserver {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(gin_helper::ErrorThrower error_thrower);
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
@@ -55,6 +54,6 @@ class Screen : public gin_helper::EventEmitter<mate::Wrappable<Screen>>,
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_SCREEN_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_SCREEN_H_
|
||||
812
atom/browser/api/atom_api_session.cc
Normal file
812
atom/browser/api/atom_api_session.cc
Normal file
@@ -0,0 +1,812 @@
|
||||
// Copyright (c) 2015 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_session.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/atom_api_cookies.h"
|
||||
#include "atom/browser/api/atom_api_download_item.h"
|
||||
#include "atom/browser/api/atom_api_net_log.h"
|
||||
#include "atom/browser/api/atom_api_protocol.h"
|
||||
#include "atom/browser/api/atom_api_web_request.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/net/atom_cert_verifier.h"
|
||||
#include "atom/browser/session_preferences.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/content_converter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/net_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/guid.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "brightray/browser/media/media_device_id_salt.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/download/public/common/download_danger_type.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/prefs/value_map_pref_store.h"
|
||||
#include "components/proxy_config/proxy_config_dictionary.h"
|
||||
#include "components/proxy_config/proxy_config_pref_names.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/download_item_utils.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"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/disk_cache/disk_cache.h"
|
||||
#include "net/dns/host_cache.h"
|
||||
#include "net/http/http_auth_handler_factory.h"
|
||||
#include "net/http/http_auth_preferences.h"
|
||||
#include "net/http/http_cache.h"
|
||||
#include "net/http/http_transaction_factory.h"
|
||||
#include "net/url_request/static_http_user_agent_settings.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using atom::api::Cookies;
|
||||
using content::BrowserThread;
|
||||
using content::StoragePartition;
|
||||
|
||||
namespace {
|
||||
|
||||
struct ClearStorageDataOptions {
|
||||
GURL origin;
|
||||
uint32_t storage_types = StoragePartition::REMOVE_DATA_MASK_ALL;
|
||||
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) {
|
||||
auto type = base::ToLowerASCII(it);
|
||||
if (type == "appcache")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_APPCACHE;
|
||||
else if (type == "cookies")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_COOKIES;
|
||||
else if (type == "filesystem")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS;
|
||||
else if (type == "indexdb")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_INDEXEDDB;
|
||||
else if (type == "localstorage")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE;
|
||||
else if (type == "shadercache")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE;
|
||||
else if (type == "websql")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_WEBSQL;
|
||||
else if (type == "serviceworkers")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS;
|
||||
else if (type == "cachestorage")
|
||||
storage_mask |= StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE;
|
||||
}
|
||||
return storage_mask;
|
||||
}
|
||||
|
||||
uint32_t GetQuotaMask(const std::vector<std::string>& quota_types) {
|
||||
uint32_t quota_mask = 0;
|
||||
for (const auto& it : quota_types) {
|
||||
auto type = base::ToLowerASCII(it);
|
||||
if (type == "temporary")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY;
|
||||
else if (type == "persistent")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT;
|
||||
else if (type == "syncable")
|
||||
quota_mask |= StoragePartition::QUOTA_MANAGED_STORAGE_MASK_SYNCABLE;
|
||||
}
|
||||
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) {
|
||||
getter->GetURLRequestContext()->set_http_user_agent_settings(
|
||||
new net::StaticHttpUserAgentSettings(
|
||||
net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang),
|
||||
user_agent));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
template <>
|
||||
struct Converter<ClearStorageDataOptions> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
ClearStorageDataOptions* out) {
|
||||
mate::Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
options.Get("origin", &out->origin);
|
||||
std::vector<std::string> types;
|
||||
if (options.Get("storages", &types))
|
||||
out->storage_types = GetStorageMask(types);
|
||||
if (options.Get("quotas", &types))
|
||||
out->quota_types = GetQuotaMask(types);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
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 <>
|
||||
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 {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kPersistPrefix[] = "persist:";
|
||||
|
||||
// Referenced session objects.
|
||||
std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
|
||||
|
||||
// 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(BrowserThread::UI, FROM_HERE,
|
||||
base::BindOnce(callback, result...));
|
||||
}
|
||||
|
||||
// Callback of HttpCache::GetBackend.
|
||||
void OnGetBackend(disk_cache::Backend** backend_ptr,
|
||||
Session::CacheAction action,
|
||||
const net::CompletionCallback& callback,
|
||||
int result) {
|
||||
if (result != net::OK) {
|
||||
RunCallbackInUI(callback, result);
|
||||
} else if (backend_ptr && *backend_ptr) {
|
||||
if (action == Session::CacheAction::CLEAR) {
|
||||
(*backend_ptr)
|
||||
->DoomAllEntries(base::Bind(&RunCallbackInUI<int>, callback));
|
||||
} else if (action == Session::CacheAction::STATS) {
|
||||
base::StringPairs stats;
|
||||
(*backend_ptr)->GetStats(&stats);
|
||||
for (const auto& stat : stats) {
|
||||
if (stat.first == "Current size") {
|
||||
int current_size;
|
||||
base::StringToInt(stat.second, ¤t_size);
|
||||
RunCallbackInUI(callback, current_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RunCallbackInUI<int>(callback, net::ERR_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
void DoCacheActionInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
Session::CacheAction action,
|
||||
const net::CompletionCallback& callback) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
auto* http_cache = request_context->http_transaction_factory()->GetCache();
|
||||
if (!http_cache)
|
||||
RunCallbackInUI<int>(callback, net::ERR_FAILED);
|
||||
|
||||
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
|
||||
using BackendPtr = disk_cache::Backend*;
|
||||
auto** backend_ptr = new BackendPtr(nullptr);
|
||||
net::CompletionCallback on_get_backend =
|
||||
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, callback);
|
||||
int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
|
||||
if (rv != net::ERR_IO_PENDING)
|
||||
on_get_backend.Run(net::OK);
|
||||
}
|
||||
|
||||
void SetCertVerifyProcInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const AtomCertVerifier::VerifyProc& proc) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
static_cast<AtomCertVerifier*>(request_context->cert_verifier())
|
||||
->SetVerifyProc(proc);
|
||||
}
|
||||
|
||||
void ClearHostResolverCacheInIO(
|
||||
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
|
||||
const base::Closure& callback) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
auto* cache = request_context->host_resolver()->GetHostCache();
|
||||
if (cache) {
|
||||
cache->clear();
|
||||
DCHECK_EQ(0u, cache->size());
|
||||
if (!callback.is_null())
|
||||
RunCallbackInUI(callback);
|
||||
}
|
||||
}
|
||||
|
||||
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->ClearAllEntries();
|
||||
}
|
||||
} 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) {
|
||||
auto* request_context = context_getter->GetURLRequestContext();
|
||||
auto* auth_handler = request_context->http_auth_handler_factory();
|
||||
if (auth_handler) {
|
||||
auto* auth_preferences = const_cast<net::HttpAuthPreferences*>(
|
||||
auth_handler->http_auth_preferences());
|
||||
if (auth_preferences)
|
||||
auth_preferences->SetServerWhitelist(domains);
|
||||
}
|
||||
}
|
||||
|
||||
void OnClearStorageDataDone(const base::Closure& callback) {
|
||||
if (!callback.is_null())
|
||||
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(),
|
||||
download::DownloadItem::INTERRUPTED,
|
||||
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
||||
download::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false, base::Time(),
|
||||
false, std::vector<download::DownloadItem::ReceivedSlice>());
|
||||
}
|
||||
|
||||
void DestroyGlobalHandle(v8::Isolate* isolate,
|
||||
const v8::Global<v8::Value>& global_handle) {
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
if (!global_handle.IsEmpty()) {
|
||||
v8::Local<v8::Value> local_handle = global_handle.Get(isolate);
|
||||
if (local_handle->IsObject()) {
|
||||
v8::Local<v8::Object> object = local_handle->ToObject();
|
||||
void* ptr = object->GetAlignedPointerFromInternalField(0);
|
||||
if (!ptr)
|
||||
return;
|
||||
delete static_cast<mate::WrappableBase*>(ptr);
|
||||
object->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: network_emulation_token_(base::UnguessableToken::Create()),
|
||||
browser_context_(browser_context) {
|
||||
// Observe DownloadManager to get download notifications.
|
||||
content::BrowserContext::GetDownloadManager(browser_context)
|
||||
->AddObserver(this);
|
||||
|
||||
new SessionPreferences(browser_context);
|
||||
|
||||
Init(isolate);
|
||||
AttachAsUserData(browser_context);
|
||||
}
|
||||
|
||||
Session::~Session() {
|
||||
content::BrowserContext::GetDownloadManager(browser_context())
|
||||
->RemoveObserver(this);
|
||||
DestroyGlobalHandle(isolate(), cookies_);
|
||||
DestroyGlobalHandle(isolate(), web_request_);
|
||||
DestroyGlobalHandle(isolate(), protocol_);
|
||||
DestroyGlobalHandle(isolate(), net_log_);
|
||||
g_sessions.erase(weak_map_id());
|
||||
}
|
||||
|
||||
void Session::OnDownloadCreated(content::DownloadManager* manager,
|
||||
download::DownloadItem* item) {
|
||||
if (item->IsSavePackageDownload())
|
||||
return;
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto handle = DownloadItem::Create(isolate(), item);
|
||||
if (item->GetState() == download::DownloadItem::INTERRUPTED)
|
||||
handle->SetSavePath(item->GetTargetFilePath());
|
||||
content::WebContents* web_contents =
|
||||
content::DownloadItemUtils::GetWebContents(item);
|
||||
bool prevent_default = Emit("will-download", handle, web_contents);
|
||||
if (prevent_default) {
|
||||
item->Cancel(true);
|
||||
item->Remove();
|
||||
}
|
||||
}
|
||||
|
||||
void Session::ResolveProxy(
|
||||
const GURL& url,
|
||||
const ResolveProxyHelper::ResolveProxyCallback& callback) {
|
||||
browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback);
|
||||
}
|
||||
|
||||
template <Session::CacheAction action>
|
||||
void Session::DoCacheAction(const net::CompletionCallback& callback) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&DoCacheActionInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
action, callback));
|
||||
}
|
||||
|
||||
void Session::ClearStorageData(mate::Arguments* args) {
|
||||
// clearStorageData([options, callback])
|
||||
ClearStorageDataOptions options;
|
||||
base::Closure callback;
|
||||
args->GetNext(&options);
|
||||
args->GetNext(&callback);
|
||||
|
||||
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(), base::Time(),
|
||||
base::Time::Max(), base::Bind(&OnClearStorageDataDone, callback));
|
||||
}
|
||||
|
||||
void Session::FlushStorageData() {
|
||||
auto* storage_partition =
|
||||
content::BrowserContext::GetStoragePartition(browser_context(), nullptr);
|
||||
storage_partition->Flush();
|
||||
}
|
||||
|
||||
void Session::SetProxy(const mate::Dictionary& options,
|
||||
const base::Closure& callback) {
|
||||
if (!browser_context_->in_memory_pref_store()) {
|
||||
callback.Run();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string proxy_rules, bypass_list, pac_url;
|
||||
|
||||
options.Get("pacScript", &pac_url);
|
||||
options.Get("proxyRules", &proxy_rules);
|
||||
options.Get("proxyBypassRules", &bypass_list);
|
||||
|
||||
// pacScript takes precedence over proxyRules.
|
||||
if (!pac_url.empty()) {
|
||||
browser_context_->in_memory_pref_store()->SetValue(
|
||||
proxy_config::prefs::kProxy,
|
||||
ProxyConfigDictionary::CreatePacScript(pac_url,
|
||||
true /* pac_mandatory */),
|
||||
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
||||
} else {
|
||||
browser_context_->in_memory_pref_store()->SetValue(
|
||||
proxy_config::prefs::kProxy,
|
||||
ProxyConfigDictionary::CreateFixedServers(proxy_rules, bypass_list),
|
||||
WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
||||
}
|
||||
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
|
||||
}
|
||||
|
||||
void Session::SetDownloadPath(const base::FilePath& path) {
|
||||
browser_context_->prefs()->SetFilePath(prefs::kDownloadDefaultDirectory,
|
||||
path);
|
||||
}
|
||||
|
||||
void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
|
||||
auto conditions = network::mojom::NetworkConditions::New();
|
||||
|
||||
options.Get("offline", &conditions->offline);
|
||||
options.Get("downloadThroughput", &conditions->download_throughput);
|
||||
options.Get("uploadThroughput", &conditions->upload_throughput);
|
||||
double latency = 0.0;
|
||||
if (options.Get("latency", &latency) && latency) {
|
||||
conditions->latency = base::TimeDelta::FromMillisecondsD(latency);
|
||||
}
|
||||
|
||||
auto* network_context = content::BrowserContext::GetDefaultStoragePartition(
|
||||
browser_context_.get())
|
||||
->GetNetworkContext();
|
||||
network_context->SetNetworkConditions(network_emulation_token_,
|
||||
std::move(conditions));
|
||||
}
|
||||
|
||||
void Session::DisableNetworkEmulation() {
|
||||
auto* network_context = content::BrowserContext::GetDefaultStoragePartition(
|
||||
browser_context_.get())
|
||||
->GetNetworkContext();
|
||||
network_context->SetNetworkConditions(
|
||||
network_emulation_token_, network::mojom::NetworkConditions::New());
|
||||
}
|
||||
|
||||
void WrapVerifyProc(base::Callback<void(const VerifyRequestParams& request,
|
||||
base::Callback<void(int)>)> proc,
|
||||
const VerifyRequestParams& request,
|
||||
base::OnceCallback<void(int)> cb) {
|
||||
proc.Run(request, base::AdaptCallbackForRepeating(std::move(cb)));
|
||||
}
|
||||
|
||||
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
base::Callback<void(const VerifyRequestParams& request,
|
||||
base::Callback<void(int)>)>
|
||||
proc;
|
||||
if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &proc))) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&SetCertVerifyProcInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
base::Bind(&WrapVerifyProc, proc)));
|
||||
}
|
||||
|
||||
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
AtomPermissionManager::RequestHandler handler;
|
||||
if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
auto* permission_manager = static_cast<AtomPermissionManager*>(
|
||||
browser_context()->GetPermissionControllerDelegate());
|
||||
permission_manager->SetPermissionRequestHandler(handler);
|
||||
}
|
||||
|
||||
void Session::SetPermissionCheckHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args) {
|
||||
AtomPermissionManager::CheckHandler handler;
|
||||
if (!(val->IsNull() || mate::ConvertFromV8(args->isolate(), val, &handler))) {
|
||||
args->ThrowError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
auto* permission_manager = static_cast<AtomPermissionManager*>(
|
||||
browser_context()->GetPermissionControllerDelegate());
|
||||
permission_manager->SetPermissionCheckHandler(handler);
|
||||
}
|
||||
|
||||
void Session::ClearHostResolverCache(mate::Arguments* args) {
|
||||
base::Closure callback;
|
||||
args->GetNext(&callback);
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&ClearHostResolverCacheInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
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::BindOnce(&ClearAuthCacheInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
options, callback));
|
||||
}
|
||||
|
||||
void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::IO, FROM_HERE,
|
||||
base::BindOnce(&AllowNTLMCredentialsForDomainsInIO,
|
||||
WrapRefCounted(browser_context_->GetRequestContext()),
|
||||
domains));
|
||||
}
|
||||
|
||||
void Session::SetUserAgent(const std::string& user_agent,
|
||||
mate::Arguments* args) {
|
||||
browser_context_->SetUserAgent(user_agent);
|
||||
|
||||
std::string accept_lang = g_browser_process->GetApplicationLocale();
|
||||
args->GetNext(&accept_lang);
|
||||
|
||||
scoped_refptr<net::URLRequestContextGetter> getter(
|
||||
browser_context_->GetRequestContext());
|
||||
getter->GetNetworkTaskRunner()->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(&SetUserAgentInIO, getter, accept_lang, user_agent));
|
||||
}
|
||||
|
||||
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::BindOnce(&AtomBlobReader::StartReading,
|
||||
base::Unretained(blob_reader), uuid, callback));
|
||||
}
|
||||
|
||||
void Session::CreateInterruptedDownload(const mate::Dictionary& options) {
|
||||
int64_t offset = 0, length = 0;
|
||||
double start_time = 0.0;
|
||||
std::string mime_type, last_modified, etag;
|
||||
base::FilePath path;
|
||||
std::vector<GURL> url_chain;
|
||||
options.Get("path", &path);
|
||||
options.Get("urlChain", &url_chain);
|
||||
options.Get("mimeType", &mime_type);
|
||||
options.Get("offset", &offset);
|
||||
options.Get("length", &length);
|
||||
options.Get("lastModified", &last_modified);
|
||||
options.Get("eTag", &etag);
|
||||
options.Get("startTime", &start_time);
|
||||
if (path.empty() || url_chain.empty() || length == 0) {
|
||||
isolate()->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate(), "Must pass non-empty path, urlChain and length.")));
|
||||
return;
|
||||
}
|
||||
if (offset >= length) {
|
||||
isolate()->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate(), "Must pass an offset value less than length.")));
|
||||
return;
|
||||
}
|
||||
auto* download_manager =
|
||||
content::BrowserContext::GetDownloadManager(browser_context());
|
||||
download_manager->GetDelegate()->GetNextId(base::Bind(
|
||||
&DownloadIdCallback, download_manager, path, url_chain, mime_type, offset,
|
||||
length, last_modified, etag, base::Time::FromDoubleT(start_time)));
|
||||
}
|
||||
|
||||
void Session::SetPreloads(
|
||||
const std::vector<base::FilePath::StringType>& preloads) {
|
||||
auto* prefs = SessionPreferences::FromBrowserContext(browser_context());
|
||||
DCHECK(prefs);
|
||||
prefs->set_preloads(preloads);
|
||||
}
|
||||
|
||||
std::vector<base::FilePath::StringType> Session::GetPreloads() const {
|
||||
auto* prefs = SessionPreferences::FromBrowserContext(browser_context());
|
||||
DCHECK(prefs);
|
||||
return prefs->preloads();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
if (cookies_.IsEmpty()) {
|
||||
auto handle = Cookies::Create(isolate, browser_context());
|
||||
cookies_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, cookies_);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Protocol(v8::Isolate* isolate) {
|
||||
if (protocol_.IsEmpty()) {
|
||||
auto handle = atom::api::Protocol::Create(isolate, browser_context());
|
||||
protocol_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, protocol_);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::WebRequest(v8::Isolate* isolate) {
|
||||
if (web_request_.IsEmpty()) {
|
||||
auto handle = atom::api::WebRequest::Create(isolate, browser_context());
|
||||
web_request_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, web_request_);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::NetLog(v8::Isolate* isolate) {
|
||||
if (net_log_.IsEmpty()) {
|
||||
auto handle = atom::api::NetLog::Create(isolate, browser_context());
|
||||
net_log_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, net_log_);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Session> Session::CreateFrom(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {
|
||||
auto* existing = TrackableObject::FromWrappedClass(isolate, browser_context);
|
||||
if (existing)
|
||||
return mate::CreateHandle(isolate, static_cast<Session*>(existing));
|
||||
|
||||
auto handle =
|
||||
mate::CreateHandle(isolate, new Session(isolate, browser_context));
|
||||
|
||||
// The Sessions should never be garbage collected, since the common pattern is
|
||||
// to use partition strings, instead of using the Session object directly.
|
||||
g_sessions[handle->weak_map_id()] =
|
||||
v8::Global<v8::Object>(isolate, handle.ToV8());
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<Session> Session::FromPartition(
|
||||
v8::Isolate* isolate,
|
||||
const std::string& partition,
|
||||
const base::DictionaryValue& options) {
|
||||
scoped_refptr<AtomBrowserContext> browser_context;
|
||||
if (partition.empty()) {
|
||||
browser_context = AtomBrowserContext::From("", false, options);
|
||||
} else if (base::StartsWith(partition, kPersistPrefix,
|
||||
base::CompareCase::SENSITIVE)) {
|
||||
std::string name = partition.substr(8);
|
||||
browser_context = AtomBrowserContext::From(name, false, options);
|
||||
} else {
|
||||
browser_context = AtomBrowserContext::From(partition, true, options);
|
||||
}
|
||||
return CreateFrom(isolate, browser_context.get());
|
||||
}
|
||||
|
||||
// static
|
||||
void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype) {
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "Session"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("resolveProxy", &Session::ResolveProxy)
|
||||
.SetMethod("getCacheSize", &Session::DoCacheAction<CacheAction::STATS>)
|
||||
.SetMethod("clearCache", &Session::DoCacheAction<CacheAction::CLEAR>)
|
||||
.SetMethod("clearStorageData", &Session::ClearStorageData)
|
||||
.SetMethod("flushStorageData", &Session::FlushStorageData)
|
||||
.SetMethod("setProxy", &Session::SetProxy)
|
||||
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
|
||||
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
|
||||
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
|
||||
.SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc)
|
||||
.SetMethod("setPermissionRequestHandler",
|
||||
&Session::SetPermissionRequestHandler)
|
||||
.SetMethod("setPermissionCheckHandler",
|
||||
&Session::SetPermissionCheckHandler)
|
||||
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
||||
.SetMethod("clearAuthCache", &Session::ClearAuthCache)
|
||||
.SetMethod("allowNTLMCredentialsForDomains",
|
||||
&Session::AllowNTLMCredentialsForDomains)
|
||||
.SetMethod("setUserAgent", &Session::SetUserAgent)
|
||||
.SetMethod("getUserAgent", &Session::GetUserAgent)
|
||||
.SetMethod("getBlobData", &Session::GetBlobData)
|
||||
.SetMethod("createInterruptedDownload",
|
||||
&Session::CreateInterruptedDownload)
|
||||
.SetMethod("setPreloads", &Session::SetPreloads)
|
||||
.SetMethod("getPreloads", &Session::GetPreloads)
|
||||
.SetProperty("cookies", &Session::Cookies)
|
||||
.SetProperty("netLog", &Session::NetLog)
|
||||
.SetProperty("protocol", &Session::Protocol)
|
||||
.SetProperty("webRequest", &Session::WebRequest);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
using atom::api::Session;
|
||||
|
||||
v8::Local<v8::Value> FromPartition(const std::string& partition,
|
||||
mate::Arguments* args) {
|
||||
if (!atom::Browser::Get()->is_ready()) {
|
||||
args->ThrowError("Session can only be received when app is ready");
|
||||
return v8::Null(args->isolate());
|
||||
}
|
||||
base::DictionaryValue options;
|
||||
args->GetNext(&options);
|
||||
return Session::FromPartition(args->isolate(), partition, options).ToV8();
|
||||
}
|
||||
|
||||
void Initialize(v8::Local<v8::Object> exports,
|
||||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)
|
||||
@@ -2,23 +2,19 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_BROWSER_API_ELECTRON_API_SESSION_H_
|
||||
#define SHELL_BROWSER_API_ELECTRON_API_SESSION_H_
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_SESSION_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_SESSION_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "atom/browser/net/resolve_proxy_helper.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "shell/browser/api/trackable_object.h"
|
||||
#include "shell/browser/net/resolve_proxy_helper.h"
|
||||
#include "shell/common/promise_util.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
#include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h" // nogncheck
|
||||
#endif
|
||||
#include "net/base/completion_callback.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
@@ -35,22 +31,23 @@ namespace net {
|
||||
class ProxyConfig;
|
||||
}
|
||||
|
||||
namespace electron {
|
||||
namespace atom {
|
||||
|
||||
class ElectronBrowserContext;
|
||||
class AtomBrowserContext;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Session : public mate::TrackableObject<Session>,
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
public SpellcheckHunspellDictionary::Observer,
|
||||
#endif
|
||||
public content::DownloadManager::Observer {
|
||||
public:
|
||||
enum class CacheAction {
|
||||
CLEAR,
|
||||
STATS,
|
||||
};
|
||||
|
||||
// Gets or creates Session from the |browser_context|.
|
||||
static mate::Handle<Session> CreateFrom(
|
||||
v8::Isolate* isolate,
|
||||
ElectronBrowserContext* browser_context);
|
||||
static mate::Handle<Session> CreateFrom(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context);
|
||||
|
||||
// Gets the Session of |partition|.
|
||||
static mate::Handle<Session> FromPartition(
|
||||
@@ -58,21 +55,20 @@ class Session : public mate::TrackableObject<Session>,
|
||||
const std::string& partition,
|
||||
const base::DictionaryValue& options = base::DictionaryValue());
|
||||
|
||||
ElectronBrowserContext* browser_context() const {
|
||||
return browser_context_.get();
|
||||
}
|
||||
AtomBrowserContext* browser_context() const { return browser_context_.get(); }
|
||||
|
||||
// mate::TrackableObject:
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
// Methods.
|
||||
v8::Local<v8::Promise> ResolveProxy(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> GetCacheSize();
|
||||
v8::Local<v8::Promise> ClearCache();
|
||||
v8::Local<v8::Promise> ClearStorageData(mate::Arguments* args);
|
||||
void ResolveProxy(const GURL& url,
|
||||
const ResolveProxyHelper::ResolveProxyCallback& callback);
|
||||
template <CacheAction action>
|
||||
void DoCacheAction(const net::CompletionCallback& callback);
|
||||
void ClearStorageData(mate::Arguments* args);
|
||||
void FlushStorageData();
|
||||
v8::Local<v8::Promise> SetProxy(mate::Arguments* args);
|
||||
void SetProxy(const mate::Dictionary& options, const base::Closure& callback);
|
||||
void SetDownloadPath(const base::FilePath& path);
|
||||
void EnableNetworkEmulation(const mate::Dictionary& options);
|
||||
void DisableNetworkEmulation();
|
||||
@@ -81,14 +77,13 @@ class Session : public mate::TrackableObject<Session>,
|
||||
mate::Arguments* args);
|
||||
void SetPermissionCheckHandler(v8::Local<v8::Value> val,
|
||||
mate::Arguments* args);
|
||||
v8::Local<v8::Promise> ClearHostResolverCache(mate::Arguments* args);
|
||||
v8::Local<v8::Promise> ClearAuthCache();
|
||||
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();
|
||||
v8::Local<v8::Promise> GetBlobData(v8::Isolate* isolate,
|
||||
const std::string& uuid);
|
||||
void DownloadURL(const GURL& url);
|
||||
void GetBlobData(const std::string& uuid,
|
||||
const AtomBlobReader::CompletionCallback& callback);
|
||||
void CreateInterruptedDownload(const mate::Dictionary& options);
|
||||
void SetPreloads(const std::vector<base::FilePath::StringType>& preloads);
|
||||
std::vector<base::FilePath::StringType> GetPreloads() const;
|
||||
@@ -96,55 +91,32 @@ class Session : public mate::TrackableObject<Session>,
|
||||
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> NetLog(v8::Isolate* isolate);
|
||||
void Preconnect(const mate::Dictionary& options, mate::Arguments* args);
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
base::Value GetSpellCheckerLanguages();
|
||||
void SetSpellCheckerLanguages(gin_helper::ErrorThrower thrower,
|
||||
const std::vector<std::string>& languages);
|
||||
bool AddWordToSpellCheckerDictionary(const std::string& word);
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
void LoadChromeExtension(const base::FilePath extension_path);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
Session(v8::Isolate* isolate, ElectronBrowserContext* browser_context);
|
||||
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Session() override;
|
||||
|
||||
// content::DownloadManager::Observer:
|
||||
void OnDownloadCreated(content::DownloadManager* manager,
|
||||
download::DownloadItem* item) override;
|
||||
|
||||
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
|
||||
// SpellcheckHunspellDictionary::Observer
|
||||
void OnHunspellDictionaryInitialized(const std::string& language) override;
|
||||
void OnHunspellDictionaryDownloadBegin(const std::string& language) override;
|
||||
void OnHunspellDictionaryDownloadSuccess(
|
||||
const std::string& language) override;
|
||||
void OnHunspellDictionaryDownloadFailure(
|
||||
const std::string& language) override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Cached mate::Wrappable objects.
|
||||
// Cached object.
|
||||
v8::Global<v8::Value> cookies_;
|
||||
v8::Global<v8::Value> protocol_;
|
||||
v8::Global<v8::Value> net_log_;
|
||||
|
||||
// Cached object.
|
||||
v8::Global<v8::Value> web_request_;
|
||||
v8::Global<v8::Value> net_log_;
|
||||
|
||||
// The client id to enable the network throttler.
|
||||
base::UnguessableToken network_emulation_token_;
|
||||
|
||||
scoped_refptr<ElectronBrowserContext> browser_context_;
|
||||
scoped_refptr<AtomBrowserContext> browser_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Session);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
} // namespace atom
|
||||
|
||||
#endif // SHELL_BROWSER_API_ELECTRON_API_SESSION_H_
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_SESSION_H_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user