Compare commits

..

3 Commits

Author SHA1 Message Date
Cheng Zhao
40066ca343 Bump v0.36.12 2016-03-27 10:40:57 +09:00
Cheng Zhao
6671e78f5d Run callback of setDestructor immediately when GC happens
Fix #4733.
2016-03-27 10:40:44 +09:00
Cheng Zhao
0480e32f99 Update brightray: fix crash when using notification on Windows 2016-03-27 10:40:03 +09:00
1562 changed files with 27778 additions and 111259 deletions

View File

@@ -1,273 +0,0 @@
version: 2
jobs:
electron-linux-arm:
docker:
- image: electronbuilds/electron:0.0.3
environment:
TARGET_ARCH: arm
resource_class: xlarge
steps:
- checkout
- run:
name: Setup for headless testing
command: sh -e /etc/init.d/xvfb start
- run:
name: Check for release
command: |
MESSAGE="$(git log --format=%B -n 1 HEAD)"
case ${MESSAGE} in
Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
esac
- run:
name: Bootstrap
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Bootstrapping Electron for release build'
script/bootstrap.py --target_arch=$TARGET_ARCH
else
echo 'Bootstrapping Electron for debug build'
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
fi
- run: npm run lint
- run:
name: Build
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Building Electron for release'
script/build.py -c R
else
echo 'Building Electron for debug'
script/build.py -c D
fi
- run:
name: Create distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Creating Electron release distribution'
script/create-dist.py
else
echo 'Skipping create distribution because build is not for release'
fi
- run:
name: Upload distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Uploading Electron release distribution'
script/upload.py
else
echo 'Skipping upload distribution because build is not for release'
fi
electron-linux-arm64:
docker:
- image: electronbuilds/electron:0.0.3
environment:
TARGET_ARCH: arm64
resource_class: xlarge
steps:
- checkout
- run:
name: Setup for headless testing
command: sh -e /etc/init.d/xvfb start
- run:
name: Check for release
command: |
MESSAGE="$(git log --format=%B -n 1 HEAD)"
case ${MESSAGE} in
Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
esac
- run:
name: Bootstrap
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Bootstrapping Electron for release build'
script/bootstrap.py --target_arch=$TARGET_ARCH
else
echo 'Bootstrapping Electron for debug build'
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
fi
- run: npm run lint
- run:
name: Build
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Building Electron for release'
script/build.py -c R
else
echo 'Building Electron for debug'
script/build.py -c D
fi
- run:
name: Create distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Creating Electron release distribution'
script/create-dist.py
else
echo 'Skipping create distribution because build is not for release'
fi
- run:
name: Upload distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Uploading Electron release distribution'
script/upload.py
else
echo 'Skipping upload distribution because build is not for release'
fi
electron-linux-ia32:
docker:
- image: electronbuilds/electron:0.0.3
environment:
TARGET_ARCH: ia32
resource_class: xlarge
steps:
- checkout
- run:
name: Setup for headless testing
command: sh -e /etc/init.d/xvfb start
- run:
name: Check for release
command: |
MESSAGE="$(git log --format=%B -n 1 HEAD)"
case ${MESSAGE} in
Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
esac
- run:
name: Bootstrap
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Bootstrapping Electron for release build'
script/bootstrap.py --target_arch=$TARGET_ARCH
else
echo 'Bootstrapping Electron for debug build'
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
fi
- run: npm run lint
- run:
name: Build
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Building Electron for release'
script/build.py -c R
else
echo 'Building Electron for debug'
script/build.py -c D
fi
- run:
name: Create distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Creating Electron release distribution'
script/create-dist.py
else
echo 'Skipping create distribution because build is not for release'
fi
- run:
name: Upload distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Uploading Electron release distribution'
script/upload.py
else
echo 'Skipping upload distribution because build is not for release'
fi
electron-linux-x64:
docker:
- image: electronbuilds/electron:0.0.3
environment:
TARGET_ARCH: x64
resource_class: xlarge
steps:
- checkout
- run:
name: Setup for headless testing
command: sh -e /etc/init.d/xvfb start
- run:
name: Check for release
command: |
MESSAGE="$(git log --format=%B -n 1 HEAD)"
case ${MESSAGE} in
Bump* ) echo 'export ELECTRON_RELEASE=1' >> $BASH_ENV
esac
- run:
name: Bootstrap
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Bootstrapping Electron for release build'
script/bootstrap.py --target_arch=$TARGET_ARCH
else
echo 'Bootstrapping Electron for debug build'
script/bootstrap.py --target_arch=$TARGET_ARCH --dev
fi
- run: npm run lint
- run:
name: Build
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Building Electron for release'
script/build.py -c R
else
echo 'Building Electron for debug'
script/build.py -c D
fi
- run:
name: Create distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Creating Electron release distribution'
script/create-dist.py
else
echo 'Skipping create distribution because build is not for release'
fi
- run:
name: Upload distribution
command: |
if [ "$ELECTRON_RELEASE" == "1" ]; then
echo 'Uploading Electron release distribution'
script/upload.py
else
echo 'Skipping upload distribution because build is not for release'
fi
- run:
name: Test
environment:
MOCHA_FILE: junit/test-results.xml
MOCHA_REPORTER: mocha-junit-reporter
command: |
if [ "$ELECTRON_RELEASE" != "1" ]; then
echo 'Testing Electron debug build'
mkdir junit
script/test.py --ci --rebuild_native_modules
else
echo 'Skipping testing on release build'
fi
- run:
name: Verify FFmpeg
command: |
if [ "$ELECTRON_RELEASE" != "1" ]; then
echo 'Verifying ffmpeg on debug build'
script/verify-ffmpeg.py
else
echo 'Skipping verify ffmpeg on release build'
fi
- store_test_results:
path: junit
- store_artifacts:
path: junit
workflows:
version: 2
build-arm:
jobs:
- electron-linux-arm
build-arm64:
jobs:
- electron-linux-arm64
build-ia32:
jobs:
- electron-linux-ia32
build-x64:
jobs:
- electron-linux-x64

View File

@@ -1,35 +0,0 @@
# Defines the Chromium style for automatic reformatting.
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Chromium
# This defaults to 'Auto'. Explicitly set it for a while, so that
# 'vector<vector<int> >' in existing files gets formatted to
# 'vector<vector<int>>'. ('Auto' means that clang-format will only use
# 'int>>' if the file already contains at least one such instance.)
Standard: Cpp11
# Make sure code like:
# IPC_BEGIN_MESSAGE_MAP()
# IPC_MESSAGE_HANDLER(WidgetHostViewHost_Update, OnUpdate)
# IPC_END_MESSAGE_MAP()
# gets correctly indented.
MacroBlockBegin: "^\
BEGIN_MSG_MAP|\
BEGIN_MSG_MAP_EX|\
BEGIN_SAFE_MSG_MAP_EX|\
CR_BEGIN_MSG_MAP_EX|\
IPC_BEGIN_MESSAGE_MAP|\
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM|\
IPC_PROTOBUF_MESSAGE_TRAITS_BEGIN|\
IPC_STRUCT_BEGIN|\
IPC_STRUCT_BEGIN_WITH_PARENT|\
IPC_STRUCT_TRAITS_BEGIN|\
POLPARAMS_BEGIN|\
PPAPI_BEGIN_MESSAGE_MAP$"
MacroBlockEnd: "^\
CR_END_MSG_MAP|\
END_MSG_MAP|\
IPC_END_MESSAGE_MAP|\
IPC_PROTOBUF_MESSAGE_TRAITS_END|\
IPC_STRUCT_END|\
IPC_STRUCT_TRAITS_END|\
POLPARAMS_END|\
PPAPI_END_MESSAGE_MAP$"

View File

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

21
.github/CODEOWNERS vendored
View File

@@ -1,21 +0,0 @@
# Order is important. The LAST matching pattern has the MOST precedence.
# gitignore style patterns are used, not globs.
# https://help.github.com/articles/about-codeowners
# https://git-scm.com/docs/gitignore
# Everything that falls through the cracks:
* @electron/reviewers
# filename patterns
*browser_view* @electron/browserview
*notification* @electron/notifications
*pdf* @electron/printing
*printing* @electron/printing
*updater* @electron/updater
# directories
/.github/ @electron/hubbers
/default_app/ @electron/docs
/docs/ @electron/docs
/docs-translations/ @electron/i18n
/npm/ @electron/hubbers

View File

@@ -1,35 +0,0 @@
<!--
Thanks for opening an issue! A few things to keep in mind:
- The issue tracker is only for bugs and feature requests.
- Before reporting a bug, please try reproducing your issue against
the latest version of Electron.
- If you need general advice, join our Slack: http://atom-slack.herokuapp.com
-->
* Electron version:
* Operating system:
### Expected behavior
<!-- What do you think should happen? -->
### Actual behavior
<!-- What actually happens? -->
### How to reproduce
<!--
Your best chance of getting this bug looked at quickly is to provide a REPOSITORY that can be cloned and run.
You can fork https://github.com/electron/electron-quick-start and include a link to the branch with your changes.
If you provide a URL, please list the commands required to clone/setup/run your repo e.g.
$ git clone $YOUR_URL -b $BRANCH
$ npm install
$ npm start || electron .
-->

29
.github/config.yml vendored
View File

@@ -1,29 +0,0 @@
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
# Comment to be posted to on first time issues
newIssueWelcomeComment: |
👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
To help make it easier for us to investigate your issue, please follow the [contributing guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md#submitting-issues).
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
# Comment to be posted to on PRs from first time contributors in your repository
newPRWelcomeComment: |
💖 Thanks for opening this pull request! 💖
Here is a list of things that will help get it across the finish line:
- Follow the JavaScript, C++, and Python [coding style](https://github.com/electron/electron/blob/master/docs/development/coding-style.md).
- Run `npm run lint` locally to catch formatting errors earlier.
- Document any user-facing changes you've made following the [documentation styleguide](https://github.com/electron/electron/blob/master/docs/styleguide.md).
- Include tests when adding/changing behavior.
- Include screenshots and animated GIFs whenever possible.
We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
# Comment to be posted to on pull requests merged by a first time user
firstPRMergeComment: >
Congrats on merging your first pull request! 🎉🎉🎉
# It is recommend to include as many gifs and emojis as possiblec

25
.github/stale.yml vendored
View File

@@ -1,25 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 45
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- fixme/bug
- fixme/crash
- fixme/regression
- fixme/security
- blocked
- blocking-stable
- needs-review
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity and is not currently prioritized. It will be closed
in a week if no further activity occurs :)
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
If you still think this issue is relevant, please ping a maintainer or
leave a comment!

44
.gitignore vendored
View File

@@ -1,45 +1,21 @@
.DS_Store
.env
.gclient_done
.npmrc
.tags*
.vs/
.vscode/
*.log
*.pyc
*.sln
*.swp
*.VC.db
*.VC.VC.opendb
*.vcxproj
*.vcxproj.filters
*.vcxproj.user
*.xcodeproj
/.idea/
/brightray/brightray.opensdf
/brightray/brightray.sdf
/brightray/brightray.sln
/brightray/brightray.suo
/brightray/brightray.v12.suo
/brightray/brightray.vcxproj*
/brightray/brightray.xcodeproj/
/build/
/dist/
/external_binaries/
/out/
/vendor/.gclient
/vendor/debian_jessie_amd64-sysroot/
/vendor/debian_jessie_arm-sysroot/
/vendor/debian_jessie_arm64-sysroot/
/vendor/debian_jessie_i386-sysroot/
/vendor/debian_wheezy_amd64-sysroot/
/vendor/brightray/vendor/download/
/vendor/debian_wheezy_arm-sysroot/
/vendor/debian_wheezy_i386-sysroot/
/vendor/download/
/vendor/llvm-build/
/vendor/llvm/
/vendor/node/deps/node-inspect/.npmrc
/vendor/npm/
/vendor/python_26/
/vendor/npm/
/vendor/llvm/
/vendor/llvm-build/
/vendor/.gclient
node_modules/
SHASUMS256.txt
*.xcodeproj
*.swp
*.pyc
debug.log
npm-debug.log

20
.gitmodules vendored
View File

@@ -1,30 +1,24 @@
[submodule "vendor/brightray"]
path = vendor/brightray
url = https://github.com/atom/brightray.git
[submodule "vendor/node"]
path = vendor/node
url = https://github.com/electron/node.git
url = https://github.com/atom/node.git
[submodule "vendor/depot_tools"]
path = vendor/depot_tools
url = https://chromium.googlesource.com/chromium/tools/depot_tools.git
[submodule "vendor/breakpad"]
path = vendor/breakpad
url = https://github.com/electron/chromium-breakpad.git
url = https://github.com/atom/chromium-breakpad.git
[submodule "vendor/native_mate"]
path = vendor/native_mate
url = https://github.com/electron/native-mate.git
url = https://github.com/zcbenz/native-mate.git
[submodule "vendor/crashpad"]
path = vendor/crashpad
url = https://github.com/electron/crashpad.git
url = https://github.com/atom/crashpad.git
[submodule "vendor/requests"]
path = vendor/requests
url = https://github.com/kennethreitz/requests
[submodule "vendor/boto"]
path = vendor/boto
url = https://github.com/boto/boto.git
[submodule "vendor/pdf_viewer"]
path = vendor/pdf_viewer
url = https://github.com/electron/pdf-viewer.git
[submodule "vendor/gyp"]
path = vendor/gyp
url = https://github.com/electron/gyp
[submodule "vendor/libchromiumcontent"]
path = vendor/libchromiumcontent
url = https://github.com/electron/libchromiumcontent

View File

@@ -1 +0,0 @@
v8.2.1

View File

@@ -3,18 +3,14 @@ git:
notifications:
email: false
before_install:
- export BOTO_CONFIG=/dev/null
language: node_js
node_js:
- "4"
language: cpp
compiler: clang
os:
- linux
- osx
env:
- TARGET_ARCH=x64
osx_image: xcode7.3
osx_image: xcode7
matrix:
include:
@@ -22,10 +18,9 @@ matrix:
env: TARGET_ARCH=arm
- os: linux
env: TARGET_ARCH=ia32
- os: linux
env: TARGET_ARCH=arm64
allow_failures:
- os: osx
- env: TARGET_ARCH=arm
- env: TARGET_ARCH=ia32
script: './script/cibuild'

View File

@@ -1,46 +1,24 @@
# Contributor Covenant Code of Conduct
# Contributor Code of Conduct
## Our Pledge
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
- The use of sexualized language or imagery
- Personal attacks
- Trolling or insulting/derogatory comments
- Public or private harassment
- Publishing other's private information, such as physical or electronic addresses, without explicit permission
- Other unethical or unprofessional conduct
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at [atom@github.com](mailto:atom@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [electron@github.com](mailto:electron@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
This Code of Conduct is adapted from the Contributor Covenant, version 1.3.0, available from http://contributor-covenant.org/version/1/3/0/

View File

@@ -1,10 +1,10 @@
# Electron에 기여하기
:+1::tada: 먼저, 기여에 관심을 가져주셔서 감사합니다! :tada::+1:
:+1::tada: 먼저, 이 프로젝트에 기여해주셔서 감사합니다! :tada::+1:
이 프로젝트는 기여자 규약 [행동강령](CODE_OF_CONDUCT.md)을 준수합니다. 따라서 이
이 프로젝트는 기여자 규약 [행동강령](CODE_OF_CONDUCT.md)을 준수합니다. 따라서 이
프로젝트의 개발에 참여하려면 이 규약을 지켜야 합니다. 받아들일 수 없는 행위를 발견했을
경우 electron@github.com로 보고하세요.
경우 atom@github.com로 보고 하십시오.
다음 항목들은 Electron에 기여하는 가이드라인을 제시합니다.
참고로 이 항목들은 그저 가이드라인에 불과하며 규칙이 아닙니다. 따라서 스스로의 적절한
@@ -12,8 +12,8 @@
## 이슈 제출
* [여기](https://github.com/electron/electron/issues/new)에서 새로운 이슈를 만들 수
있습니다. 하지만 이슈를 작성하기 전에 아래의 항목들을 숙지하고 가능한 한 이슈 보고에
* [여기](https://github.com/atom/electron/issues/new)에서 새로운 이슈를 만들 수
있습니다. 하지만 이슈를 작성하기 전에 아래의 항목들을 숙지하고 가능한한 이슈 보고에
대해 최대한 많은 정보와 자세한 설명을 포함해야 합니다. 가능하다면 다음 항목을 포함해야
합니다:
* 사용하고 있는 Electron의 버전
@@ -23,18 +23,18 @@
* 추가로 다음 사항을 준수하면 이슈를 해결하는데 큰 도움이 됩니다:
* 스크린샷 또는 GIF 애니메이션 이미지들
* 터미널에 출력된 에러의 내용 또는 개발자 도구, 알림창에 뜬 내용
* [Cursory search](https://github.com/electron/electron/issues?utf8=✓&q=is%3Aissue+)를
* [Cursory search](https://github.com/atom/electron/issues?utf8=✓&q=is%3Aissue+)를
통해 이미 비슷한 내용의 이슈가 등록되어있는지 확인
## Pull Request 하기
* 가능한 한 스크린샷과 GIF 애니메이션 이미지를 pull request에 추가
* JavaScript, C++과 Python등
[참조 문서에 정의된 코딩 스타일](/docs-translations/ko-KR/development/coding-style.md)을
* 가능한한 스크린샷과 GIF 애니메이션 이미지를 pull request에 추가
* CoffeeScript, JavaScript, C++과 Python등
[참조문서에 정의된 코딩스타일](/docs-translations/ko-KR/development/coding-style.md)을
준수
* [문서 스타일 가이드](/docs-translations/ko-KR/styleguide.md)에 따라 문서를
[Markdown](https://daringfireball.net/projects/markdown) 형식으로 작성.
* 짧은, 현재 시제 커밋 메시지 사용. [커밋 메시지 스타일 가이드](#git-커밋-메시지)를
* 짧은, 현재 시제 커밋 메시지 사용. [커밋 메시지 스타일 가이드](#Git-커밋-메시지)를
참고하세요
## 스타일 가이드
@@ -58,7 +58,7 @@
### Git 커밋 메시지
* 현재 시제 사용 ("Added feature" 대신 "Add feature" 사용)
* 명령법(imperative mood) 사용 ("Moves cursor to..." 대신 "Move cursor to..." 사용)
* 필수적 분위기(imperative mood) 사용 ("Moves cursor to..." 대신 "Move cursor to..." 사용)
* 첫 줄은 72자에 맞추거나 그 보다 적게 제한
* 자유롭게 필요에 따라 이슈나 PR링크를 참조
* 단순한 문서 변경일 경우 `[ci skip]`을 커밋 메시지에 추가
@@ -68,13 +68,13 @@
* :non-potable_water: `:non-potable_water:` 메모리 누수를 연결했을 때
* :memo: `:memo:` 문서를 작성했을 때
* :penguin: `:penguin:` Linux에 대한 패치를 했을 때
* :apple: `:apple:` macOS에 대한 패치를 했을 때
* :apple: `:apple:` Mac OS에 대한 패치를 했을 때
* :checkered_flag: `:checkered_flag:` Windows에 대한 패치를 했을 때
* :bug: `:bug:` 버그를 고쳤을 때
* :fire: `:fire:` 코드 또는 파일을 삭제했을 때
* :green_heart: `:green_heart:` CI 빌드를 고쳤을 때
* :white_check_mark: `:white_check_mark:` 테스트를 추가했을 때
* :lock: `:lock:` 보안 문제를 해결했을 때
* :arrow_up: `:arrow_up:` 의존성 라이브러리를 업데이트 했을 때
* :arrow_down: `:arrow_down:` 의존성 라이브러리를 다운그레이드 했을 때
* :arrow_up: `:arrow_up:` 종속성 라이브러리를 업데이트 했을 때
* :arrow_down: `:arrow_down:` 종속성 라이브러리를 다운그레이드 했을 때
* :shirt: `:shirt:` linter(코드 검사기)의 경고를 제거했을 때

View File

@@ -1,12 +1,10 @@
# Contributing to Electron
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/CONTRIBUTING.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/CONTRIBUTING.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/CONTRIBUTING.md) | [Dutch](https://github.com/electron/electron/tree/master/docs-translations/nl/project/CONTRIBUTING.md)
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable
behavior to electron@github.com.
behavior to atom@github.com.
The following is a set of guidelines for contributing to Electron.
These are just guidelines, not rules, use your best judgment and feel free to
@@ -14,8 +12,7 @@ propose changes to this document in a pull request.
## Submitting Issues
### Creating Issues
* You can create an issue [here](https://github.com/electron/electron/issues/new),
* You can create an issue [here](https://github.com/atom/electron/issues/new),
but before doing that please read the notes below and include as many details as
possible with your report. If you can, please include:
* The version of Electron you are using
@@ -25,22 +22,13 @@ possible with your report. If you can, please include:
* Other things that will help resolve your issue:
* Screenshots and animated GIFs
* Error output that appears in your terminal, dev tools or as an alert
* Perform a [cursory search](https://github.com/electron/electron/issues?utf8=✓&q=is%3Aissue+)
* Perform a [cursory search](https://github.com/atom/electron/issues?utf8=✓&q=is%3Aissue+)
to see if a similar issue has already been submitted
### Issue Maintenance and Closure
* If an issue is inactive for 45 days (no activity of any kind), it will be
marked for closure with `stale`.
* If after this label is applied, no further activity occurs in the next 7 days,
the issue will be closed.
* If an issue has been closed and you still feel it's relevant, feel free to
ping a maintainer or add a comment!
## Submitting Pull Requests
* Include screenshots and animated GIFs in your pull request whenever possible.
* Follow the JavaScript, C++, and Python [coding style defined in docs](/docs/development/coding-style.md).
* Follow the CoffeeScript, JavaScript, C++ and Python [coding style defined in docs](/docs/development/coding-style.md).
* Write documentation in [Markdown](https://daringfireball.net/projects/markdown).
See the [Documentation Styleguide](/docs/styleguide.md).
* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages).
@@ -77,7 +65,7 @@ the issue will be closed.
* :non-potable_water: `:non-potable_water:` when plugging memory leaks
* :memo: `:memo:` when writing docs
* :penguin: `:penguin:` when fixing something on Linux
* :apple: `:apple:` when fixing something on macOS
* :apple: `:apple:` when fixing something on Mac OS
* :checkered_flag: `:checkered_flag:` when fixing something on Windows
* :bug: `:bug:` when fixing a bug
* :fire: `:fire:` when removing code or files

View File

@@ -1,18 +0,0 @@
FROM electronbuilds/libchromiumcontent:0.0.4
USER root
# Set up HOME directory
ENV HOME=/home
RUN chmod a+rwx /home
# Install node.js
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
RUN apt-get update && apt-get install -y --force-yes nodejs
# Install wget used by crash reporter
RUN apt-get install -y --force-yes wget
# Add xvfb init script
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb

View File

@@ -1,17 +0,0 @@
FROM electronbuilds/libchromiumcontent:0.0.4
USER root
# Install node.js
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
RUN apt-get update && apt-get install -y --force-yes nodejs
# Install wget used by crash reporter
RUN apt-get install -y --force-yes wget
# Add xvfb init script
ADD tools/xvfb-init.sh /etc/init.d/xvfb
RUN chmod a+x /etc/init.d/xvfb
USER builduser
WORKDIR /home/builduser

2
ISSUE_TEMPLATE.md Normal file
View File

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

View File

@@ -1,4 +1,4 @@
Copyright (c) 2013-2017 GitHub Inc.
Copyright (c) 2014 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

80
README-ko.md Normal file
View File

@@ -0,0 +1,80 @@
[![Electron Logo](http://electron.atom.io/images/electron-logo.svg)](http://electron.atom.io/)
[![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron)
[![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies)
[![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/)
### [Electron](https://github.com/atom/electron/) 한국어 참조문서
:zap: *프레임워크 이름이 Atom Shell에서 Electron으로 변경되었습니다* :zap:
Electron 프레임워크는 JavaScript, HTML 그리고 CSS를 사용하여
Cross-Platform 데스크톱 어플리케이션을 개발할 수 있도록 해주는 프레임워크입니다.
[Node.js](https://nodejs.org/)와 [Chromium](http://www.chromium.org)을 기반으로
만들어졌으며 [Atom Editor](https://github.com/atom/atom)에 사용되고 있습니다.
Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서
[@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요.
이 프로젝트는 기여자 규약 [행동강령](CODE_OF_CONDUCT.md)을 준수합니다. 따라서 이
프로젝트의 개발에 참여하려면 이 규약을 지켜야 합니다. 받아들일 수 없는 행위를 발견했을
경우 atom@github.com로 보고 하십시오.
## 다운로드
Linux, Windows, OS X 용으로 미리 빌드된 Electron 바이너리와 디버그 심볼이 준비되어
있습니다. [releases](https://github.com/atom/electron/releases) 페이지에서 받아 볼
수 있습니다.
또한 [`npm`](https://docs.npmjs.com/)을 통해 미리 빌드된 Electron 바이너리를 설치할
수도 있습니다:
```sh
# $PATH에 `electron` 커맨드를 등록하고 전역에 설치합니다.
npm install electron-prebuilt -g
# 개발 의존성 모듈 형태로 설치합니다.
npm install electron-prebuilt --save-dev
```
### 미러
- [China](https://npm.taobao.org/mirrors/electron)
## 참조 문서
[Docs](https://github.com/atom/electron/tree/master/docs/README.md)에 개발 지침과
API 레퍼런스가 있습니다. Electron을 빌드 하는 방법과 프로젝트에 기여하는법 또한 문서에
포함되어 있으니 참고하시기 바랍니다.
## 참조 문서 (번역)
- [브라질 포르투갈어](https://github.com/atom/electron/tree/master/docs-translations/pt-BR)
- [한국어](https://github.com/atom/electron/tree/master/docs-translations/ko-KR)
- [일본어](https://github.com/atom/electron/tree/master/docs-translations/jp)
- [스페인어](https://github.com/atom/electron/tree/master/docs-translations/es)
- [중국어 간체](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
- [중국어 번체](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
- [우크라이나어](https://github.com/atom/electron/tree/master/docs-translations/uk-UA)
- [러시아어](https://github.com/atom/electron/tree/master/docs-translations/ru-RU)
- [프랑스어](https://github.com/atom/electron/tree/master/docs-translations/fr-FR)
## 시작하기
[`atom/electron-quick-start`](https://github.com/atom/electron-quick-start)
저장소를 클론하여 Electron을 간단히 접해볼 수 있습니다.
## 커뮤니티
다음 링크를 통해 커뮤니티에 질문을 올리거나 토론을 나눌 수 있습니다:
- Atom 포럼의 [`electron`](http://discuss.atom.io/c/electron) 카테고리
- Freenode 채팅의 `#atom-shell` 채널
- Slack의 [`Atom`](http://atom-slack.herokuapp.com/) 채널
- [`electron-br`](https://electron-br.slack.com) *(브라질)* 커뮤니티
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(한국)* 커뮤니티
- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(일본)* 커뮤니티
[awesome-electron](https://github.com/sindresorhus/awesome-electron) 프로젝트에
커뮤니티가 운영중인 유용한 예제 어플리케이션과 도구, 리소스가 있으니 한번 참고해 보시기
바랍니다.

121
README.md
View File

@@ -1,99 +1,65 @@
[![Electron Logo](https://electron.atom.io/images/electron-logo.svg)](https://electron.atom.io/)
[![Electron Logo](http://electron.atom.io/images/electron-logo.svg)](http://electron.atom.io/)
[![Travis Build Status](https://travis-ci.org/electron/electron.svg?branch=master)](https://travis-ci.org/electron/electron)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/bc56v83355fi3369/branch/master?svg=true)](https://ci.appveyor.com/project/electron-bot/electron/branch/master)
[![devDependency Status](https://david-dm.org/electron/electron/dev-status.svg)](https://david-dm.org/electron/electron?type=dev)
[![Build Status](https://travis-ci.org/atom/electron.svg?branch=master)](https://travis-ci.org/atom/electron)
[![devDependency Status](https://david-dm.org/atom/electron/dev-status.svg)](https://david-dm.org/atom/electron#info=devDependencies)
[![Join the Electron Community on Slack](http://atom-slack.herokuapp.com/badge.svg)](http://atom-slack.herokuapp.com/)
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/README.md) | [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW/project/README.md) | [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es/project/README.md) | [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR/project/README.md) | [German](https://github.com/electron/electron/tree/master/docs-translations/de-DE/project/README.md)
:zap: *Formerly known as Atom Shell* :zap:
The Electron framework lets you write cross-platform desktop applications
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
[Chromium](http://www.chromium.org) and is used by the [Atom
editor](https://github.com/atom/atom) and many other [apps](https://electron.atom.io/apps).
[Chromium](http://www.chromium.org) and is used in the [Atom
editor](https://github.com/atom/atom).
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
announcements.
This project adheres to the Contributor Covenant
[code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md).
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable
behavior to [electron@github.com](mailto:electron@github.com).
behavior to atom@github.com.
## Installation
## Downloads
To install prebuilt Electron binaries, use [`npm`](https://docs.npmjs.com/).
The preferred method is to install Electron as a development dependency in your
app:
Prebuilt binaries and debug symbols of Electron for Linux, Windows and OS X can
be found on the [releases](https://github.com/atom/electron/releases) page.
You can also use [`npm`](https://docs.npmjs.com/) to install prebuilt electron
binaries:
```sh
npm install electron --save-dev --save-exact
```
# Install the `electron` command globally in your $PATH
npm install electron-prebuilt -g
The `--save-exact` flag is recommended as Electron does not follow semantic
versioning. For info on how to manage Electron versions in your apps, see
[Electron versioning](https://electron.atom.io/docs/tutorial/electron-versioning/).
For more installation options and troubleshooting tips, see
[installation](https://electron.atom.io/docs/tutorial/installation/).
## Quick Start
Clone and run the
[electron/electron-quick-start](https://github.com/electron/electron-quick-start)
repository to see a minimal Electron app in action:
```
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install
npm start
```
## Resources for Learning Electron
- [electron.atom.io/docs](http://electron.atom.io/docs) - all of Electron's documentation
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - a very basic starter Electron app
- [electron.atom.io/community/#boilerplates](http://electron.atom.io/community/#boilerplates) - sample starter apps created by the community
- [electron/simple-samples](https://github.com/electron/simple-samples) - small applications with ideas for taking them further
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - an Electron app that teaches you how to use Electron
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - small demo apps for the various Electron APIs
## Programmatic usage
Most people use Electron from the command line, but if you require `electron` inside
your **Node app** (not your Electron app) it will return the file path to the
binary. Use this to spawn Electron from Node scripts:
```javascript
const electron = require('electron')
const proc = require('child_process')
// will print something similar to /Users/maf/.../Electron
console.log(electron)
// spawn Electron
const child = proc.spawn(electron)
# Install as a development dependency
npm install electron-prebuilt --save-dev
```
### Mirrors
- [China](https://npm.taobao.org/mirrors/electron)
## Documentation
Guides and the API reference are located in the
[docs](https://github.com/atom/electron/tree/master/docs) directory. It also
contains documents describing how to build and contribute to Electron.
## Documentation Translations
- [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR)
- [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR)
- [Japanese](https://github.com/electron/electron/tree/master/docs-translations/jp)
- [Spanish](https://github.com/electron/electron/tree/master/docs-translations/es)
- [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN)
- [Traditional Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-TW)
- [Turkish](https://github.com/electron/electron/tree/master/docs-translations/tr-TR)
- [Thai](https://github.com/electron/electron/tree/master/docs-translations/th-TH)
- [Ukrainian](https://github.com/electron/electron/tree/master/docs-translations/uk-UA)
- [Russian](https://github.com/electron/electron/tree/master/docs-translations/ru-RU)
- [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)
- [Indonesian](https://github.com/electron/electron/tree/master/docs-translations/id)
- [Brazilian Portuguese](https://github.com/atom/electron/tree/master/docs-translations/pt-BR)
- [Korean](https://github.com/atom/electron/tree/master/docs-translations/ko-KR)
- [Japanese](https://github.com/atom/electron/tree/master/docs-translations/jp)
- [Spanish](https://github.com/atom/electron/tree/master/docs-translations/es)
- [Simplified Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-CN)
- [Traditional Chinese](https://github.com/atom/electron/tree/master/docs-translations/zh-TW)
- [Ukrainian](https://github.com/atom/electron/tree/master/docs-translations/uk-UA)
- [Russian](https://github.com/atom/electron/tree/master/docs-translations/ru-RU)
- [French](https://github.com/atom/electron/tree/master/docs-translations/fr-FR)
## Quick Start
Clone and run the [`atom/electron-quick-start`](https://github.com/atom/electron-quick-start)
repository to see a minimal Electron app in action.
## Community
@@ -103,18 +69,9 @@ locations:
forums
- `#atom-shell` channel on Freenode
- [`Atom`](http://atom-slack.herokuapp.com/) channel on Slack
- [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
- [`electron-kr`](http://www.meetup.com/electron-kr/) *(Korean)*
- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
- [`electron-tr`](http://electron-tr.herokuapp.com) *(Turkish)*
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
- [`electron-jp`](https://electron-jp-slackin.herokuapp.com/) *(Japanese)*
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)
for a community maintained list of useful example apps, tools and resources.
## License
[MIT](https://github.com/electron/electron/blob/master/LICENSE)
When using the Electron or other GitHub logos, be sure to follow the [GitHub logo guidelines](https://github.com/logos).

View File

@@ -1,9 +0,0 @@
# Reporting Security Issues
The Electron team and community take security bugs in Electron seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
To report a security issue, email [electron@github.com](mailto:electron@github.com) and include the word "SECURITY" in the subject line.
The Electron team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
Report security bugs in third-party modules to the person or team maintaining the module. You can also report a vulnerability through the [Node Security Project](https://nodesecurity.io/report).

View File

@@ -2,8 +2,6 @@
# http://www.appveyor.com/docs/appveyor-yml
version: "{build}"
os: Visual Studio 2015
init:
- git config --global core.autocrlf input
@@ -12,7 +10,7 @@ platform:
- x64
install:
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\14.0\bin\;%PATH%
- cmd: SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH%
- cmd: SET PATH=C:\python27;%PATH%
- cmd: python script/cibuild
@@ -20,6 +18,6 @@ branches:
only:
- master
# disable build and test phases
# disable build and test pahses
build: off
test: off

View File

@@ -4,11 +4,9 @@
'product_name%': 'Electron',
'company_name%': 'GitHub, Inc',
'company_abbr%': 'github',
'version%': '1.8.2-beta.1',
'js2c_input_dir': '<(SHARED_INTERMEDIATE_DIR)/js2c',
'version%': '0.36.12',
},
'includes': [
'features.gypi',
'filenames.gypi',
'vendor/native_mate/native_mate_files.gypi',
],
@@ -23,11 +21,6 @@
'<(source_root)/external_binaries',
],
}],
['enable_osr==1', {
'defines': [
'ENABLE_OSR',
],
}], # enable_osr==1
],
},
'targets': [
@@ -36,7 +29,6 @@
'type': 'executable',
'dependencies': [
'js2asar',
'app2asar',
'<(project_name)_lib',
],
'sources': [
@@ -74,6 +66,12 @@
'<(PRODUCT_DIR)/<(product_name) Framework.framework',
],
},
{
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Resources',
'files': [
'default_app',
],
},
],
'postbuilds': [
{
@@ -87,14 +85,14 @@
# is marked for no PIE (ASLR).
'postbuild_name': 'Make More Helpers',
'action': [
'tools/mac/make_more_helpers.sh',
'vendor/brightray/tools/mac/make_more_helpers.sh',
'Frameworks',
'<(product_name)',
],
},
# The application doesn't have real localizations, it just has
# empty .lproj directories, which is enough to convince Cocoa
# that Electron supports those languages.
# atom-shell supports those languages.
{
'postbuild_name': 'Make Empty Localizations',
'variables': {
@@ -132,17 +130,7 @@
'VCManifestTool': {
'EmbedManifest': 'true',
'AdditionalManifestFiles': 'atom/browser/resources/win/atom.manifest',
},
'VCLinkerTool': {
# Chrome builds with this minimum environment which makes e.g.
# GetSystemMetrics(SM_CXSIZEFRAME) return Windows XP/2003
# compatible metrics. See: https://crbug.com/361720
#
# The following two settings translate to a linker flag
# of /SUBSYSTEM:WINDOWS,5.02
'MinimumRequiredVersion': '5.02',
'SubSystem': '2',
},
}
},
'copies': [
{
@@ -155,6 +143,7 @@
],
}, {
'copied_libraries': [
'<(libchromiumcontent_dir)/pdf.dll',
'<(libchromiumcontent_dir)/ffmpeg.dll',
],
}],
@@ -167,16 +156,24 @@
'<(libchromiumcontent_dir)/libEGL.dll',
'<(libchromiumcontent_dir)/libGLESv2.dll',
'<(libchromiumcontent_dir)/icudtl.dat',
'<(libchromiumcontent_dir)/blink_image_resources_200_percent.pak',
'<(libchromiumcontent_dir)/content_resources_200_percent.pak',
'<(libchromiumcontent_dir)/content_shell.pak',
'<(libchromiumcontent_dir)/ui_resources_200_percent.pak',
'<(libchromiumcontent_dir)/views_resources_200_percent.pak',
'<(libchromiumcontent_dir)/natives_blob.bin',
'<(libchromiumcontent_dir)/snapshot_blob.bin',
'external_binaries/d3dcompiler_47.dll',
'external_binaries/xinput1_3.dll',
'external_binaries/msvcp120.dll',
'external_binaries/msvcr120.dll',
'external_binaries/vccorlib120.dll',
],
},
{
'destination': '<(PRODUCT_DIR)/resources',
'files': [
'default_app',
]
},
],
}, {
'dependencies': [
@@ -207,15 +204,17 @@
'<@(copied_libraries)',
'<(libchromiumcontent_dir)/locales',
'<(libchromiumcontent_dir)/icudtl.dat',
'<(libchromiumcontent_dir)/blink_image_resources_200_percent.pak',
'<(libchromiumcontent_dir)/content_resources_200_percent.pak',
'<(libchromiumcontent_dir)/content_shell.pak',
'<(libchromiumcontent_dir)/ui_resources_200_percent.pak',
'<(libchromiumcontent_dir)/views_resources_200_percent.pak',
'<(libchromiumcontent_dir)/natives_blob.bin',
'<(libchromiumcontent_dir)/snapshot_blob.bin',
],
},
{
'destination': '<(PRODUCT_DIR)/resources',
'files': [
'default_app',
]
},
],
}], # OS=="linux"
],
@@ -225,26 +224,19 @@
'type': 'static_library',
'dependencies': [
'atom_js2c',
'vendor/pdf_viewer/pdf_viewer.gyp:pdf_viewer',
'brightray/brightray.gyp:brightray',
'vendor/brightray/brightray.gyp:brightray',
'vendor/node/node.gyp:node',
],
'defines': [
# We need to access internal implementations of Node.
'NODE_WANT_INTERNALS=1',
'NODE_SHARED_MODE',
'HAVE_OPENSSL=1',
'HAVE_INSPECTOR=1',
# This is defined in skia/skia_common.gypi.
'SK_SUPPORT_LEGACY_GETTOPDEVICE',
# Disable warnings for g_settings_list_schemas.
'GLIB_DISABLE_DEPRECATION_WARNINGS',
# Defined in Chromium but not exposed in its gyp file.
'V8_USE_EXTERNAL_STARTUP_DATA',
'V8_SHARED',
'USING_V8_SHARED',
'USING_V8_PLATFORM_SHARED',
'USING_V8_BASE_SHARED',
'ENABLE_PLUGINS',
'ENABLE_PEPPER_CDMS',
'USE_PROPRIETARY_CODECS',
],
'sources': [
'<@(lib_sources)',
@@ -252,6 +244,7 @@
'include_dirs': [
'.',
'chromium_src',
'vendor/brightray',
'vendor/native_mate',
# Include atom_natives.h.
'<(SHARED_INTERMEDIATE_DIR)',
@@ -278,7 +271,7 @@
],
},
'export_dependent_settings': [
'brightray/brightray.gyp:brightray',
'vendor/brightray/brightray.gyp:brightray',
],
'conditions': [
['libchromiumcontent_component', {
@@ -298,8 +291,6 @@
'-lcomdlg32.lib',
'-lwininet.lib',
'-lwinmm.lib',
'-lcrypt32.lib',
'-luiautomationcore.lib',
],
},
'dependencies': [
@@ -325,10 +316,6 @@
'$(SDKROOT)/System/Library/Frameworks/QTKit.framework',
],
},
'xcode_settings': {
# ReactiveCocoa which is used by Squirrel requires using __weak.
'CLANG_ENABLE_OBJC_WEAK': 'YES',
},
}], # OS=="mac" and mas_build==0
['OS=="mac" and mas_build==1', {
'defines': [
@@ -341,10 +328,6 @@
],
}], # OS=="mac" and mas_build==1
['OS=="linux"', {
'sources': [
'<@(lib_sources_linux)',
'<@(lib_sources_nss)',
],
'link_settings': {
'ldflags': [
# Make binary search for libraries under current directory, so we
@@ -388,142 +371,25 @@
'<@(js_sources)',
],
'outputs': [
'<(resources_path)/electron.asar',
'<(resources_path)/atom.asar',
],
'action': [
'python',
'tools/js2asar.py',
'<@(_outputs)',
'lib',
'<@(_inputs)',
],
}
],
}, # target js2asar
{
'target_name': 'app2asar',
'type': 'none',
'actions': [
{
'action_name': 'app2asar',
'variables': {
'conditions': [
['OS=="mac"', {
'resources_path': '<(PRODUCT_DIR)/<(product_name).app/Contents/Resources',
},{
'resources_path': '<(PRODUCT_DIR)/resources',
}],
],
},
'inputs': [
'<@(default_app_sources)',
],
'outputs': [
'<(resources_path)/default_app.asar',
],
'action': [
'python',
'tools/js2asar.py',
'<@(_outputs)',
'default_app',
'<@(_inputs)',
],
}
],
}, # target app2asar
{
'target_name': 'atom_js2c_copy',
'type': 'none',
'copies': [
{
'destination': '<(js2c_input_dir)',
'files': [
'<@(js2c_sources)',
],
},
],
}, # target atom_js2c_copy
{
'target_name': 'atom_browserify',
'type': 'none',
'dependencies': [
# depend on this target to ensure the '<(js2c_input_dir)' is created
'atom_js2c_copy',
],
'variables': {
'sandbox_args': [
'./lib/sandboxed_renderer/init.js',
'-r',
'./lib/sandboxed_renderer/api/exports/electron.js:electron',
'-r',
'./lib/sandboxed_renderer/api/exports/fs.js:fs',
'-r',
'./lib/sandboxed_renderer/api/exports/os.js:os',
'-r',
'./lib/sandboxed_renderer/api/exports/path.js:path',
'-r',
'./lib/sandboxed_renderer/api/exports/child_process.js:child_process'
],
'isolated_args': [
'lib/isolated_renderer/init.js',
]
},
'actions': [
{
'action_name': 'atom_browserify_sandbox',
'inputs': [
'<!@(python tools/list-browserify-deps.py <(sandbox_args))'
],
'outputs': [
'<(js2c_input_dir)/preload_bundle.js',
],
'action': [
'npm',
'run',
'--silent',
'browserify',
'--',
'<@(sandbox_args)',
'-o',
'<@(_outputs)',
],
},
{
'action_name': 'atom_browserify_isolated_context',
'inputs': [
'<!@(python tools/list-browserify-deps.py <(isolated_args))'
],
'outputs': [
'<(js2c_input_dir)/isolated_bundle.js',
],
'action': [
'npm',
'run',
'--silent',
'browserify',
'--',
'<@(isolated_args)',
'-o',
'<@(_outputs)',
],
},
],
}, # target atom_browserify
{
'target_name': 'atom_js2c',
'type': 'none',
'dependencies': [
'atom_js2c_copy',
'atom_browserify',
],
'actions': [
{
'action_name': 'atom_js2c',
'inputs': [
# List all input files that should trigger a rebuild with js2c
'<@(js2c_sources)',
'<(js2c_input_dir)/preload_bundle.js',
'<(js2c_input_dir)/isolated_bundle.js',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/atom_natives.h',
@@ -532,7 +398,7 @@
'python',
'tools/js2c.py',
'<@(_outputs)',
'<(js2c_input_dir)',
'<@(_inputs)',
],
}
],
@@ -563,9 +429,6 @@
'libraries': [
'$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
'$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework',
'$(SDKROOT)/System/Library/Frameworks/Quartz.framework',
'$(SDKROOT)/System/Library/Frameworks/Security.framework',
'$(SDKROOT)/System/Library/Frameworks/SecurityInterface.framework',
],
},
'mac_bundle': 1,
@@ -575,7 +438,6 @@
'<(libchromiumcontent_dir)/icudtl.dat',
'<(libchromiumcontent_dir)/natives_blob.bin',
'<(libchromiumcontent_dir)/snapshot_blob.bin',
'<(PRODUCT_DIR)/pdf_viewer_resources.pak',
],
'xcode_settings': {
'ATOM_BUNDLE_ID': 'com.<(company_abbr).<(project_name).framework',
@@ -623,6 +485,16 @@
'${BUILT_PRODUCTS_DIR}/<(product_name) Framework.framework/Versions/A/<(product_name) Framework',
],
},
{
'postbuild_name': 'Fix path of ffmpeg',
'action': [
'install_name_tool',
'-change',
'@loader_path/libffmpeg.dylib',
'@rpath/libffmpeg.dylib',
'${BUILT_PRODUCTS_DIR}/<(product_name) Framework.framework/Versions/A/<(product_name) Framework',
],
},
{
'postbuild_name': 'Add symlinks for framework subdirectories',
'action': [

View File

@@ -1 +0,0 @@
filter=+build/include_alpha

View File

@@ -7,7 +7,6 @@
#include <string>
#include <vector>
#include "atom/common/atom_constants.h"
#include "atom/common/atom_version.h"
#include "atom/common/chrome_version.h"
#include "atom/common/options_switches.h"
@@ -19,13 +18,12 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/pepper_plugin_info.h"
#include "content/public/common/user_agent.h"
#include "pdf/pdf.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "third_party/widevine/cdm/stub/widevine_cdm_version.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/url_constants.h"
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
#include "chrome/common/widevine_cdm_constants.h"
#endif
@@ -44,7 +42,7 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
std::vector<std::string> flash_version_numbers = base::SplitString(
version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
if (flash_version_numbers.empty())
if (flash_version_numbers.size() < 1)
flash_version_numbers.push_back("11");
// |SplitString()| puts in an empty string given an empty string. :(
else if (flash_version_numbers[0].empty())
@@ -73,7 +71,7 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
return plugin;
}
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
const std::string& version) {
content::PepperPluginInfo widevine_cdm;
@@ -91,11 +89,13 @@ content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
// Add the supported codecs as if they came from the component manifest.
std::vector<std::string> codecs;
codecs.push_back(kCdmSupportedCodecVorbis);
codecs.push_back(kCdmSupportedCodecVp8);
codecs.push_back(kCdmSupportedCodecVp9);
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
#if defined(USE_PROPRIETARY_CODECS)
codecs.push_back(kCdmSupportedCodecAac);
codecs.push_back(kCdmSupportedCodecAvc1);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
#endif // defined(USE_PROPRIETARY_CODECS)
std::string codec_string = base::JoinString(
codecs, std::string(1, kCdmSupportedCodecsValueDelimiter));
widevine_cdm_mime_type.additional_param_names.push_back(
@@ -110,25 +110,6 @@ content::PepperPluginInfo CreateWidevineCdmInfo(const base::FilePath& path,
}
#endif
void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
content::PepperPluginInfo pdf_info;
pdf_info.is_internal = true;
pdf_info.is_out_of_process = true;
pdf_info.name = "Chromium PDF Viewer";
pdf_info.description = "Portable Document Format";
pdf_info.path = base::FilePath::FromUTF8Unsafe(kPdfPluginPath);
content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf",
"Portable Document Format");
pdf_info.mime_types.push_back(pdf_mime_type);
pdf_info.internal_entry_points.get_interface = chrome_pdf::PPP_GetInterface;
pdf_info.internal_entry_points.initialize_module =
chrome_pdf::PPP_InitializeModule;
pdf_info.internal_entry_points.shutdown_module =
chrome_pdf::PPP_ShutdownModule;
pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV;
plugins->push_back(pdf_info);
}
void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
const char* separator,
const char* cmd_switch) {
@@ -145,7 +126,7 @@ void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
void AddPepperFlashFromCommandLine(
std::vector<content::PepperPluginInfo>* plugins) {
auto command_line = base::CommandLine::ForCurrentProcess();
base::FilePath flash_path = command_line->GetSwitchValuePath(
auto flash_path = command_line->GetSwitchValueNative(
switches::kPpapiFlashPath);
if (flash_path.empty())
return;
@@ -153,19 +134,20 @@ void AddPepperFlashFromCommandLine(
auto flash_version = command_line->GetSwitchValueASCII(
switches::kPpapiFlashVersion);
plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
plugins->push_back(
CreatePepperFlashInfo(base::FilePath(flash_path), flash_version));
}
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
void AddWidevineCdmFromCommandLine(
std::vector<content::PepperPluginInfo>* plugins) {
auto command_line = base::CommandLine::ForCurrentProcess();
base::FilePath widevine_cdm_path = command_line->GetSwitchValuePath(
auto widevine_cdm_path = command_line->GetSwitchValueNative(
switches::kWidevineCdmPath);
if (widevine_cdm_path.empty())
return;
if (!base::PathExists(widevine_cdm_path))
if (!base::PathExists(base::FilePath(widevine_cdm_path)))
return;
auto widevine_cdm_version = command_line->GetSwitchValueASCII(
@@ -173,7 +155,7 @@ void AddWidevineCdmFromCommandLine(
if (widevine_cdm_version.empty())
return;
plugins->push_back(CreateWidevineCdmInfo(widevine_cdm_path,
plugins->push_back(CreateWidevineCdmInfo(base::FilePath(widevine_cdm_path),
widevine_cdm_version));
}
#endif
@@ -198,28 +180,37 @@ base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
return l10n_util::GetStringUTF16(message_id);
}
void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
schemes->standard_schemes.push_back("chrome-extension");
std::vector<std::string> splited;
ConvertStringWithSeparatorToVector(&splited, ",",
switches::kRegisterServiceWorkerSchemes);
for (const std::string& scheme : splited)
schemes->service_worker_schemes.push_back(scheme);
schemes->service_worker_schemes.push_back(url::kFileScheme);
ConvertStringWithSeparatorToVector(&splited, ",", switches::kSecureSchemes);
for (const std::string& scheme : splited)
schemes->secure_schemes.push_back(scheme);
void AtomContentClient::AddAdditionalSchemes(
std::vector<url::SchemeWithType>* standard_schemes,
std::vector<std::string>* savable_schemes) {
std::vector<std::string> schemes;
ConvertStringWithSeparatorToVector(&schemes, ",",
switches::kRegisterStandardSchemes);
if (!schemes.empty()) {
for (const std::string& scheme : schemes)
standard_schemes->push_back({scheme.c_str(), url::SCHEME_WITHOUT_PORT});
}
standard_schemes->push_back({"chrome-extension", url::SCHEME_WITHOUT_PORT});
}
void AtomContentClient::AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) {
AddPepperFlashFromCommandLine(plugins);
#if defined(WIDEVINE_CDM_AVAILABLE) && BUILDFLAG(ENABLE_PEPPER_CDMS)
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
AddWidevineCdmFromCommandLine(plugins);
#endif
ComputeBuiltInPlugins(plugins);
}
void AtomContentClient::AddServiceWorkerSchemes(
std::set<std::string>* service_worker_schemes) {
std::vector<std::string> schemes;
ConvertStringWithSeparatorToVector(&schemes, ",",
switches::kRegisterServiceWorkerSchemes);
if (!schemes.empty()) {
for (const std::string& scheme : schemes)
service_worker_schemes->insert(scheme);
}
service_worker_schemes->insert(url::kFileScheme);
}
} // namespace atom

View File

@@ -23,9 +23,13 @@ class AtomContentClient : public brightray::ContentClient {
std::string GetProduct() const override;
std::string GetUserAgent() const override;
base::string16 GetLocalizedString(int message_id) const override;
void AddAdditionalSchemes(Schemes* schemes) override;
void AddAdditionalSchemes(
std::vector<url::SchemeWithType>* standard_schemes,
std::vector<std::string>* savable_schemes) override;
void AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) override;
void AddServiceWorkerSchemes(
std::set<std::string>* service_worker_schemes) override;
private:
DISALLOW_COPY_AND_ASSIGN(AtomContentClient);

View File

@@ -5,7 +5,7 @@
#ifndef ATOM_APP_ATOM_LIBRARY_MAIN_H_
#define ATOM_APP_ATOM_LIBRARY_MAIN_H_
#include "build/build_config.h"
#include "base/basictypes.h"
#if defined(OS_MACOSX)
extern "C" {

View File

@@ -7,20 +7,18 @@
#include <stdlib.h>
#if defined(OS_WIN)
#include <windows.h> // windows.h must be included first
#include <atlbase.h> // ensures that ATL statics like `_AtlWinModule` are initialized (it's an issue in static debug build)
#include <shellapi.h>
#include <windows.h>
#include <shellscalingapi.h>
#include <tchar.h>
#include <shellapi.h>
#include "atom/app/atom_main_delegate.h"
#include "atom/common/crash_reporter/win/crash_service_main.h"
#include "base/environment.h"
#include "base/process/launch.h"
#include "base/win/windows_version.h"
#include "content/public/app/sandbox_helper_win.h"
#include "content/public/app/startup_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"
#include "ui/gfx/win/dpi.h"
#elif defined(OS_LINUX) // defined(OS_WIN)
#include "atom/app/atom_main_delegate.h" // NOLINT
#include "content/public/app/content_main.h"
@@ -35,7 +33,8 @@
namespace {
const auto kRunAsNode = "ELECTRON_RUN_AS_NODE";
const char* kRunAsNode = "ELECTRON_RUN_AS_NODE";
const char* kOldRunAsNode = "ATOM_SHELL_INTERNAL_RUN_AS_NODE";
bool IsEnvSet(const char* name) {
#if defined(OS_WIN)
@@ -48,6 +47,50 @@ bool IsEnvSet(const char* name) {
#endif
}
bool IsRunAsNode() {
return IsEnvSet(kRunAsNode) || IsEnvSet(kOldRunAsNode);
}
#if defined(OS_WIN)
// Win8.1 supports monitor-specific DPI scaling.
bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
typedef HRESULT(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
reinterpret_cast<SetProcessDpiAwarenessPtr>(
GetProcAddress(GetModuleHandleA("user32.dll"),
"SetProcessDpiAwarenessInternal"));
if (set_process_dpi_awareness_func) {
HRESULT hr = set_process_dpi_awareness_func(value);
if (SUCCEEDED(hr)) {
VLOG(1) << "SetProcessDpiAwareness succeeded.";
return true;
} else if (hr == E_ACCESSDENIED) {
LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
"Function called twice, or manifest was used.";
}
}
return false;
}
// This function works for Windows Vista through Win8. Win8.1 must use
// SetProcessDpiAwareness[Wrapper].
BOOL SetProcessDPIAwareWrapper() {
typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
SetProcessDPIAwarePtr set_process_dpi_aware_func =
reinterpret_cast<SetProcessDPIAwarePtr>(
GetProcAddress(GetModuleHandleA("user32.dll"),
"SetProcessDPIAware"));
return set_process_dpi_aware_func &&
set_process_dpi_aware_func();
}
void EnableHighDPISupport() {
if (!SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
SetProcessDPIAwareWrapper();
}
}
#endif
} // namespace
#if defined(OS_WIN)
@@ -55,35 +98,14 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
int argc = 0;
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
bool run_as_node = IsEnvSet(kRunAsNode);
// Make output work in console if we are not in cygiwn.
if (!IsEnvSet("TERM") && !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE")) {
AttachConsole(ATTACH_PARENT_PROCESS);
#ifdef _DEBUG
// Don't display assert dialog boxes in CI test runs
static const auto kCI = "ELECTRON_CI";
bool is_ci = IsEnvSet(kCI);
if (!is_ci) {
for (int i = 0; i < argc; ++i) {
if (!_wcsicmp(wargv[i], L"--ci")) {
is_ci = true;
_putenv_s(kCI, "1"); // set flag for child processes
break;
}
}
FILE* dontcare;
freopen_s(&dontcare, "CON", "w", stdout);
freopen_s(&dontcare, "CON", "w", stderr);
}
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
// Make sure the output is printed to console.
if (run_as_node || !IsEnvSet("ELECTRON_NO_ATTACH_CONSOLE"))
base::RouteStdioToConsole(false);
// Convert argv to to UTF8
char** argv = new char*[argc];
@@ -119,31 +141,12 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
}
}
#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 (run_as_node) {
if (IsRunAsNode()) {
// Now that argv conversion is done, we can finally start.
base::AtExitManager atexit_manager;
base::i18n::InitializeICU();
return atom::NodeMain(argc, argv);
} else if (IsEnvSet("ELECTRON_INTERNAL_CRASH_SERVICE")) {
} else if (IsEnvSet("ATOM_SHELL_INTERNAL_CRASH_SERVICE")) {
return crash_service::Main(cmd);
}
@@ -151,18 +154,23 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
content::InitializeSandboxInfo(&sandbox_info);
atom::AtomMainDelegate delegate;
// We don't want to set DPI awareness on pre-Win7 because we don't support
// DirectWrite there. GDI fonts are kerned very badly, so better to leave
// DPI-unaware and at effective 1.0. See also ShouldUseDirectWrite().
if (base::win::GetVersion() >= base::win::VERSION_WIN7)
EnableHighDPISupport();
content::ContentMainParams params(&delegate);
params.instance = instance;
params.sandbox_info = &sandbox_info;
atom::AtomCommandLine::Init(argc, argv);
atom::AtomCommandLine::InitW(argc, wargv);
return content::ContentMain(params);
}
#elif defined(OS_LINUX) // defined(OS_WIN)
int main(int argc, const char* argv[]) {
if (IsEnvSet(kRunAsNode)) {
if (IsRunAsNode()) {
base::i18n::InitializeICU();
base::AtExitManager atexit_manager;
return atom::NodeMain(argc, const_cast<char**>(argv));
@@ -179,7 +187,7 @@ int main(int argc, const char* argv[]) {
#else // defined(OS_LINUX)
int main(int argc, const char* argv[]) {
if (IsEnvSet(kRunAsNode)) {
if (IsRunAsNode()) {
return AtomInitializeICUandStartNode(argc, const_cast<char**>(argv));
}

View File

@@ -4,16 +4,13 @@
#include "atom/app/atom_main_delegate.h"
#include <iostream>
#include <string>
#include <iostream>
#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"
@@ -28,20 +25,11 @@ namespace atom {
namespace {
const char* kRelauncherProcess = "relauncher";
bool IsBrowserProcess(base::CommandLine* cmd) {
std::string process_type = cmd->GetSwitchValueASCII(::switches::kProcessType);
std::string process_type = cmd->GetSwitchValueASCII(switches::kProcessType);
return process_type.empty();
}
#if defined(OS_WIN)
void InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*,
unsigned int, uintptr_t) {
// noop.
}
#endif
} // namespace
AtomMainDelegate::AtomMainDelegate() {
@@ -73,8 +61,8 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
#endif // !defined(OS_WIN)
// Only enable logging when --enable-logging is specified.
std::unique_ptr<base::Environment> env(base::Environment::Create());
if (!command_line->HasSwitch(::switches::kEnableLogging) &&
scoped_ptr<base::Environment> 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);
@@ -95,18 +83,6 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
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);
}
@@ -114,31 +90,27 @@ void AtomMainDelegate::PreSandboxStartup() {
brightray::MainDelegate::PreSandboxStartup();
// Set google API key.
std::unique_ptr<base::Environment> env(base::Environment::Create());
scoped_ptr<base::Environment> env(base::Environment::Create());
if (!env->HasVar("GOOGLE_API_KEY"))
env->SetVar("GOOGLE_API_KEY", GOOGLEAPIS_API_KEY);
auto command_line = base::CommandLine::ForCurrentProcess();
std::string process_type = command_line->GetSwitchValueASCII(
::switches::kProcessType);
switches::kProcessType);
if (process_type == switches::kUtilityProcess) {
AtomContentUtilityClient::PreSandboxStartup();
}
// Only append arguments for browser process.
if (!IsBrowserProcess(command_line))
return;
if (!command_line->HasSwitch(switches::kEnableMixedSandbox)) {
if (command_line->HasSwitch(switches::kEnableSandbox)) {
// Disable setuid sandbox since it is not longer required on
// linux(namespace sandbox is available on most distros).
command_line->AppendSwitch(::switches::kDisableSetuidSandbox);
} else {
// Disable renderer sandbox for most of node's functions.
command_line->AppendSwitch(::switches::kNoSandbox);
}
}
// Disable renderer sandbox for most of node's functions.
command_line->AppendSwitch(switches::kNoSandbox);
// Allow file:// URIs to read other file:// URIs by default.
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);
#if defined(OS_MACOSX)
// Enable AVFoundation.
@@ -153,15 +125,7 @@ content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
content::ContentRendererClient*
AtomMainDelegate::CreateContentRendererClient() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableSandbox) ||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kNoSandbox)) {
renderer_client_.reset(new AtomSandboxedRendererClient);
} else {
renderer_client_.reset(new AtomRendererClient);
}
renderer_client_.reset(new AtomRendererClient);
return renderer_client_.get();
}
@@ -170,29 +134,8 @@ content::ContentUtilityClient* AtomMainDelegate::CreateContentUtilityClient() {
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::unique_ptr<brightray::ContentClient>(new AtomContentClient);
scoped_ptr<brightray::ContentClient> AtomMainDelegate::CreateContentClient() {
return scoped_ptr<brightray::ContentClient>(new AtomContentClient).Pass();
}
} // namespace atom

View File

@@ -5,10 +5,8 @@
#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_H_
#define ATOM_APP_ATOM_MAIN_DELEGATE_H_
#include <string>
#include "brightray/common/content_client.h"
#include "brightray/common/main_delegate.h"
#include "brightray/common/content_client.h"
namespace atom {
@@ -24,30 +22,19 @@ class AtomMainDelegate : public brightray::MainDelegate {
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;
scoped_ptr<brightray::ContentClient> CreateContentClient() override;
#if defined(OS_MACOSX)
void OverrideChildProcessPath() override;
void OverrideFrameworkBundlePath() override;
#endif
private:
#if defined(OS_MACOSX)
void SetUpBundleOverrides();
#endif
brightray::ContentClient content_client_;
std::unique_ptr<content::ContentBrowserClient> browser_client_;
std::unique_ptr<content::ContentRendererClient> renderer_client_;
std::unique_ptr<content::ContentUtilityClient> utility_client_;
scoped_ptr<content::ContentBrowserClient> browser_client_;
scoped_ptr<content::ContentRendererClient> renderer_client_;
scoped_ptr<content::ContentUtilityClient> utility_client_;
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
};

View File

@@ -7,10 +7,7 @@
#include "base/mac/bundle_locations.h"
#include "base/files/file_path.h"
#include "base/files/file_util.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"
@@ -51,15 +48,4 @@ void AtomMainDelegate::OverrideChildProcessPath() {
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());
}
} // namespace atom

View File

@@ -7,18 +7,12 @@
#include "atom/app/uv_task_runner.h"
#include "atom/browser/javascript_environment.h"
#include "atom/browser/node_debugger.h"
#include "atom/common/api/atom_bindings.h"
#include "atom/common/crash_reporter/crash_reporter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/threading/thread_task_runner_handle.h"
#include "atom/common/node_includes.h"
#include "base/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 {
@@ -33,11 +27,6 @@ int NodeMain(int argc, char *argv[]) {
scoped_refptr<UvTaskRunner> uv_task_runner(new UvTaskRunner(loop));
base::ThreadTaskRunnerHandle handle(uv_task_runner);
// Initialize feature list.
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
feature_list->InitializeFromCommandLine("", "");
base::FeatureList::SetInstance(std::move(feature_list));
gin::V8Initializer::LoadV8Snapshot();
gin::V8Initializer::LoadV8Natives();
JavascriptEnvironment gin_env;
@@ -46,25 +35,14 @@ int NodeMain(int argc, char *argv[]) {
const char** exec_argv;
node::Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
node::IsolateData isolate_data(gin_env.isolate(), loop);
node::Environment* env = node::CreateEnvironment(
&isolate_data, gin_env.context(), argc, argv,
gin_env.isolate(), loop, gin_env.context(), argc, argv,
exec_argc, exec_argv);
// Enable support for v8 inspector.
NodeDebugger node_debugger(env);
node_debugger.Start();
mate::Dictionary process(gin_env.isolate(), env->process_object());
#if defined(OS_WIN)
process.SetMethod("log", &AtomBindings::Log);
#endif
process.SetMethod("crash", &AtomBindings::Crash);
// Setup process.crashReporter.start in child node processes
auto reporter = mate::Dictionary::CreateEmpty(gin_env.isolate());
reporter.SetMethod("start", &crash_reporter::CrashReporter::StartInstance);
process.Set("crashReporter", reporter);
// Start our custom debugger implementation.
NodeDebugger node_debugger(gin_env.isolate());
if (node_debugger.IsRunning())
env->AssignToContext(v8::Debug::GetDebugContext());
node::LoadEnvironment(env);
@@ -85,7 +63,7 @@ int NodeMain(int argc, char *argv[]) {
exit_code = node::EmitExit(env);
node::RunAtExit(env);
node::FreeEnvironment(env);
env->Dispose();
}
v8::V8::Dispose();

View File

@@ -2,8 +2,6 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include <utility>
#include "atom/app/uv_task_runner.h"
#include "base/stl_util.h"
@@ -21,13 +19,13 @@ UvTaskRunner::~UvTaskRunner() {
}
bool UvTaskRunner::PostDelayedTask(const tracked_objects::Location& from_here,
base::OnceClosure task,
const base::Closure& task,
base::TimeDelta delay) {
auto* timer = new uv_timer_t;
uv_timer_t* timer = new uv_timer_t;
timer->data = this;
uv_timer_init(loop_, timer);
uv_timer_start(timer, UvTaskRunner::OnTimeout, delay.InMilliseconds(), 0);
tasks_[timer] = std::move(task);
tasks_[timer] = task;
return true;
}
@@ -37,9 +35,9 @@ bool UvTaskRunner::RunsTasksOnCurrentThread() const {
bool UvTaskRunner::PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
base::OnceClosure task,
const base::Closure& task,
base::TimeDelta delay) {
return PostDelayedTask(from_here, std::move(task), delay);
return PostDelayedTask(from_here, task, delay);
}
// static
@@ -48,7 +46,7 @@ void UvTaskRunner::OnTimeout(uv_timer_t* timer) {
if (!ContainsKey(self->tasks_, timer))
return;
std::move(self->tasks_[timer]).Run();
self->tasks_[timer].Run();
self->tasks_.erase(timer);
uv_timer_stop(timer);
uv_close(reinterpret_cast<uv_handle_t*>(timer), UvTaskRunner::OnClose);

View File

@@ -21,12 +21,12 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
// base::SingleThreadTaskRunner:
bool PostDelayedTask(const tracked_objects::Location& from_here,
base::OnceClosure task,
const base::Closure& task,
base::TimeDelta delay) override;
bool RunsTasksOnCurrentThread() const override;
bool PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
base::OnceClosure task,
const base::Closure& task,
base::TimeDelta delay) override;
private:
@@ -35,7 +35,7 @@ class UvTaskRunner : public base::SingleThreadTaskRunner {
uv_loop_t* loop_;
std::map<uv_timer_t*, base::OnceClosure> tasks_;
std::map<uv_timer_t*, base::Closure> tasks_;
DISALLOW_COPY_AND_ASSIGN(UvTaskRunner);
};

File diff suppressed because it is too large Load Diff

View File

@@ -5,30 +5,15 @@
#ifndef ATOM_BROWSER_API_ATOM_API_APP_H_
#define ATOM_BROWSER_API_ATOM_API_APP_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "atom/browser/api/event_emitter.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/browser.h"
#include "atom/browser/browser_observer.h"
#include "atom/common/native_mate_converters/callback.h"
#include "base/process/process_iterator.h"
#include "base/task/cancelable_task_tracker.h"
#include "chrome/browser/icon_manager.h"
#include "chrome/browser/process_singleton.h"
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "content/public/browser/render_process_host.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "net/base/completion_callback.h"
#if defined(USE_NSS_CERTS)
#include "chrome/browser/certificate_manager_model.h"
#endif
namespace base {
class FilePath;
@@ -36,69 +21,22 @@ class FilePath;
namespace mate {
class Arguments;
} // namespace mate
}
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) {
this->type = type;
this->pid = pid;
this->metrics = std::move(metrics);
}
};
namespace api {
class App : public AtomBrowserClient::Delegate,
public mate::EventEmitter<App>,
public mate::EventEmitter,
public BrowserObserver,
public content::GpuDataManagerObserver,
public content::BrowserChildProcessObserver {
public content::GpuDataManagerObserver {
public:
using FileIconCallback = base::Callback<void(v8::Local<v8::Value>,
const gfx::Image&)>;
static mate::Handle<App> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// Called when window with disposition needs to be created.
void OnCreateWindow(
const GURL& target_url,
const std::string& frame_name,
WindowOpenDisposition disposition,
const std::vector<std::string>& features,
const scoped_refptr<content::ResourceRequestBodyImpl>& body,
int render_process_id,
int render_frame_id);
#if defined(USE_NSS_CERTS)
void OnCertificateManagerModelCreated(
std::unique_ptr<base::DictionaryValue> options,
const net::CompletionCallback& callback,
std::unique_ptr<CertificateManagerModel> model);
#endif
base::FilePath GetAppPath() const;
void RenderProcessReady(content::RenderProcessHost* host);
void RenderProcessDisconnected(base::ProcessId host_pid);
void PreMainMessageLoopRun();
protected:
explicit App(v8::Isolate* isolate);
~App() override;
App();
virtual ~App();
// BrowserObserver:
void OnBeforeQuit(bool* prevent_default) override;
@@ -109,35 +47,13 @@ class App : public AtomBrowserClient::Delegate,
void OnOpenURL(const std::string& url) override;
void OnActivate(bool has_visible_windows) override;
void OnWillFinishLaunching() override;
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
void OnLogin(LoginHandler* login_handler,
const base::DictionaryValue& request_details) override;
void OnAccessibilitySupportChanged() override;
void OnPreMainMessageLoopRun() override;
#if defined(OS_MACOSX)
void OnWillContinueUserActivity(
bool* prevent_default,
const std::string& type) override;
void OnDidFailToContinueUserActivity(
const std::string& type,
const std::string& error) override;
void OnContinueUserActivity(
bool* prevent_default,
const std::string& type,
const base::DictionaryValue& user_info) override;
void OnUserActivityWasContinued(
const std::string& type,
const base::DictionaryValue& user_info) override;
void OnUpdateUserActivityState(
bool* prevent_default,
const std::string& type,
const base::DictionaryValue& user_info) override;
void OnNewWindowForTab() override;
#endif
void OnFinishLaunching() override;
void OnLogin(LoginHandler* login_handler) override;
// content::ContentBrowserClient:
void AllowCertificateError(
content::WebContents* web_contents,
int render_process_id,
int render_frame_id,
int cert_error,
const net::SSLInfo& ssl_info,
const GURL& request_url,
@@ -145,31 +61,25 @@ class App : public AtomBrowserClient::Delegate,
bool overridable,
bool strict_enforcement,
bool expired_previous_decision,
const base::Callback<void(content::CertificateRequestResultType)>&
callback) override;
const base::Callback<void(bool)>& callback,
content::CertificateRequestResultType* request) override;
void SelectClientCertificate(
content::WebContents* web_contents,
net::SSLCertRequestInfo* cert_request_info,
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
// content::GpuDataManagerObserver:
void OnGpuProcessCrashed(base::TerminationStatus status) override;
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
// content::BrowserChildProcessObserver:
void BrowserChildProcessLaunchedAndConnected(
const content::ChildProcessData& data) override;
void BrowserChildProcessHostDisconnected(
const content::ChildProcessData& data) override;
void BrowserChildProcessCrashed(
const content::ChildProcessData& data, int exit_code) override;
void BrowserChildProcessKilled(
const content::ChildProcessData& data, int exit_code) override;
#if defined(OS_MACOSX)
void OnPlatformThemeChanged() override;
#endif
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
void SetAppPath(const base::FilePath& app_path);
void ChildProcessLaunched(int process_type, base::ProcessHandle handle);
void ChildProcessDisconnected(base::ProcessId pid);
// Get/Set the pre-defined path in PathService.
base::FilePath GetPath(mate::Arguments* args, const std::string& name);
void SetPath(mate::Arguments* args,
@@ -177,55 +87,16 @@ class App : public AtomBrowserClient::Delegate,
const base::FilePath& path);
void SetDesktopName(const std::string& desktop_name);
std::string GetLocale();
void AllowNTLMCredentialsForAllDomains(bool should_allow);
bool MakeSingleInstance(
const ProcessSingleton::NotificationCallback& callback);
void ReleaseSingleInstance();
bool Relaunch(mate::Arguments* args);
void DisableHardwareAcceleration(mate::Arguments* args);
void DisableDomainBlockingFor3DAPIs(mate::Arguments* args);
bool IsAccessibilitySupportEnabled();
void SetAccessibilitySupportEnabled(bool enabled);
Browser::LoginItemSettings GetLoginItemSettings(mate::Arguments* args);
#if defined(USE_NSS_CERTS)
void ImportCertificate(const base::DictionaryValue& options,
const net::CompletionCallback& callback);
#endif
void GetFileIcon(const base::FilePath& path,
mate::Arguments* args);
std::vector<mate::Dictionary> GetAppMetrics(v8::Isolate* isolate);
v8::Local<v8::Value> GetGPUFeatureStatus(v8::Isolate* isolate);
void EnableMixedSandbox(mate::Arguments* args);
#if defined(OS_MACOSX)
bool MoveToApplicationsFolder(mate::Arguments* args);
bool IsInApplicationsFolder();
#endif
std::string GetLocale();
#if defined(OS_WIN)
// Get the current Jump List settings.
v8::Local<v8::Value> GetJumpListSettings();
// Set or remove a custom Jump List for the application.
JumpListResult SetJumpList(v8::Local<v8::Value> val, mate::Arguments* args);
#endif // defined(OS_WIN)
std::unique_ptr<ProcessSingleton> process_singleton_;
#if defined(USE_NSS_CERTS)
std::unique_ptr<CertificateManagerModel> certificate_manager_model_;
bool IsAeroGlassEnabled();
#endif
// Tracks tasks requesting file icons.
base::CancelableTaskTracker cancelable_task_tracker_;
base::FilePath app_path_;
using ProcessMetricMap =
std::unordered_map<base::ProcessId,
std::unique_ptr<atom::ProcessMetric>>;
ProcessMetricMap app_metrics_;
scoped_ptr<ProcessSingleton> process_singleton_;
DISALLOW_COPY_AND_ASSIGN(App);
};

View File

@@ -4,13 +4,12 @@
#include "atom/browser/api/atom_api_auto_updater.h"
#include "base/time/time.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 "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
@@ -35,9 +34,8 @@ namespace atom {
namespace api {
AutoUpdater::AutoUpdater(v8::Isolate* isolate) {
AutoUpdater::AutoUpdater() {
auto_updater::AutoUpdater::SetDelegate(this);
Init(isolate);
}
AutoUpdater::~AutoUpdater() {
@@ -48,32 +46,13 @@ void AutoUpdater::OnError(const std::string& message) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
mate::EmitEvent(
isolate(),
GetWrapper(),
EmitCustomEvent(
"error",
error->ToObject(isolate()->GetCurrentContext()).ToLocalChecked(),
// Message is also emitted to keep compatibility with old code.
message);
}
void AutoUpdater::OnError(const std::string& message,
const int code, const std::string& domain) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
auto error = v8::Exception::Error(mate::StringToV8(isolate(), message));
auto errorObject = error->ToObject(
isolate()->GetCurrentContext()).ToLocalChecked();
// add two new params for better error handling
errorObject->Set(mate::StringToV8(isolate(), "code"),
v8::Integer::New(isolate(), code));
errorObject->Set(mate::StringToV8(isolate(), "domain"),
mate::StringToV8(isolate(), domain));
mate::EmitEvent(isolate(), GetWrapper(), "error", errorObject, message);
}
void AutoUpdater::OnCheckingForUpdate() {
Emit("checking-for-update");
}
@@ -99,38 +78,31 @@ void AutoUpdater::OnWindowAllClosed() {
QuitAndInstall();
}
void AutoUpdater::SetFeedURL(const std::string& url, mate::Arguments* args) {
auto_updater::AutoUpdater::HeaderMap headers;
args->GetNext(&headers);
auto_updater::AutoUpdater::SetFeedURL(url, headers);
mate::ObjectTemplateBuilder AutoUpdater::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("setFeedURL", &auto_updater::AutoUpdater::SetFeedURL)
.SetMethod("checkForUpdates", &auto_updater::AutoUpdater::CheckForUpdates)
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
}
void AutoUpdater::QuitAndInstall() {
// If we don't have any window then quitAndInstall immediately.
if (WindowList::IsEmpty()) {
WindowList* window_list = WindowList::GetInstance();
if (window_list->size() == 0) {
auto_updater::AutoUpdater::QuitAndInstall();
return;
}
// Otherwise do the restart after all windows have been closed.
WindowList::AddObserver(this);
WindowList::CloseAllWindows();
window_list->AddObserver(this);
for (NativeWindow* window : *window_list)
window->Close();
}
// static
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(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)
.SetMethod("quitAndInstall", &AutoUpdater::QuitAndInstall);
return CreateHandle(isolate, new AutoUpdater);
}
} // namespace api
@@ -140,14 +112,11 @@ void AutoUpdater::BuildPrototype(
namespace {
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();
mate::Dictionary dict(isolate, exports);
dict.Set("autoUpdater", AutoUpdater::Create(isolate));
dict.Set("AutoUpdater", AutoUpdater::GetConstructor(isolate)->GetFunction());
dict.Set("autoUpdater", atom::api::AutoUpdater::Create(isolate));
}
} // namespace

View File

@@ -10,30 +10,24 @@
#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 atom {
namespace api {
class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
class AutoUpdater : public mate::EventEmitter,
public auto_updater::Delegate,
public WindowListObserver {
public:
static mate::Handle<AutoUpdater> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit AutoUpdater(v8::Isolate* isolate);
~AutoUpdater() override;
AutoUpdater();
virtual ~AutoUpdater();
// Delegate implementations.
void OnError(const std::string& error) override;
void OnError(const std::string& message, const int code,
const std::string& domain);
void OnCheckingForUpdate() override;
void OnUpdateAvailable() override;
void OnUpdateNotAvailable() override;
@@ -45,9 +39,11 @@ class AutoUpdater : public mate::EventEmitter<AutoUpdater>,
// WindowListObserver:
void OnWindowAllClosed() override;
// mate::Wrappable implementations:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
std::string GetFeedURL();
void SetFeedURL(const std::string& url, mate::Arguments* args);
void QuitAndInstall();
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);

View File

@@ -1,163 +0,0 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_browser_view.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/browser.h"
#include "atom/browser/native_browser_view.h"
#include "atom/common/color_util.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "atom/common/options_switches.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/geometry/rect.h"
namespace mate {
template <>
struct Converter<atom::AutoResizeFlags> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
atom::AutoResizeFlags* auto_resize_flags) {
mate::Dictionary params;
if (!ConvertFromV8(isolate, val, &params)) {
return false;
}
uint8_t flags = 0;
bool width = false;
if (params.Get("width", &width) && width) {
flags |= atom::kAutoResizeWidth;
}
bool height = false;
if (params.Get("height", &height) && height) {
flags |= atom::kAutoResizeHeight;
}
*auto_resize_flags = static_cast<atom::AutoResizeFlags>(flags);
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
BrowserView::BrowserView(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options)
: api_web_contents_(nullptr) {
Init(isolate, wrapper, options);
}
void BrowserView::Init(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options) {
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
web_preferences.Set("isBrowserView", true);
mate::Handle<class WebContents> web_contents =
WebContents::Create(isolate, web_preferences);
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
view_.reset(NativeBrowserView::Create(
api_web_contents_->managed_web_contents()->GetView()));
InitWith(isolate, wrapper);
}
BrowserView::~BrowserView() {
api_web_contents_->DestroyWebContents(true /* async */);
}
// static
mate::WrappableBase* BrowserView::New(mate::Arguments* args) {
if (!Browser::Get()->is_ready()) {
args->ThrowError("Cannot create BrowserView before app is ready");
return nullptr;
}
if (args->Length() > 1) {
args->ThrowError("Too many arguments");
return nullptr;
}
mate::Dictionary options;
if (!(args->Length() == 1 && args->GetNext(&options))) {
options = mate::Dictionary::CreateEmpty(args->isolate());
}
return new BrowserView(args->isolate(), args->GetThis(), options);
}
int32_t BrowserView::ID() const {
return weak_map_id();
}
void BrowserView::SetAutoResize(AutoResizeFlags flags) {
view_->SetAutoResizeFlags(flags);
}
void BrowserView::SetBounds(const gfx::Rect& bounds) {
view_->SetBounds(bounds);
}
void BrowserView::SetBackgroundColor(const std::string& color_name) {
view_->SetBackgroundColor(ParseHexColor(color_name));
}
v8::Local<v8::Value> BrowserView::WebContents() {
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::WebContents)
.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);
mate::Dictionary dict(isolate, exports);
dict.Set("BrowserView", browser_view);
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_browser_view, Initialize)

View File

@@ -1,73 +0,0 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
#define ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_
#include <memory>
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/native_browser_view.h"
#include "native_mate/handle.h"
namespace gfx {
class Rect;
}
namespace mate {
class Arguments;
class Dictionary;
} // namespace mate
namespace atom {
class NativeBrowserView;
namespace api {
class WebContents;
class BrowserView : public mate::TrackableObject<BrowserView> {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
WebContents* web_contents() const { return api_web_contents_; }
NativeBrowserView* view() const { return view_.get(); }
int32_t ID() const;
protected:
BrowserView(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
~BrowserView() override;
private:
void Init(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
void SetAutoResize(AutoResizeFlags flags);
void SetBounds(const gfx::Rect& bounds);
void SetBackgroundColor(const std::string& color_name);
v8::Local<v8::Value> WebContents();
v8::Global<v8::Value> web_contents_;
class WebContents* api_web_contents_;
std::unique_ptr<NativeBrowserView> view_;
DISALLOW_COPY_AND_ASSIGN(BrowserView);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_VIEW_H_

View File

@@ -7,13 +7,12 @@
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/node_includes.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "content/public/browser/tracing_controller.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
using content::TracingController;
namespace mate {
@@ -54,7 +53,13 @@ scoped_refptr<TracingController::TraceDataSink> GetTraceDataSink(
void StopRecording(const base::FilePath& path,
const CompletionCallback& callback) {
TracingController::GetInstance()->StopTracing(
TracingController::GetInstance()->DisableRecording(
GetTraceDataSink(path, callback));
}
void CaptureMonitoringSnapshot(const base::FilePath& path,
const CompletionCallback& callback) {
TracingController::GetInstance()->CaptureMonitoringSnapshot(
GetTraceDataSink(path, callback));
}
@@ -65,10 +70,19 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
dict.SetMethod("getCategories", base::Bind(
&TracingController::GetCategories, controller));
dict.SetMethod("startRecording", base::Bind(
&TracingController::StartTracing, controller));
&TracingController::EnableRecording, controller));
dict.SetMethod("stopRecording", &StopRecording);
dict.SetMethod("startMonitoring", base::Bind(
&TracingController::EnableMonitoring, controller));
dict.SetMethod("stopMonitoring", base::Bind(
&TracingController::DisableMonitoring, controller));
dict.SetMethod("captureMonitoringSnapshot", &CaptureMonitoringSnapshot);
dict.SetMethod("getTraceBufferUsage", base::Bind(
&TracingController::GetTraceBufferUsage, controller));
dict.SetMethod("setWatchEvent", base::Bind(
&TracingController::SetWatchEvent, controller));
dict.SetMethod("cancelWatchEvent", base::Bind(
&TracingController::CancelWatchEvent, controller));
}
} // namespace

View File

@@ -4,7 +4,6 @@
#include "atom/browser/api/atom_api_cookies.h"
#include "atom/browser/atom_browser_context.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"
@@ -20,7 +19,6 @@
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
using atom::AtomCookieDelegate;
using content::BrowserThread;
namespace mate {
@@ -32,7 +30,7 @@ struct Converter<atom::api::Cookies::Error> {
if (val == atom::api::Cookies::SUCCESS)
return v8::Null(isolate);
else
return v8::Exception::Error(StringToV8(isolate, "Setting cookie failed"));
return v8::Exception::Error(StringToV8(isolate, "failed"));
}
};
@@ -49,38 +47,12 @@ struct Converter<net::CanonicalCookie> {
dict.Set("secure", val.IsSecure());
dict.Set("httpOnly", val.IsHttpOnly());
dict.Set("session", !val.IsPersistent());
if (val.IsPersistent())
if (!val.IsPersistent())
dict.Set("expirationDate", val.ExpiryDate().ToDoubleT());
return dict.GetHandle();
}
};
template<>
struct Converter<net::CookieStore::ChangeCause> {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const net::CookieStore::ChangeCause& val) {
switch (val) {
case net::CookieStore::ChangeCause::INSERTED:
case net::CookieStore::ChangeCause::EXPLICIT:
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_BETWEEN:
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_PREDICATE:
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_SINGLE:
case net::CookieStore::ChangeCause::EXPLICIT_DELETE_CANONICAL:
return mate::StringToV8(isolate, "explicit");
case net::CookieStore::ChangeCause::OVERWRITE:
return mate::StringToV8(isolate, "overwrite");
case net::CookieStore::ChangeCause::EXPIRED:
return mate::StringToV8(isolate, "expired");
case net::CookieStore::ChangeCause::EVICTED:
return mate::StringToV8(isolate, "evicted");
case net::CookieStore::ChangeCause::EXPIRED_OVERWRITE:
return mate::StringToV8(isolate, "expired-overwrite");
default:
return mate::StringToV8(isolate, "unknown");
}
}
};
} // namespace mate
namespace atom {
@@ -140,7 +112,7 @@ void RunCallbackInUI(const base::Closure& callback) {
}
// Remove cookies from |list| not matching |filter|, and pass it to |callback|.
void FilterCookies(std::unique_ptr<base::DictionaryValue> filter,
void FilterCookies(scoped_ptr<base::DictionaryValue> filter,
const Cookies::GetCallback& callback,
const net::CookieList& list) {
net::CookieList result;
@@ -153,7 +125,7 @@ void FilterCookies(std::unique_ptr<base::DictionaryValue> filter,
// Receives cookies matching |filter| in IO thread.
void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
std::unique_ptr<base::DictionaryValue> filter,
scoped_ptr<base::DictionaryValue> filter,
const Cookies::GetCallback& callback) {
std::string url;
filter->GetString("url", &url);
@@ -161,12 +133,12 @@ void GetCookiesOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
auto filtered_callback =
base::Bind(FilterCookies, base::Passed(&filter), callback);
net::CookieMonster* monster = GetCookieStore(getter)->GetCookieMonster();
// Empty url will match all url cookies.
if (url.empty())
GetCookieStore(getter)->GetAllCookiesAsync(filtered_callback);
monster->GetAllCookiesAsync(filtered_callback);
else
GetCookieStore(getter)->GetAllCookiesForURLAsync(GURL(url),
filtered_callback);
monster->GetAllCookiesForURLAsync(GURL(url), filtered_callback);
}
// Removes cookie with |url| and |name| in IO thread.
@@ -183,23 +155,14 @@ void OnSetCookie(const Cookies::SetCallback& callback, bool success) {
base::Bind(callback, success ? Cookies::SUCCESS : Cookies::FAILED));
}
// Flushes cookie store in IO thread.
void FlushCookieStoreOnIOThread(
scoped_refptr<net::URLRequestContextGetter> getter,
const base::Closure& callback) {
GetCookieStore(getter)->FlushStore(base::Bind(RunCallbackInUI, callback));
}
// Sets cookie with |details| in IO thread.
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
std::unique_ptr<base::DictionaryValue> details,
scoped_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);
@@ -208,13 +171,6 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
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) ?
@@ -222,37 +178,23 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
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);
}
GetCookieStore(getter)->SetCookieWithDetailsAsync(
GURL(url), name, value, domain, path, creation_time,
expiration_time, last_access_time, secure, http_only,
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT,
base::Bind(OnSetCookie, callback));
GetCookieStore(getter)->GetCookieMonster()->SetCookieWithDetailsAsync(
GURL(url), name, value, domain, path, expiration_time, secure, http_only,
false, net::COOKIE_PRIORITY_DEFAULT, base::Bind(OnSetCookie, callback));
}
} // namespace
Cookies::Cookies(v8::Isolate* isolate,
AtomBrowserContext* browser_context)
: request_context_getter_(browser_context->url_request_context_getter()),
cookie_delegate_(browser_context->cookie_delegate()) {
Init(isolate);
cookie_delegate_->AddObserver(this);
Cookies::Cookies(content::BrowserContext* browser_context)
: request_context_getter_(browser_context->GetRequestContext()) {
}
Cookies::~Cookies() {
cookie_delegate_->RemoveObserver(this);
}
void Cookies::Get(const base::DictionaryValue& filter,
const GetCallback& callback) {
std::unique_ptr<base::DictionaryValue> copied(filter.CreateDeepCopy());
scoped_ptr<base::DictionaryValue> copied(filter.CreateDeepCopy());
auto getter = make_scoped_refptr(request_context_getter_);
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -269,43 +211,27 @@ void Cookies::Remove(const GURL& url, const std::string& name,
void Cookies::Set(const base::DictionaryValue& details,
const SetCallback& callback) {
std::unique_ptr<base::DictionaryValue> copied(details.CreateDeepCopy());
scoped_ptr<base::DictionaryValue> copied(details.CreateDeepCopy());
auto getter = make_scoped_refptr(request_context_getter_);
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(SetCookieOnIO, getter, Passed(&copied), callback));
}
void Cookies::FlushStore(const base::Closure& callback) {
auto getter = make_scoped_refptr(request_context_getter_);
content::BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(FlushCookieStoreOnIOThread, getter, callback));
}
void Cookies::OnCookieChanged(const net::CanonicalCookie& cookie,
bool removed,
net::CookieStore::ChangeCause cause) {
Emit("changed", cookie, cause, removed);
}
// static
mate::Handle<Cookies> Cookies::Create(
v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Cookies(isolate, browser_context));
content::BrowserContext* browser_context) {
return mate::CreateHandle(isolate, new Cookies(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())
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("get", &Cookies::Get)
.SetMethod("remove", &Cookies::Remove)
.SetMethod("set", &Cookies::Set)
.SetMethod("flushStore", &Cookies::FlushStore);
.SetMethod("set", &Cookies::Set);
}
} // namespace api

View File

@@ -8,7 +8,6 @@
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/net/atom_cookie_delegate.h"
#include "base/callback.h"
#include "native_mate/handle.h"
#include "net/cookies/canonical_cookie.h"
@@ -17,18 +16,19 @@ namespace base {
class DictionaryValue;
}
namespace content {
class BrowserContext;
}
namespace net {
class URLRequestContextGetter;
}
namespace atom {
class AtomBrowserContext;
namespace api {
class Cookies : public mate::TrackableObject<Cookies>,
public AtomCookieDelegate::Observer {
class Cookies : public mate::TrackableObject<Cookies> {
public:
enum Error {
SUCCESS,
@@ -39,30 +39,23 @@ class Cookies : public mate::TrackableObject<Cookies>,
using SetCallback = base::Callback<void(Error)>;
static mate::Handle<Cookies> Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context);
content::BrowserContext* browser_context);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
protected:
Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~Cookies() override;
explicit Cookies(content::BrowserContext* browser_context);
~Cookies();
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);
// AtomCookieDelegate::Observer:
void OnCookieChanged(const net::CanonicalCookie& cookie,
bool removed,
net::CookieStore::ChangeCause cause) override;
private:
net::URLRequestContextGetter* request_context_getter_;
scoped_refptr<AtomCookieDelegate> cookie_delegate_;
DISALLOW_COPY_AND_ASSIGN(Cookies);
};

View File

@@ -9,24 +9,31 @@
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/web_contents.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "atom/common/node_includes.h"
using content::DevToolsAgentHost;
namespace atom {
namespace api {
Debugger::Debugger(v8::Isolate* isolate, content::WebContents* web_contents)
namespace {
// The wrapDebugger funtion which is implemented in JavaScript.
using WrapDebuggerCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapDebuggerCallback g_wrap_debugger;
} // namespace
Debugger::Debugger(content::WebContents* web_contents)
: web_contents_(web_contents),
previous_request_id_(0) {
Init(isolate);
}
Debugger::~Debugger() {
@@ -44,23 +51,12 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host,
const std::string& message) {
DCHECK(agent_host == agent_host_.get());
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::String> local_message =
v8::String::NewFromUtf8(isolate(), message.data());
v8::MaybeLocal<v8::Value> parsed_message = v8::JSON::Parse(
isolate()->GetCurrentContext(), local_message);
if (parsed_message.IsEmpty()) {
scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
if (!parsed_message->IsType(base::Value::TYPE_DICTIONARY))
return;
}
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
if (!mate::ConvertFromV8(isolate(), parsed_message.ToLocalChecked(),
dict.get())) {
return;
}
base::DictionaryValue* dict =
static_cast<base::DictionaryValue*>(parsed_message.get());
int id;
if (!dict->GetInteger("id", &id)) {
std::string method;
@@ -118,7 +114,7 @@ bool Debugger::IsAttached() {
void Debugger::Detach() {
if (!agent_host_.get())
return;
agent_host_->DetachClient(this);
agent_host_->DetachClient();
AgentHostClosed(agent_host_.get(), false);
agent_host_ = nullptr;
}
@@ -147,40 +143,51 @@ void Debugger::SendCommand(mate::Arguments* args) {
std::string json_args;
base::JSONWriter::Write(request, &json_args);
agent_host_->DispatchProtocolMessage(this, json_args);
agent_host_->DispatchProtocolMessage(json_args);
}
// static
mate::Handle<Debugger> Debugger::Create(
v8::Isolate* isolate,
content::WebContents* web_contents) {
return mate::CreateHandle(isolate, new Debugger(isolate, web_contents));
auto handle = mate::CreateHandle(isolate, new Debugger(web_contents));
g_wrap_debugger.Run(handle.ToV8());
return handle;
}
// static
void Debugger::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Debugger"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("attach", &Debugger::Attach)
.SetMethod("isAttached", &Debugger::IsAttached)
.SetMethod("detach", &Debugger::Detach)
.SetMethod("sendCommand", &Debugger::SendCommand);
}
void ClearWrapDebugger() {
g_wrap_debugger.Reset();
}
void SetWrapDebugger(const WrapDebuggerCallback& callback) {
g_wrap_debugger = callback;
// Cleanup the wrapper on exit.
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
base::Bind(ClearWrapDebugger));
}
} // namespace api
} // namespace atom
namespace {
using atom::api::Debugger;
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(isolate, exports)
.Set("Debugger", Debugger::GetConstructor(isolate)->GetFunction());
mate::Dictionary dict(isolate, exports);
dict.SetMethod("_setWrapDebugger", &atom::api::SetWrapDebugger);
}
} // namespace

View File

@@ -39,11 +39,11 @@ class Debugger: public mate::TrackableObject<Debugger>,
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
protected:
Debugger(v8::Isolate* isolate, content::WebContents* web_contents);
~Debugger() override;
explicit Debugger(content::WebContents* web_contents);
~Debugger();
// content::DevToolsAgentHostClient:
void AgentHostClosed(content::DevToolsAgentHost* agent_host,

View File

@@ -4,17 +4,15 @@
#include "atom/browser/api/atom_api_desktop_capturer.h"
using base::PlatformThreadRef;
#include "atom/common/api/atom_api_native_image.h"
#include "atom/common/node_includes.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/media/desktop_media_list.h"
#include "native_mate/dictionary.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
#include "atom/common/node_includes.h"
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
#include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
namespace mate {
@@ -39,8 +37,7 @@ namespace atom {
namespace api {
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
Init(isolate);
DesktopCapturer::DesktopCapturer() {
}
DesktopCapturer::~DesktopCapturer() {
@@ -62,14 +59,12 @@ void DesktopCapturer::StartHandling(bool capture_window,
options.set_disable_effects(false);
#endif
std::unique_ptr<webrtc::DesktopCapturer> screen_capturer(
capture_screen ? webrtc::DesktopCapturer::CreateScreenCapturer(options)
: nullptr);
std::unique_ptr<webrtc::DesktopCapturer> window_capturer(
capture_window ? webrtc::DesktopCapturer::CreateWindowCapturer(options)
: nullptr);
media_list_.reset(new NativeDesktopMediaList(
std::move(screen_capturer), std::move(window_capturer)));
scoped_ptr<webrtc::ScreenCapturer> screen_capturer(
capture_screen ? webrtc::ScreenCapturer::Create(options) : nullptr);
scoped_ptr<webrtc::WindowCapturer> window_capturer(
capture_window ? webrtc::WindowCapturer::Create(options) : nullptr);
media_list_.reset(new NativeDesktopMediaList(screen_capturer.Pass(),
window_capturer.Pass()));
media_list_->SetThumbnailSize(thumbnail_size);
media_list_->StartUpdating(this);
@@ -92,20 +87,19 @@ void DesktopCapturer::OnSourceThumbnailChanged(int index) {
bool DesktopCapturer::OnRefreshFinished() {
Emit("finished", media_list_->GetSources());
media_list_.reset();
return false;
}
mate::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
}
// static
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(mate::StringToV8(isolate, "DesktopCapturer"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
return mate::CreateHandle(isolate, new DesktopCapturer);
}
} // namespace api

View File

@@ -14,21 +14,18 @@ namespace atom {
namespace api {
class DesktopCapturer: public mate::EventEmitter<DesktopCapturer>,
class DesktopCapturer: public mate::EventEmitter,
public DesktopMediaListObserver {
public:
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);
protected:
explicit DesktopCapturer(v8::Isolate* isolate);
~DesktopCapturer() override;
DesktopCapturer();
~DesktopCapturer();
// DesktopMediaListObserver overrides.
void OnSourceAdded(int index) override;
@@ -39,7 +36,11 @@ class DesktopCapturer: public mate::EventEmitter<DesktopCapturer>,
bool OnRefreshFinished() override;
private:
std::unique_ptr<DesktopMediaList> media_list_;
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
scoped_ptr<DesktopMediaList> media_list_;
DISALLOW_COPY_AND_ASSIGN(DesktopCapturer);
};

View File

@@ -8,13 +8,11 @@
#include "atom/browser/api/atom_api_window.h"
#include "atom/browser/native_window.h"
#include "atom/browser/ui/certificate_trust.h"
#include "atom/browser/ui/file_dialog.h"
#include "atom/browser/ui/message_box.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
@@ -37,27 +35,6 @@ struct Converter<file_dialog::Filter> {
}
};
template<>
struct Converter<file_dialog::DialogSettings> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
file_dialog::DialogSettings* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
dict.Get("window", &(out->parent_window));
dict.Get("title", &(out->title));
dict.Get("message", &(out->message));
dict.Get("buttonLabel", &(out->button_label));
dict.Get("nameFieldLabel", &(out->name_field_label));
dict.Get("defaultPath", &(out->default_path));
dict.Get("filters", &(out->filters));
dict.Get("properties", &(out->properties));
dict.Get("showsTagField", &(out->shows_tag_field));
return true;
}
};
} // namespace mate
namespace {
@@ -70,8 +47,6 @@ void ShowMessageBox(int type,
const std::string& title,
const std::string& message,
const std::string& detail,
const std::string& checkbox_label,
bool checkbox_checked,
const gfx::ImageSkia& icon,
atom::NativeWindow* window,
mate::Arguments* args) {
@@ -80,44 +55,53 @@ void ShowMessageBox(int type,
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
peek,
&callback)) {
atom::ShowMessageBox(window, static_cast<atom::MessageBoxType>(type),
buttons, default_id, cancel_id, options, title,
message, detail, checkbox_label, checkbox_checked,
icon, callback);
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons,
default_id, cancel_id, options, title,
message, detail, icon, callback);
} else {
int chosen = atom::ShowMessageBox(
window, static_cast<atom::MessageBoxType>(type), buttons, default_id,
cancel_id, options, title, message, detail, icon);
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
buttons, default_id, cancel_id,
options, title, message, detail, icon);
args->Return(chosen);
}
}
void ShowOpenDialog(const file_dialog::DialogSettings& settings,
void ShowOpenDialog(const std::string& title,
const base::FilePath& default_path,
const file_dialog::Filters& filters,
int properties,
atom::NativeWindow* window,
mate::Arguments* args) {
v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::OpenDialogCallback callback;
if (mate::Converter<file_dialog::OpenDialogCallback>::FromV8(args->isolate(),
peek,
&callback)) {
file_dialog::ShowOpenDialog(settings, callback);
file_dialog::ShowOpenDialog(window, title, default_path, filters,
properties, callback);
} else {
std::vector<base::FilePath> paths;
if (file_dialog::ShowOpenDialog(settings, &paths))
if (file_dialog::ShowOpenDialog(window, title, default_path, filters,
properties, &paths))
args->Return(paths);
}
}
void ShowSaveDialog(const file_dialog::DialogSettings& settings,
void ShowSaveDialog(const std::string& title,
const base::FilePath& default_path,
const file_dialog::Filters& filters,
atom::NativeWindow* window,
mate::Arguments* args) {
v8::Local<v8::Value> peek = args->PeekNext();
file_dialog::SaveDialogCallback callback;
if (mate::Converter<file_dialog::SaveDialogCallback>::FromV8(args->isolate(),
peek,
&callback)) {
file_dialog::ShowSaveDialog(settings, callback);
file_dialog::ShowSaveDialog(window, title, default_path, filters, callback);
} else {
base::FilePath path;
if (file_dialog::ShowSaveDialog(settings, &path))
if (file_dialog::ShowSaveDialog(window, title, default_path, filters,
&path))
args->Return(path);
}
}
@@ -129,10 +113,6 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
#if defined(OS_MACOSX) || defined(OS_WIN)
dict.SetMethod("showCertificateTrustDialog",
&certificate_trust::ShowCertificateTrust);
#endif
}
} // namespace

View File

@@ -10,13 +10,13 @@
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/node_includes.h"
#include "base/memory/linked_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "native_mate/dictionary.h"
#include "net/base/filename_util.h"
#include "atom/common/node_includes.h"
namespace mate {
template<>
@@ -25,9 +25,6 @@ struct Converter<content::DownloadItem::DownloadState> {
content::DownloadItem::DownloadState state) {
std::string download_state;
switch (state) {
case content::DownloadItem::IN_PROGRESS:
download_state = "progressing";
break;
case content::DownloadItem::COMPLETE:
download_state = "completed";
break;
@@ -52,15 +49,17 @@ namespace api {
namespace {
std::map<uint32_t, v8::Global<v8::Object>> g_download_item_objects;
// The wrapDownloadItem funtion which is implemented in JavaScript
using WrapDownloadItemCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapDownloadItemCallback g_wrap_download_item;
std::map<uint32, linked_ptr<v8::Global<v8::Value>>> g_download_item_objects;
} // namespace
DownloadItem::DownloadItem(v8::Isolate* isolate,
content::DownloadItem* download_item)
DownloadItem::DownloadItem(content::DownloadItem* download_item)
: download_item_(download_item) {
download_item_->AddObserver(this);
Init(isolate);
AttachAsUserData(download_item);
}
@@ -72,17 +71,19 @@ DownloadItem::~DownloadItem() {
}
// Remove from the global map.
g_download_item_objects.erase(weak_map_id());
auto iter = g_download_item_objects.find(weak_map_id());
if (iter != g_download_item_objects.end())
g_download_item_objects.erase(iter);
}
void DownloadItem::OnDownloadUpdated(content::DownloadItem* item) {
if (download_item_->IsDone()) {
Emit("done", item->GetState());
// Destroy the item once item is downloaded.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, GetDestroyClosure());
base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure());
} else {
Emit("updated", item->GetState());
Emit("updated");
}
}
@@ -96,27 +97,20 @@ void DownloadItem::Pause() {
download_item_->Pause();
}
bool DownloadItem::IsPaused() const {
return download_item_->IsPaused();
}
void DownloadItem::Resume() {
download_item_->Resume();
}
bool DownloadItem::CanResume() const {
return download_item_->CanResume();
}
void DownloadItem::Cancel() {
download_item_->Cancel(true);
download_item_->Remove();
}
int64_t DownloadItem::GetReceivedBytes() const {
int64 DownloadItem::GetReceivedBytes() const {
return download_item_->GetReceivedBytes();
}
int64_t DownloadItem::GetTotalBytes() const {
int64 DownloadItem::GetTotalBytes() const {
return download_item_->GetTotalBytes();
}
@@ -134,7 +128,7 @@ std::string DownloadItem::GetFilename() const {
std::string(),
download_item_->GetSuggestedFilename(),
GetMimeType(),
"download").LossyDisplayName());
std::string()).LossyDisplayName());
}
std::string DownloadItem::GetContentDisposition() const {
@@ -145,18 +139,6 @@ const GURL& DownloadItem::GetURL() const {
return download_item_->GetURL();
}
const std::vector<GURL>& DownloadItem::GetURLChain() const {
return download_item_->GetUrlChain();
}
content::DownloadItem::DownloadState DownloadItem::GetState() const {
return download_item_->GetState();
}
bool DownloadItem::IsDone() const {
return download_item_->IsDone();
}
void DownloadItem::SetSavePath(const base::FilePath& path) {
save_path_ = path;
}
@@ -165,28 +147,13 @@ base::FilePath DownloadItem::GetSavePath() const {
return save_path_;
}
std::string DownloadItem::GetLastModifiedTime() const {
return download_item_->GetLastModifiedTime();
}
std::string DownloadItem::GetETag() const {
return download_item_->GetETag();
}
double DownloadItem::GetStartTime() const {
return download_item_->GetStartTime().ToDoubleT();
}
// static
void DownloadItem::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "DownloadItem"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.MakeDestroyable()
.SetMethod("pause", &DownloadItem::Pause)
.SetMethod("isPaused", &DownloadItem::IsPaused)
.SetMethod("resume", &DownloadItem::Resume)
.SetMethod("canResume", &DownloadItem::CanResume)
.SetMethod("cancel", &DownloadItem::Cancel)
.SetMethod("getReceivedBytes", &DownloadItem::GetReceivedBytes)
.SetMethod("getTotalBytes", &DownloadItem::GetTotalBytes)
@@ -195,14 +162,8 @@ void DownloadItem::BuildPrototype(v8::Isolate* isolate,
.SetMethod("getFilename", &DownloadItem::GetFilename)
.SetMethod("getContentDisposition", &DownloadItem::GetContentDisposition)
.SetMethod("getURL", &DownloadItem::GetURL)
.SetMethod("getURLChain", &DownloadItem::GetURLChain)
.SetMethod("getState", &DownloadItem::GetState)
.SetMethod("isDone", &DownloadItem::IsDone)
.SetMethod("setSavePath", &DownloadItem::SetSavePath)
.SetMethod("getSavePath", &DownloadItem::GetSavePath)
.SetMethod("getLastModifiedTime", &DownloadItem::GetLastModifiedTime)
.SetMethod("getETag", &DownloadItem::GetETag)
.SetMethod("getStartTime", &DownloadItem::GetStartTime);
.SetMethod("getSavePath", &DownloadItem::GetSavePath);
}
// static
@@ -212,14 +173,27 @@ mate::Handle<DownloadItem> DownloadItem::Create(
if (existing)
return mate::CreateHandle(isolate, static_cast<DownloadItem*>(existing));
auto handle = mate::CreateHandle(isolate, new DownloadItem(isolate, item));
auto handle = mate::CreateHandle(isolate, new DownloadItem(item));
g_wrap_download_item.Run(handle.ToV8());
// Reference this object in case it got garbage collected.
g_download_item_objects[handle->weak_map_id()] =
v8::Global<v8::Object>(isolate, handle.ToV8());
g_download_item_objects[handle->weak_map_id()] = make_linked_ptr(
new v8::Global<v8::Value>(isolate, handle.ToV8()));
return handle;
}
void ClearWrapDownloadItem() {
g_wrap_download_item.Reset();
}
void SetWrapDownloadItem(const WrapDownloadItemCallback& callback) {
g_wrap_download_item = callback;
// Cleanup the wrapper on exit.
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
base::Bind(ClearWrapDownloadItem));
}
} // namespace api
} // namespace atom
@@ -229,9 +203,8 @@ 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(isolate, exports)
.Set("DownloadItem",
atom::api::DownloadItem::GetConstructor(isolate)->GetFunction());
mate::Dictionary dict(isolate, exports);
dict.SetMethod("_setWrapDownloadItem", &atom::api::SetWrapDownloadItem);
}
} // namespace

View File

@@ -6,7 +6,6 @@
#define ATOM_BROWSER_API_ATOM_API_DOWNLOAD_ITEM_H_
#include <string>
#include <vector>
#include "atom/browser/api/trackable_object.h"
#include "base/files/file_path.h"
@@ -24,32 +23,25 @@ class DownloadItem : public mate::TrackableObject<DownloadItem>,
static mate::Handle<DownloadItem> Create(v8::Isolate* isolate,
content::DownloadItem* item);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
void Pause();
bool IsPaused() const;
void Resume();
bool CanResume() const;
void Cancel();
int64_t GetReceivedBytes() const;
int64_t GetTotalBytes() const;
int64 GetReceivedBytes() const;
int64 GetTotalBytes() const;
std::string GetMimeType() const;
bool HasUserGesture() const;
std::string GetFilename() const;
std::string GetContentDisposition() const;
const GURL& GetURL() const;
const std::vector<GURL>& GetURLChain() const;
content::DownloadItem::DownloadState GetState() const;
bool IsDone() const;
void SetSavePath(const base::FilePath& path);
base::FilePath GetSavePath() const;
std::string GetLastModifiedTime() const;
std::string GetETag() const;
double GetStartTime() const;
protected:
DownloadItem(v8::Isolate* isolate, content::DownloadItem* download_item);
explicit DownloadItem(content::DownloadItem* download_item);
~DownloadItem();
// Override content::DownloadItem::Observer methods

View File

@@ -19,8 +19,7 @@ namespace atom {
namespace api {
GlobalShortcut::GlobalShortcut(v8::Isolate* isolate) {
Init(isolate);
GlobalShortcut::GlobalShortcut() {
}
GlobalShortcut::~GlobalShortcut() {
@@ -67,22 +66,20 @@ void GlobalShortcut::UnregisterAll() {
GlobalShortcutListener::GetInstance()->UnregisterAccelerators(this);
}
// static
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new GlobalShortcut(isolate));
}
// static
void GlobalShortcut::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "GlobalShortcut"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
mate::ObjectTemplateBuilder GlobalShortcut::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("register", &GlobalShortcut::Register)
.SetMethod("isRegistered", &GlobalShortcut::IsRegistered)
.SetMethod("unregister", &GlobalShortcut::Unregister)
.SetMethod("unregisterAll", &GlobalShortcut::UnregisterAll);
}
// static
mate::Handle<GlobalShortcut> GlobalShortcut::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new GlobalShortcut);
}
} // namespace api
} // namespace atom

View File

@@ -23,13 +23,14 @@ class GlobalShortcut : public extensions::GlobalShortcutListener::Observer,
public:
static mate::Handle<GlobalShortcut> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit GlobalShortcut(v8::Isolate* isolate);
GlobalShortcut();
~GlobalShortcut() override;
// mate::Wrappable implementations:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
typedef std::map<ui::Accelerator, base::Closure> AcceleratorCallbackMap;

View File

@@ -19,17 +19,16 @@ namespace atom {
namespace api {
Menu::Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
Menu::Menu()
: model_(new AtomMenuModel(this)),
parent_(nullptr) {
InitWith(isolate, wrapper);
parent_(NULL) {
}
Menu::~Menu() {
}
void Menu::AfterInit(v8::Isolate* isolate) {
mate::Dictionary wrappable(isolate, GetWrapper());
mate::Dictionary wrappable(isolate, GetWrapper(isolate));
mate::Dictionary delegate;
if (!wrappable.Get("delegate", &delegate))
return;
@@ -54,21 +53,16 @@ bool Menu::IsCommandIdVisible(int command_id) const {
return is_visible_.Run(command_id);
}
bool Menu::GetAcceleratorForCommandIdWithParams(
int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const {
bool Menu::GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Value> val = get_accelerator_.Run(
command_id, use_default_accelerator);
v8::Local<v8::Value> val = get_accelerator_.Run(command_id);
return mate::ConvertFromV8(isolate(), val, accelerator);
}
void Menu::ExecuteCommand(int command_id, int flags) {
execute_command_.Run(
mate::internal::CreateEventFromFlags(isolate(), flags),
command_id);
void Menu::ExecuteCommand(int command_id, int event_flags) {
execute_command_.Run(command_id);
}
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
@@ -155,9 +149,8 @@ bool Menu::IsVisibleAt(int index) const {
// static
void Menu::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Menu"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.MakeDestroyable()
.SetMethod("insertItem", &Menu::InsertItemAt)
.SetMethod("insertCheckItem", &Menu::InsertCheckItemAt)
@@ -176,8 +169,7 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isItemCheckedAt", &Menu::IsItemCheckedAt)
.SetMethod("isEnabledAt", &Menu::IsEnabledAt)
.SetMethod("isVisibleAt", &Menu::IsVisibleAt)
.SetMethod("popupAt", &Menu::PopupAt)
.SetMethod("closePopupAt", &Menu::ClosePopupAt);
.SetMethod("popupAt", &Menu::PopupAt);
}
} // namespace api
@@ -187,15 +179,14 @@ void Menu::BuildPrototype(v8::Isolate* isolate,
namespace {
using atom::api::Menu;
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
using atom::api::Menu;
v8::Isolate* isolate = context->GetIsolate();
Menu::SetConstructor(isolate, base::Bind(&Menu::New));
v8::Local<v8::Function> constructor = mate::CreateConstructor<Menu>(
isolate, "Menu", base::Bind(&Menu::Create));
mate::Dictionary dict(isolate, exports);
dict.Set("Menu", Menu::GetConstructor(isolate)->GetFunction());
dict.Set("Menu", static_cast<v8::Local<v8::Value>>(constructor));
#if defined(OS_MACOSX)
dict.SetMethod("setApplicationMenu", &Menu::SetApplicationMenu);
dict.SetMethod("sendActionToFirstResponder",

View File

@@ -5,13 +5,13 @@
#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_window.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/ui/atom_menu_model.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
namespace atom {
@@ -20,10 +20,10 @@ namespace api {
class Menu : public mate::TrackableObject<Menu>,
public AtomMenuModel::Delegate {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static mate::Wrappable* Create();
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
#if defined(OS_MACOSX)
// Set the global menubar.
@@ -36,7 +36,7 @@ class Menu : public mate::TrackableObject<Menu>,
AtomMenuModel* model() const { return model_.get(); }
protected:
Menu(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
Menu();
~Menu() override;
// mate::Wrappable:
@@ -46,18 +46,16 @@ 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 GetAcceleratorForCommandIdWithParams(
int command_id,
bool use_default_accelerator,
ui::Accelerator* accelerator) const override;
bool GetAcceleratorForCommandId(int command_id,
ui::Accelerator* accelerator) override;
void ExecuteCommand(int command_id, int event_flags) override;
void MenuWillShow(ui::SimpleMenuModel* source) override;
virtual void PopupAt(
Window* window, int x, int y, int positioning_item, bool async) = 0;
virtual void ClosePopupAt(int32_t window_id) = 0;
virtual void PopupAt(Window* window,
int x = -1, int y = -1,
int positioning_item = 0) = 0;
std::unique_ptr<AtomMenuModel> model_;
scoped_ptr<AtomMenuModel> model_;
Menu* parent_;
private:
@@ -91,8 +89,8 @@ class Menu : public mate::TrackableObject<Menu>,
base::Callback<bool(int)> is_checked_;
base::Callback<bool(int)> is_enabled_;
base::Callback<bool(int)> is_visible_;
base::Callback<v8::Local<v8::Value>(int, bool)> get_accelerator_;
base::Callback<void(v8::Local<v8::Value>, int)> execute_command_;
base::Callback<v8::Local<v8::Value>(int)> get_accelerator_;
base::Callback<void(int)> execute_command_;
base::Callback<void()> menu_will_show_;
DISALLOW_COPY_AND_ASSIGN(Menu);

View File

@@ -7,40 +7,27 @@
#include "atom/browser/api/atom_api_menu.h"
#include <map>
#include <string>
#import "atom/browser/ui/cocoa/atom_menu_controller.h"
using base::scoped_nsobject;
namespace atom {
namespace api {
class MenuMac : public Menu {
protected:
MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
MenuMac();
void PopupAt(
Window* window, int x, int y, int positioning_item, bool async) override;
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
int32_t window_id, int x, int y, int positioning_item,
bool async);
void ClosePopupAt(int32_t window_id) override;
void PopupAt(Window* window, int x, int y, int positioning_item = 0) override;
base::scoped_nsobject<AtomMenuController> menu_controller_;
private:
friend class Menu;
static void SendActionToFirstResponder(const std::string& action);
scoped_nsobject<AtomMenuController> menu_controller_;
// window ID -> open context menu
std::map<int32_t, scoped_nsobject<AtomMenuController>> popup_controllers_;
base::WeakPtrFactory<MenuMac> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MenuMac);
};

View File

@@ -5,60 +5,31 @@
#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.h"
#include "base/strings/sys_string_conversions.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "atom/common/node_includes.h"
using content::BrowserThread;
namespace atom {
namespace api {
MenuMac::MenuMac(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: Menu(isolate, wrapper),
weak_factory_(this) {
MenuMac::MenuMac() {
}
void MenuMac::PopupAt(
Window* window, int x, int y, int positioning_item, bool async) {
void MenuMac::PopupAt(Window* window, int x, int y, int positioning_item) {
NativeWindow* native_window = window->window();
if (!native_window)
return;
auto popup = base::Bind(&MenuMac::PopupOnUI, weak_factory_.GetWeakPtr(),
native_window->GetWeakPtr(), window->ID(), x, y,
positioning_item, async);
if (async)
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, popup);
else
popup.Run();
}
void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
int32_t window_id, int x, int y, int positioning_item,
bool async) {
if (!native_window)
return;
brightray::InspectableWebContents* web_contents =
native_window->inspectable_web_contents();
content::WebContents* web_contents = native_window->web_contents();
if (!web_contents)
return;
auto close_callback = base::Bind(&MenuMac::ClosePopupAt,
weak_factory_.GetWeakPtr(), window_id);
popup_controllers_[window_id] = base::scoped_nsobject<AtomMenuController>(
[[AtomMenuController alloc] initWithModel:model()
useDefaultAccelerator:NO]);
NSMenu* menu = [popup_controllers_[window_id] menu];
NSView* view = web_contents->GetView()->GetNativeView();
base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:model_.get()]);
NSMenu* menu = [menu_controller menu];
NSView* view = web_contents->GetContentNativeView();
// Which menu item to show.
NSMenuItem* item = nil;
@@ -75,58 +46,15 @@ void MenuMac::PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
position = NSMakePoint(x, [view frame].size.height - y);
}
// If no preferred item is specified, try to show all of the menu items.
if (!positioning_item) {
CGFloat windowBottom = CGRectGetMinY([view window].frame);
CGFloat lowestMenuPoint = windowBottom + position.y - [menu size].height;
CGFloat screenBottom = CGRectGetMinY([view window].screen.frame);
CGFloat distanceFromBottom = lowestMenuPoint - screenBottom;
if (distanceFromBottom < 0)
position.y = position.y - distanceFromBottom + 4;
}
// Place the menu left of cursor if it is overflowing off right of screen.
CGFloat windowLeft = CGRectGetMinX([view window].frame);
CGFloat rightmostMenuPoint = windowLeft + position.x + [menu size].width;
CGFloat screenRight = CGRectGetMaxX([view window].screen.frame);
if (rightmostMenuPoint > screenRight)
position.x = position.x - [menu size].width;
if (async) {
[popup_controllers_[window_id] setCloseCallback:close_callback];
// Make sure events can be pumped while the menu is up.
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
// One of the events that could be pumped is |window.close()|.
// User-initiated event-tracking loops protect against this by
// setting flags in -[CrApplication sendEvent:], but since
// web-content menus are initiated by IPC message the setup has to
// be done manually.
base::mac::ScopedSendingEvent sendingEventScoper;
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
} else {
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
close_callback.Run();
}
}
void MenuMac::ClosePopupAt(int32_t window_id) {
popup_controllers_.erase(window_id);
// Show the menu.
[menu popUpMenuPositioningItem:item atLocation:position inView:view];
}
// static
void Menu::SetApplicationMenu(Menu* base_menu) {
MenuMac* menu = static_cast<MenuMac*>(base_menu);
base::scoped_nsobject<AtomMenuController> menu_controller(
[[AtomMenuController alloc] initWithModel:menu->model_.get()
useDefaultAccelerator:YES]);
[[AtomMenuController alloc] initWithModel:menu->model_.get()]);
[NSApp setMainMenu:[menu_controller menu]];
// Ensure the menu_controller_ is destroyed after main menu is set.
@@ -140,8 +68,8 @@ void Menu::SendActionToFirstResponder(const std::string& action) {
}
// static
mate::WrappableBase* Menu::New(mate::Arguments* args) {
return new MenuMac(args->isolate(), args->GetThis());
mate::Wrappable* Menu::Create() {
return new MenuMac();
}
} // namespace api

View File

@@ -5,23 +5,18 @@
#include "atom/browser/api/atom_api_menu_views.h"
#include "atom/browser/native_window_views.h"
#include "atom/browser/unresponsive_suppressor.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/display/screen.h"
using views::MenuRunner;
#include "ui/gfx/screen.h"
#include "ui/views/controls/menu/menu_runner.h"
namespace atom {
namespace api {
MenuViews::MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper)
: Menu(isolate, wrapper),
weak_factory_(this) {
MenuViews::MenuViews() {
}
void MenuViews::PopupAt(
Window* window, int x, int y, int positioning_item, bool async) {
void MenuViews::PopupAt(Window* window, int x, int y, int positioning_item) {
NativeWindow* native_window = static_cast<NativeWindow*>(window->window());
if (!native_window)
return;
@@ -35,26 +30,17 @@ void MenuViews::PopupAt(
// (-1, -1) means showing on mouse location.
gfx::Point location;
if (x == -1 || y == -1) {
location = display::Screen::GetScreen()->GetCursorScreenPoint();
location = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint();
} else {
gfx::Point origin = view->GetViewBounds().origin();
location = gfx::Point(origin.x() + x, origin.y() + y);
}
int flags = MenuRunner::CONTEXT_MENU | MenuRunner::HAS_MNEMONICS;
if (async)
flags |= MenuRunner::ASYNC;
// Don't emit unresponsive event when showing menu.
atom::UnresponsiveSuppressor suppressor;
// Show the menu.
int32_t window_id = window->ID();
auto close_callback = base::Bind(
&MenuViews::ClosePopupAt, weak_factory_.GetWeakPtr(), window_id);
menu_runners_[window_id] = std::unique_ptr<MenuRunner>(new MenuRunner(
model(), flags, close_callback));
ignore_result(menu_runners_[window_id]->RunMenuAt(
views::MenuRunner menu_runner(
model(),
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
ignore_result(menu_runner.RunMenuAt(
static_cast<NativeWindowViews*>(window->window())->widget(),
NULL,
gfx::Rect(location, gfx::Size()),
@@ -62,13 +48,9 @@ void MenuViews::PopupAt(
ui::MENU_SOURCE_MOUSE));
}
void MenuViews::ClosePopupAt(int32_t window_id) {
menu_runners_.erase(window_id);
}
// static
mate::WrappableBase* Menu::New(mate::Arguments* args) {
return new MenuViews(args->isolate(), args->GetThis());
mate::Wrappable* Menu::Create() {
return new MenuViews();
}
} // namespace api

View File

@@ -5,12 +5,8 @@
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
#define ATOM_BROWSER_API_ATOM_API_MENU_VIEWS_H_
#include <map>
#include "atom/browser/api/atom_api_menu.h"
#include "base/memory/weak_ptr.h"
#include "ui/display/screen.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/gfx/screen.h"
namespace atom {
@@ -18,19 +14,12 @@ namespace api {
class MenuViews : public Menu {
public:
MenuViews(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
MenuViews();
protected:
void PopupAt(
Window* window, int x, int y, int positioning_item, bool async) override;
void ClosePopupAt(int32_t window_id) override;
void PopupAt(Window* window, int x, int y, int positioning_item = 0) override;
private:
// window ID -> open context menu
std::map<int32_t, std::unique_ptr<views::MenuRunner>> menu_runners_;
base::WeakPtrFactory<MenuViews> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MenuViews);
};

View File

@@ -1,61 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_net.h"
#include "atom/browser/api/atom_api_url_request.h"
#include "atom/common/node_includes.h"
#include "native_mate/dictionary.h"
namespace atom {
namespace api {
Net::Net(v8::Isolate* isolate) {
Init(isolate);
}
Net::~Net() {}
// static
v8::Local<v8::Value> Net::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new Net(isolate)).ToV8();
}
// static
void Net::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Net"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetProperty("URLRequest", &Net::URLRequest);
}
v8::Local<v8::Value> Net::URLRequest(v8::Isolate* isolate) {
return URLRequest::GetConstructor(isolate)->GetFunction();
}
} // namespace api
} // namespace atom
namespace {
using atom::api::Net;
using atom::api::URLRequest;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
URLRequest::SetConstructor(isolate, base::Bind(URLRequest::New));
mate::Dictionary dict(isolate, exports);
dict.Set("net", Net::Create(isolate));
dict.Set("Net", Net::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_net, Initialize)

View File

@@ -1,35 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_NET_H_
#define ATOM_BROWSER_API_ATOM_API_NET_H_
#include "atom/browser/api/event_emitter.h"
namespace atom {
namespace api {
class Net : public mate::EventEmitter<Net> {
public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
v8::Local<v8::Value> URLRequest(v8::Isolate* isolate);
protected:
explicit Net(v8::Isolate* isolate);
~Net() override;
private:
DISALLOW_COPY_AND_ASSIGN(Net);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_NET_H_

View File

@@ -1,249 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_notification.h"
#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/browser.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/node_includes.h"
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/browser_client.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "url/gurl.h"
namespace mate {
template<>
struct Converter<brightray::NotificationAction> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
brightray::NotificationAction* out) {
mate::Dictionary dict;
if (!ConvertFromV8(isolate, val, &dict))
return false;
if (!dict.Get("type", &(out->type))) {
return false;
}
dict.Get("text", &(out->text));
return true;
}
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
brightray::NotificationAction val) {
mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate);
dict.Set("text", val.text);
dict.Set("type", val.type);
return dict.GetHandle();
}
};
} // namespace mate
namespace atom {
namespace api {
Notification::Notification(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
mate::Arguments* args) {
InitWith(isolate, wrapper);
presenter_ = brightray::BrowserClient::Get()->GetNotificationPresenter();
mate::Dictionary opts;
if (args->GetNext(&opts)) {
opts.Get("title", &title_);
opts.Get("subtitle", &subtitle_);
opts.Get("body", &body_);
has_icon_ = opts.Get("icon", &icon_);
if (has_icon_) {
opts.Get("icon", &icon_path_);
}
opts.Get("silent", &silent_);
opts.Get("replyPlaceholder", &reply_placeholder_);
opts.Get("hasReply", &has_reply_);
opts.Get("actions", &actions_);
opts.Get("sound", &sound_);
}
}
Notification::~Notification() {
if (notification_)
notification_->set_delegate(nullptr);
}
// static
mate::WrappableBase* Notification::New(mate::Arguments* args) {
if (!Browser::Get()->is_ready()) {
args->ThrowError("Cannot create Notification before app is ready");
return nullptr;
}
return new Notification(args->isolate(), args->GetThis(), args);
}
// Getters
base::string16 Notification::GetTitle() const {
return title_;
}
base::string16 Notification::GetSubtitle() const {
return subtitle_;
}
base::string16 Notification::GetBody() const {
return body_;
}
bool Notification::GetSilent() const {
return silent_;
}
base::string16 Notification::GetReplyPlaceholder() const {
return reply_placeholder_;
}
bool Notification::GetHasReply() const {
return has_reply_;
}
std::vector<brightray::NotificationAction> Notification::GetActions() const {
return actions_;
}
base::string16 Notification::GetSound() const {
return sound_;
}
// Setters
void Notification::SetTitle(const base::string16& new_title) {
title_ = new_title;
}
void Notification::SetSubtitle(const base::string16& new_subtitle) {
subtitle_ = new_subtitle;
}
void Notification::SetBody(const base::string16& new_body) {
body_ = new_body;
}
void Notification::SetSilent(bool new_silent) {
silent_ = new_silent;
}
void Notification::SetReplyPlaceholder(const base::string16& new_placeholder) {
reply_placeholder_ = new_placeholder;
}
void Notification::SetHasReply(bool new_has_reply) {
has_reply_ = new_has_reply;
}
void Notification::SetActions(
const std::vector<brightray::NotificationAction>& actions) {
actions_ = actions;
}
void Notification::SetSound(const base::string16& new_sound) {
sound_ = new_sound;
}
void Notification::NotificationAction(int index) {
Emit("action", index);
}
void Notification::NotificationClick() {
Emit("click");
}
void Notification::NotificationReplied(const std::string& reply) {
Emit("reply", reply);
}
void Notification::NotificationDisplayed() {
Emit("show");
}
void Notification::NotificationDestroyed() {
Emit("close");
}
void Notification::NotificationClosed() {
}
// Showing notifications
void Notification::Show() {
if (presenter_) {
notification_ = presenter_->CreateNotification(this);
if (notification_) {
brightray::NotificationOptions options;
options.title = title_;
options.subtitle = subtitle_;
options.msg = body_;
options.icon_url = GURL();
options.icon = icon_.AsBitmap();
options.silent = silent_;
options.has_reply = has_reply_;
options.reply_placeholder = reply_placeholder_;
options.actions = actions_;
options.sound = sound_;
notification_->Show(options);
}
}
}
bool Notification::IsSupported() {
return !!brightray::BrowserClient::Get()->GetNotificationPresenter();
}
// static
void Notification::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Notification"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.MakeDestroyable()
.SetMethod("show", &Notification::Show)
.SetProperty("title", &Notification::GetTitle, &Notification::SetTitle)
.SetProperty("subtitle", &Notification::GetSubtitle,
&Notification::SetSubtitle)
.SetProperty("body", &Notification::GetBody, &Notification::SetBody)
.SetProperty("silent", &Notification::GetSilent, &Notification::SetSilent)
.SetProperty("replyPlaceholder", &Notification::GetReplyPlaceholder,
&Notification::SetReplyPlaceholder)
.SetProperty("hasReply", &Notification::GetHasReply,
&Notification::SetHasReply)
.SetProperty("actions", &Notification::GetActions,
&Notification::SetActions)
.SetProperty("sound", &Notification::GetSound,
&Notification::SetSound);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::Notification;
void Initialize(v8::Local<v8::Object> exports,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv) {
v8::Isolate* isolate = context->GetIsolate();
Notification::SetConstructor(isolate, base::Bind(&Notification::New));
mate::Dictionary dict(isolate, exports);
dict.Set("Notification",
Notification::GetConstructor(isolate)->GetFunction());
dict.SetMethod("isSupported", &Notification::IsSupported);
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_notification, Initialize)

View File

@@ -1,93 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_
#define ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_
#include <memory>
#include <string>
#include <vector>
#include "atom/browser/api/trackable_object.h"
#include "base/strings/utf_string_conversions.h"
#include "brightray/browser/notification.h"
#include "brightray/browser/notification_delegate.h"
#include "brightray/browser/notification_presenter.h"
#include "native_mate/handle.h"
#include "ui/gfx/image/image.h"
namespace atom {
namespace api {
class Notification : public mate::TrackableObject<Notification>,
public brightray::NotificationDelegate {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static bool IsSupported();
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// NotificationDelegate:
void NotificationAction(int index) override;
void NotificationClick() override;
void NotificationReplied(const std::string& reply) override;
void NotificationDisplayed() override;
void NotificationDestroyed() override;
void NotificationClosed() override;
protected:
Notification(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
mate::Arguments* args);
~Notification() override;
void Show();
// Prop Getters
base::string16 GetTitle() const;
base::string16 GetSubtitle() const;
base::string16 GetBody() const;
bool GetSilent() const;
base::string16 GetReplyPlaceholder() const;
bool GetHasReply() const;
std::vector<brightray::NotificationAction> GetActions() const;
base::string16 GetSound() const;
// Prop Setters
void SetTitle(const base::string16& new_title);
void SetSubtitle(const base::string16& new_subtitle);
void SetBody(const base::string16& new_body);
void SetSilent(bool new_silent);
void SetReplyPlaceholder(const base::string16& new_reply_placeholder);
void SetHasReply(bool new_has_reply);
void SetActions(const std::vector<brightray::NotificationAction>& actions);
void SetSound(const base::string16& sound);
private:
base::string16 title_;
base::string16 subtitle_;
base::string16 body_;
gfx::Image icon_;
base::string16 icon_path_;
bool has_icon_ = false;
bool silent_ = false;
base::string16 reply_placeholder_;
bool has_reply_ = false;
std::vector<brightray::NotificationAction> actions_;
base::string16 sound_;
brightray::NotificationPresenter* presenter_;
base::WeakPtr<brightray::Notification> notification_;
DISALLOW_COPY_AND_ASSIGN(Notification);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_NOTIFICATION_H_

View File

@@ -5,19 +5,17 @@
#include "atom/browser/api/atom_api_power_monitor.h"
#include "atom/browser/browser.h"
#include "atom/common/node_includes.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_device_source.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
namespace atom {
namespace api {
PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
PowerMonitor::PowerMonitor() {
base::PowerMonitor::Get()->AddObserver(this);
Init(isolate);
}
PowerMonitor::~PowerMonitor() {
@@ -44,17 +42,11 @@ v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate,
"Cannot require \"powerMonitor\" module before app is ready")));
"Cannot initialize \"power-monitor\" module before app is ready")));
return v8::Null(isolate);
}
return mate::CreateHandle(isolate, new PowerMonitor(isolate)).ToV8();
}
// static
void PowerMonitor::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "PowerMonitor"));
return CreateHandle(isolate, new PowerMonitor).ToV8();
}
} // namespace api
@@ -64,19 +56,16 @@ void PowerMonitor::BuildPrototype(
namespace {
using atom::api::PowerMonitor;
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
#if defined(OS_MACOSX)
base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
#endif
using atom::api::PowerMonitor;
v8::Isolate* isolate = context->GetIsolate();
mate::Dictionary dict(isolate, exports);
dict.Set("powerMonitor", PowerMonitor::Create(isolate));
dict.Set("PowerMonitor",
PowerMonitor::GetConstructor(isolate)->GetFunction());
}
} // namespace

View File

@@ -19,11 +19,8 @@ class PowerMonitor : public mate::TrackableObject<PowerMonitor>,
public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
explicit PowerMonitor(v8::Isolate* isolate);
PowerMonitor();
~PowerMonitor() override;
// base::PowerObserver implementations:

View File

@@ -6,21 +6,18 @@
#include <string>
#include "content/public/browser/browser_thread.h"
#include "native_mate/dictionary.h"
#include "atom/common/node_includes.h"
using content::BrowserThread;
#include "content/public/browser/power_save_blocker.h"
#include "native_mate/dictionary.h"
namespace mate {
template<>
struct Converter<device::PowerSaveBlocker::PowerSaveBlockerType> {
struct Converter<content::PowerSaveBlocker::PowerSaveBlockerType> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
device::PowerSaveBlocker::PowerSaveBlockerType* out) {
using device::PowerSaveBlocker;
content::PowerSaveBlocker::PowerSaveBlockerType* out) {
using content::PowerSaveBlocker;
std::string type;
if (!ConvertFromV8(isolate, val, &type))
return false;
@@ -40,10 +37,9 @@ namespace atom {
namespace api {
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
PowerSaveBlocker::PowerSaveBlocker()
: current_blocker_type_(
device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
Init(isolate);
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
}
PowerSaveBlocker::~PowerSaveBlocker() {
@@ -61,32 +57,30 @@ void PowerSaveBlocker::UpdatePowerSaveBlocker() {
// higher precedence level than |kPowerSaveBlockPreventAppSuspension|.
//
// Only the highest-precedence blocker type takes effect.
device::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
content::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
for (const auto& element : power_save_blocker_types_) {
if (element.second ==
device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
new_blocker_type =
device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
break;
}
}
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
std::unique_ptr<device::PowerSaveBlocker> new_blocker(
new device::PowerSaveBlocker(
scoped_ptr<content::PowerSaveBlocker> new_blocker =
content::PowerSaveBlocker::Create(
new_blocker_type,
device::PowerSaveBlocker::kReasonOther,
ATOM_PRODUCT_NAME,
BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)));
content::PowerSaveBlocker::kReasonOther,
ATOM_PRODUCT_NAME);
power_save_blocker_.swap(new_blocker);
current_blocker_type_ = new_blocker_type;
}
}
int PowerSaveBlocker::Start(
device::PowerSaveBlocker::PowerSaveBlockerType type) {
content::PowerSaveBlocker::PowerSaveBlockerType type) {
static int count = 0;
power_save_blocker_types_[count] = type;
UpdatePowerSaveBlocker();
@@ -103,21 +97,19 @@ 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())
mate::ObjectTemplateBuilder PowerSaveBlocker::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("start", &PowerSaveBlocker::Start)
.SetMethod("stop", &PowerSaveBlocker::Stop)
.SetMethod("isStarted", &PowerSaveBlocker::IsStarted);
}
// static
mate::Handle<PowerSaveBlocker> PowerSaveBlocker::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new PowerSaveBlocker);
}
} // namespace api
} // namespace atom

View File

@@ -6,10 +6,10 @@
#define ATOM_BROWSER_API_ATOM_API_POWER_SAVE_BLOCKER_H_
#include <map>
#include <memory>
#include "atom/browser/api/trackable_object.h"
#include "device/power_save_blocker/power_save_blocker.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/power_save_blocker.h"
#include "native_mate/handle.h"
namespace mate {
@@ -24,27 +24,28 @@ 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();
~PowerSaveBlocker() override;
// mate::Wrappable implementations:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
void UpdatePowerSaveBlocker();
int Start(device::PowerSaveBlocker::PowerSaveBlockerType type);
int Start(content::PowerSaveBlocker::PowerSaveBlockerType type);
bool Stop(int id);
bool IsStarted(int id);
std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_;
scoped_ptr<content::PowerSaveBlocker> power_save_blocker_;
// Currnet blocker type used by |power_save_blocker_|
device::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_;
content::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_;
// Map from id to the corresponding blocker type for each request.
using PowerSaveBlockerTypeMap =
std::map<int, device::PowerSaveBlocker::PowerSaveBlockerType>;
std::map<int, content::PowerSaveBlocker::PowerSaveBlockerType>;
PowerSaveBlockerTypeMap power_save_blocker_types_;
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);

View File

@@ -5,21 +5,16 @@
#include "atom/browser/api/atom_api_protocol.h"
#include "atom/browser/atom_browser_client.h"
#include "atom/browser/atom_browser_context.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_string_job.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/native_mate_converters/net_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;
@@ -27,177 +22,16 @@ namespace atom {
namespace api {
namespace {
// List of registered custom standard schemes.
std::vector<std::string> g_standard_schemes;
// Clear protocol handlers in IO thread.
void ClearJobFactoryInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter) {
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
job_factory->Clear();
}
} // 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_WITHOUT_PORT);
if (secure) {
url::AddSecureScheme(scheme.c_str());
}
policy->RegisterWebSafeScheme(scheme);
}
// Add the schemes to command line switches, so child processes can also
// register them.
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
atom::switches::kStandardSchemes, base::JoinString(schemes, ","));
if (secure) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
atom::switches::kSecureSchemes, base::JoinString(schemes, ","));
}
}
Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context)
Protocol::Protocol(AtomBrowserContext* browser_context)
: request_context_getter_(browser_context->GetRequestContext()),
weak_factory_(this) {
Init(isolate);
job_factory_(browser_context->job_factory()) {
CHECK(job_factory_);
}
Protocol::~Protocol() {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(ClearJobFactoryInIO, request_context_getter_));
}
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);
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::UnregisterProtocolInIO,
request_context_getter_, scheme),
base::Bind(&Protocol::OnIOCompleted,
GetWeakPtr(), callback));
}
// static
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
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) {
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::IsProtocolHandledInIO,
request_context_getter_, scheme),
callback);
}
// static
bool Protocol::IsProtocolHandledInIO(
scoped_refptr<brightray::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);
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::UninterceptProtocolInIO,
request_context_getter_, scheme),
base::Bind(&Protocol::OnIOCompleted,
GetWeakPtr(), callback));
}
// static
Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme) {
return static_cast<AtomURLRequestJobFactory*>(
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";
}
}
AtomURLRequestJobFactory* Protocol::GetJobFactoryInIO() const {
request_context_getter_->GetURLRequestContext(); // Force init.
return static_cast<AtomURLRequestJobFactory*>(
static_cast<brightray::URLRequestContextGetter*>(
request_context_getter_.get())->job_factory());
}
// 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())
mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
.SetMethod("registerServiceWorkerSchemes",
&Protocol::RegisterServiceWorkerSchemes)
.SetMethod("registerStringProtocol",
@@ -221,29 +55,117 @@ void Protocol::BuildPrototype(
.SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol);
}
void Protocol::RegisterStandardSchemes(
const std::vector<std::string>& schemes) {
atom::AtomBrowserClient::SetCustomSchemes(schemes);
}
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);
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::UnregisterProtocolInIO,
base::Unretained(this), scheme),
base::Bind(&Protocol::OnIOCompleted,
base::Unretained(this), callback));
}
Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
const std::string& scheme) {
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) {
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::IsProtocolHandledInIO,
base::Unretained(this), scheme),
callback);
}
bool Protocol::IsProtocolHandledInIO(const std::string& scheme) {
return job_factory_->IsHandledProtocol(scheme);
}
void Protocol::UninterceptProtocol(
const std::string& scheme, mate::Arguments* args) {
CompletionCallback callback;
args->GetNext(&callback);
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::UninterceptProtocolInIO,
base::Unretained(this), scheme),
base::Bind(&Protocol::OnIOCompleted,
base::Unretained(this), callback));
}
Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
const std::string& scheme) {
if (!original_protocols_.contains(scheme))
return PROTOCOL_NOT_INTERCEPTED;
job_factory_->ReplaceProtocol(scheme,
original_protocols_.take_and_erase(scheme));
return PROTOCOL_OK;
}
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 registred";
case PROTOCOL_NOT_REGISTERED: return "The scheme has not been registred";
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(browser_context));
}
} // 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);
auto browser_context = static_cast<atom::AtomBrowserContext*>(
atom::AtomBrowserMainParts::Get()->browser_context());
dict.Set("protocol", atom::api::Protocol::Create(isolate, browser_context));
}
} // namespace

View File

@@ -5,49 +5,47 @@
#ifndef ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_
#define ATOM_BROWSER_API_ATOM_API_PROTOCOL_H_
#include <map>
#include <string>
#include <map>
#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 "base/containers/scoped_ptr_hash_map.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"
#include "native_mate/wrappable.h"
namespace base {
class DictionaryValue;
namespace net {
class URLRequest;
class URLRequestContextGetter;
}
namespace atom {
class AtomBrowserContext;
class AtomURLRequestJobFactory;
namespace api {
std::vector<std::string> GetStandardSchemes();
void RegisterStandardSchemes(const std::vector<std::string>& schemes,
mate::Arguments* args);
class Protocol : public mate::TrackableObject<Protocol> {
class Protocol : public mate::Wrappable {
public:
using Handler =
base::Callback<void(const base::DictionaryValue&, v8::Local<v8::Value>)>;
base::Callback<void(const net::URLRequest*, 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();
explicit Protocol(AtomBrowserContext* browser_context);
// mate::Wrappable implementations:
virtual mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate);
private:
// Possible errors.
@@ -79,18 +77,21 @@ class Protocol : public mate::TrackableObject<Protocol> {
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override {
RequestJob* request_job = new RequestJob(request, network_delegate);
request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_);
request_job->SetHandlerInfo(isolate_, request_context_, handler_);
return request_job;
}
private:
v8::Isolate* isolate_;
scoped_refptr<net::URLRequestContextGetter> request_context_;
net::URLRequestContextGetter* request_context_;
Protocol::Handler handler_;
DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler);
};
// Register schemes to standard scheme list.
void RegisterStandardSchemes(const std::vector<std::string>& schemes);
// Register schemes that can handle service worker.
void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
@@ -104,24 +105,19 @@ class Protocol : public mate::TrackableObject<Protocol> {
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::RegisterProtocolInIO<RequestJob>,
request_context_getter_, isolate(), scheme, handler),
base::Unretained(this), scheme, handler),
base::Bind(&Protocol::OnIOCompleted,
GetWeakPtr(), callback));
base::Unretained(this), callback));
}
template<typename RequestJob>
static ProtocolError RegisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
v8::Isolate* isolate,
const std::string& scheme,
const Handler& handler) {
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
if (job_factory->IsHandledProtocol(scheme))
ProtocolError RegisterProtocolInIO(const std::string& scheme,
const Handler& handler) {
if (job_factory_->IsHandledProtocol(scheme))
return PROTOCOL_REGISTERED;
std::unique_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
scoped_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
new CustomProtocolHandler<RequestJob>(
isolate, request_context_getter.get(), handler));
if (job_factory->SetProtocolHandler(scheme, std::move(protocol_handler)))
isolate(), request_context_getter_, handler));
if (job_factory_->SetProtocolHandler(scheme, protocol_handler.Pass()))
return PROTOCOL_OK;
else
return PROTOCOL_FAIL;
@@ -129,16 +125,12 @@ class Protocol : public mate::TrackableObject<Protocol> {
// Unregister the protocol handler that handles |scheme|.
void UnregisterProtocol(const std::string& scheme, mate::Arguments* args);
static ProtocolError UnregisterProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme);
ProtocolError UnregisterProtocolInIO(const std::string& scheme);
// Whether the protocol has handler registered.
void IsProtocolHandled(const std::string& scheme,
const BooleanCallback& callback);
static bool IsProtocolHandledInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme);
bool IsProtocolHandledInIO(const std::string& scheme);
// Replace the protocol handler with a new one.
template<typename RequestJob>
@@ -150,36 +142,32 @@ class Protocol : public mate::TrackableObject<Protocol> {
content::BrowserThread::PostTaskAndReplyWithResult(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&Protocol::InterceptProtocolInIO<RequestJob>,
request_context_getter_, isolate(), scheme, handler),
base::Unretained(this), scheme, handler),
base::Bind(&Protocol::OnIOCompleted,
GetWeakPtr(), callback));
base::Unretained(this), callback));
}
template<typename RequestJob>
static ProtocolError InterceptProtocolInIO(
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
v8::Isolate* isolate,
const std::string& scheme,
const Handler& handler) {
auto job_factory = static_cast<AtomURLRequestJobFactory*>(
request_context_getter->job_factory());
if (!job_factory->IsHandledProtocol(scheme))
ProtocolError InterceptProtocolInIO(const std::string& scheme,
const Handler& handler) {
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))
if (!job_factory_->HasProtocolHandler(scheme))
return PROTOCOL_FAIL;
std::unique_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
new CustomProtocolHandler<RequestJob>(
isolate, request_context_getter.get(), handler));
if (!job_factory->InterceptProtocol(scheme, std::move(protocol_handler)))
if (ContainsKey(original_protocols_, scheme))
return PROTOCOL_INTERCEPTED;
scoped_ptr<CustomProtocolHandler<RequestJob>> protocol_handler(
new CustomProtocolHandler<RequestJob>(
isolate(), request_context_getter_, handler));
original_protocols_.set(
scheme,
job_factory_->ReplaceProtocol(scheme, protocol_handler.Pass()));
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<brightray::URLRequestContextGetter> request_context_getter,
const std::string& scheme);
ProtocolError UninterceptProtocolInIO(const std::string& scheme);
// Convert error code to JS exception and call the callback.
void OnIOCompleted(const CompletionCallback& callback, ProtocolError error);
@@ -187,14 +175,15 @@ class Protocol : public mate::TrackableObject<Protocol> {
// Convert error code to string.
std::string ErrorCodeToString(ProtocolError error);
AtomURLRequestJobFactory* GetJobFactoryInIO() const;
net::URLRequestContextGetter* request_context_getter_;
base::WeakPtr<Protocol> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// Map that stores the original protocols of schemes.
using OriginalProtocolsMap = base::ScopedPtrHashMap<
std::string,
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>>;
OriginalProtocolsMap original_protocols_;
scoped_refptr<brightray::URLRequestContextGetter> request_context_getter_;
base::WeakPtrFactory<Protocol> weak_factory_;
AtomURLRequestJobFactory* job_factory_; // weak ref
DISALLOW_COPY_AND_ASSIGN(Protocol);
};

View File

@@ -1,90 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_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_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_render_process_preferences,
Initialize)

View File

@@ -1,44 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_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_

View File

@@ -12,9 +12,7 @@
#include "base/bind.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"
#include "ui/gfx/screen.h"
#include "atom/common/node_includes.h"
@@ -36,23 +34,22 @@ typename T::iterator FindById(T* container, int id) {
// Convert the changed_metrics bitmask to string array.
std::vector<std::string> MetricsToArray(uint32_t metrics) {
std::vector<std::string> array;
if (metrics & display::DisplayObserver::DISPLAY_METRIC_BOUNDS)
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS)
array.push_back("bounds");
if (metrics & display::DisplayObserver::DISPLAY_METRIC_WORK_AREA)
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA)
array.push_back("workArea");
if (metrics & display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR)
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR)
array.push_back("scaleFactor");
if (metrics & display::DisplayObserver::DISPLAY_METRIC_ROTATION)
if (metrics & gfx::DisplayObserver::DISPLAY_METRIC_ROTATION)
array.push_back("rotation");
return array;
}
} // namespace
Screen::Screen(v8::Isolate* isolate, display::Screen* screen)
: screen_(screen) {
Screen::Screen(gfx::Screen* screen) : screen_(screen) {
displays_ = screen_->GetAllDisplays();
screen_->AddObserver(this);
Init(isolate);
}
Screen::~Screen() {
@@ -63,67 +60,73 @@ gfx::Point Screen::GetCursorScreenPoint() {
return screen_->GetCursorScreenPoint();
}
display::Display Screen::GetPrimaryDisplay() {
gfx::Display Screen::GetPrimaryDisplay() {
return screen_->GetPrimaryDisplay();
}
std::vector<display::Display> Screen::GetAllDisplays() {
return screen_->GetAllDisplays();
std::vector<gfx::Display> Screen::GetAllDisplays() {
return displays_;
}
display::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) {
gfx::Display Screen::GetDisplayNearestPoint(const gfx::Point& point) {
return screen_->GetDisplayNearestPoint(point);
}
display::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
gfx::Display Screen::GetDisplayMatching(const gfx::Rect& match_rect) {
return screen_->GetDisplayMatching(match_rect);
}
void Screen::OnDisplayAdded(const display::Display& new_display) {
void Screen::OnDisplayAdded(const gfx::Display& new_display) {
displays_.push_back(new_display);
Emit("display-added", new_display);
}
void Screen::OnDisplayRemoved(const display::Display& old_display) {
void Screen::OnDisplayRemoved(const gfx::Display& old_display) {
auto iter = FindById(&displays_, old_display.id());
if (iter == displays_.end())
return;
displays_.erase(iter);
Emit("display-removed", old_display);
}
void Screen::OnDisplayMetricsChanged(const display::Display& display,
void Screen::OnDisplayMetricsChanged(const gfx::Display& display,
uint32_t changed_metrics) {
auto iter = FindById(&displays_, display.id());
if (iter == displays_.end())
return;
*iter = display;
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
}
mate::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return mate::ObjectTemplateBuilder(isolate)
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
}
// static
v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
if (!Browser::Get()->is_ready()) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate,
"Cannot require \"screen\" module before app is ready")));
"Cannot initialize \"screen\" module before app is ready")));
return v8::Null(isolate);
}
display::Screen* screen = display::Screen::GetScreen();
gfx::Screen* screen = gfx::Screen::GetNativeScreen();
if (!screen) {
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Failed to get screen information")));
return v8::Null(isolate);
}
return mate::CreateHandle(isolate, new Screen(isolate, screen)).ToV8();
}
// static
void Screen::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Screen"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("getCursorScreenPoint", &Screen::GetCursorScreenPoint)
.SetMethod("getPrimaryDisplay", &Screen::GetPrimaryDisplay)
.SetMethod("getAllDisplays", &Screen::GetAllDisplays)
.SetMethod("getDisplayNearestPoint", &Screen::GetDisplayNearestPoint)
#if defined(OS_MACOSX)
.SetMethod("getMenuBarHeight", &Screen::getMenuBarHeight)
#endif
.SetMethod("getDisplayMatching", &Screen::GetDisplayMatching);
return mate::CreateHandle(isolate, new Screen(screen)).ToV8();
}
} // namespace api
@@ -132,14 +135,10 @@ void Screen::BuildPrototype(
namespace {
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();
mate::Dictionary dict(isolate, exports);
dict.Set("screen", Screen::Create(isolate));
dict.Set("Screen", Screen::GetConstructor(isolate)->GetFunction());
mate::Dictionary dict(context->GetIsolate(), exports);
dict.Set("screen", atom::api::Screen::Create(context->GetIsolate()));
}
} // namespace

View File

@@ -9,8 +9,7 @@
#include "atom/browser/api/event_emitter.h"
#include "native_mate/handle.h"
#include "ui/display/display_observer.h"
#include "ui/display/screen.h"
#include "ui/gfx/display_observer.h"
namespace gfx {
class Point;
@@ -22,36 +21,34 @@ namespace atom {
namespace api {
class Screen : public mate::EventEmitter<Screen>,
public display::DisplayObserver {
class Screen : public mate::EventEmitter,
public gfx::DisplayObserver {
public:
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
protected:
Screen(v8::Isolate* isolate, display::Screen* screen);
~Screen() override;
explicit Screen(gfx::Screen* screen);
virtual ~Screen();
gfx::Point GetCursorScreenPoint();
display::Display GetPrimaryDisplay();
std::vector<display::Display> GetAllDisplays();
display::Display GetDisplayNearestPoint(const gfx::Point& point);
display::Display GetDisplayMatching(const gfx::Rect& match_rect);
gfx::Display GetPrimaryDisplay();
std::vector<gfx::Display> GetAllDisplays();
gfx::Display GetDisplayNearestPoint(const gfx::Point& point);
gfx::Display GetDisplayMatching(const gfx::Rect& match_rect);
#if defined(OS_MACOSX)
int getMenuBarHeight();
#endif
// display::DisplayObserver:
void OnDisplayAdded(const display::Display& new_display) override;
void OnDisplayRemoved(const display::Display& old_display) override;
void OnDisplayMetricsChanged(const display::Display& display,
// gfx::DisplayObserver:
void OnDisplayAdded(const gfx::Display& new_display) override;
void OnDisplayRemoved(const gfx::Display& old_display) override;
void OnDisplayMetricsChanged(const gfx::Display& display,
uint32_t changed_metrics) override;
// mate::Wrappable:
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
private:
display::Screen* screen_;
gfx::Screen* screen_;
std::vector<gfx::Display> displays_;
DISALLOW_COPY_AND_ASSIGN(Screen);
};

View File

@@ -1,18 +0,0 @@
// Copyright (c) 2017 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#import "atom/browser/api/atom_api_screen.h"
#import <Cocoa/Cocoa.h>
namespace atom {
namespace api {
int Screen::getMenuBarHeight() {
return [[NSApp mainMenu] menuBarHeight];
}
}// namespace api
}// namespace atom

View File

@@ -4,54 +4,44 @@
#include "atom/browser/api/atom_api_session.h"
#include <map>
#include <string>
#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_protocol.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/api/atom_api_web_request.h"
#include "atom/browser/api/save_page_handler.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/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/file_path_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "base/files/file_path.h"
#include "base/guid.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "brightray/browser/media/media_device_id_salt.h"
#include "base/thread_task_runner_handle.h"
#include "brightray/browser/net/devtools_network_conditions.h"
#include "brightray/browser/net/devtools_network_controller_handle.h"
#include "brightray/browser/net/devtools_network_controller.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager_delegate.h"
#include "content/public/browser/storage_partition.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#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/proxy/proxy_config_service_fixed.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/proxy/proxy_config_service_fixed.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"
using atom::api::Cookies;
using content::BrowserThread;
using content::StoragePartition;
@@ -59,21 +49,12 @@ namespace {
struct ClearStorageDataOptions {
GURL origin;
uint32_t storage_types = StoragePartition::REMOVE_DATA_MASK_ALL;
uint32_t quota_types = StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL;
uint32 storage_types = StoragePartition::REMOVE_DATA_MASK_ALL;
uint32 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;
uint32 GetStorageMask(const std::vector<std::string>& storage_types) {
uint32 storage_mask = 0;
for (const auto& it : storage_types) {
auto type = base::ToLowerASCII(it);
if (type == "appcache")
@@ -96,8 +77,8 @@ uint32_t GetStorageMask(const std::vector<std::string>& storage_types) {
return storage_mask;
}
uint32_t GetQuotaMask(const std::vector<std::string>& quota_types) {
uint32_t quota_mask = 0;
uint32 GetQuotaMask(const std::vector<std::string>& quota_types) {
uint32 quota_mask = 0;
for (const auto& it : quota_types) {
auto type = base::ToLowerASCII(it);
if (type == "temporary")
@@ -110,27 +91,6 @@ uint32_t GetQuotaMask(const std::vector<std::string>& quota_types) {
return quota_mask;
}
net::HttpAuth::Scheme GetAuthSchemeFromString(const std::string& scheme) {
if (scheme == "basic")
return net::HttpAuth::AUTH_SCHEME_BASIC;
if (scheme == "digest")
return net::HttpAuth::AUTH_SCHEME_DIGEST;
if (scheme == "ntlm")
return net::HttpAuth::AUTH_SCHEME_NTLM;
if (scheme == "negotiate")
return net::HttpAuth::AUTH_SCHEME_NEGOTIATE;
return net::HttpAuth::AUTH_SCHEME_MAX;
}
void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
const std::string& accept_lang,
const std::string& user_agent) {
getter->GetURLRequestContext()->set_http_user_agent_settings(
new net::StaticHttpUserAgentSettings(
net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang),
user_agent));
}
} // namespace
namespace mate {
@@ -153,32 +113,12 @@ struct Converter<ClearStorageDataOptions> {
}
};
template <>
struct Converter<ClearAuthCacheOptions> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
ClearAuthCacheOptions* out) {
mate::Dictionary options;
if (!ConvertFromV8(isolate, val, &options))
return false;
options.Get("type", &out->type);
options.Get("origin", &out->origin);
options.Get("realm", &out->realm);
options.Get("username", &out->username);
options.Get("password", &out->password);
std::string scheme;
if (options.Get("scheme", &scheme))
out->auth_scheme = GetAuthSchemeFromString(scheme);
return true;
}
};
template <>
template<>
struct Converter<net::ProxyConfig> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
net::ProxyConfig* out) {
std::string proxy_rules, proxy_bypass_rules;
std::string proxy_rules;
GURL pac_url;
mate::Dictionary options;
// Fallback to previous API when passed String.
@@ -188,7 +128,6 @@ struct Converter<net::ProxyConfig> {
} else if (ConvertFromV8(isolate, val, &options)) {
options.Get("pacScript", &pac_url);
options.Get("proxyRules", &proxy_rules);
options.Get("proxyBypassRules", &proxy_bypass_rules);
} else {
return false;
}
@@ -198,25 +137,11 @@ struct Converter<net::ProxyConfig> {
out->set_pac_url(pac_url);
} else {
out->proxy_rules().ParseFromString(proxy_rules);
out->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_rules);
}
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 {
@@ -225,20 +150,19 @@ namespace api {
namespace {
const char kPersistPrefix[] = "persist:";
// Referenced session objects.
std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
// The wrapSession funtion which is implemented in JavaScript
using WrapSessionCallback = base::Callback<void(v8::Local<v8::Value>)>;
WrapSessionCallback g_wrap_session;
class ResolveProxyHelper {
public:
ResolveProxyHelper(AtomBrowserContext* browser_context,
const GURL& url,
const Session::ResolveProxyCallback& callback)
Session::ResolveProxyCallback callback)
: callback_(callback),
original_thread_(base::ThreadTaskRunnerHandle::Get()) {
scoped_refptr<net::URLRequestContextGetter> context_getter =
browser_context->url_request_context_getter();
browser_context->GetRequestContext();
context_getter->GetNetworkTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ResolveProxyHelper::ResolveProxy,
@@ -267,8 +191,8 @@ class ResolveProxyHelper {
// Start the request.
int result = proxy_service->ResolveProxy(
url, "GET", &proxy_info_, completion_callback, &pac_req_, nullptr,
net::NetLogWithSource());
url, net::LOAD_NORMAL, &proxy_info_, completion_callback,
&pac_req_, nullptr, net::BoundNetLog());
// Completed synchronously.
if (result != net::ERR_IO_PENDING)
@@ -284,9 +208,6 @@ class ResolveProxyHelper {
};
// Runs the callback in UI thread.
void RunCallbackInUI(const base::Callback<void()>& callback) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
}
template<typename ...T>
void RunCallbackInUI(const base::Callback<void(T...)>& callback, T... result) {
BrowserThread::PostTask(
@@ -307,10 +228,10 @@ void OnGetBackend(disk_cache::Backend** backend_ptr,
} else if (action == Session::CacheAction::STATS) {
base::StringPairs stats;
(*backend_ptr)->GetStats(&stats);
for (const auto& stat : stats) {
if (stat.first == "Current size") {
for (size_t i = 0; i < stats.size(); ++i) {
if (stats[i].first == "Current size") {
int current_size;
base::StringToInt(stat.second, &current_size);
base::StringToInt(stats[i].second, &current_size);
RunCallbackInUI(callback, current_size);
break;
}
@@ -332,7 +253,7 @@ void DoCacheActionInIO(
// Call GetBackend and make the backend's ptr accessable in OnGetBackend.
using BackendPtr = disk_cache::Backend*;
auto* backend_ptr = new BackendPtr(nullptr);
BackendPtr* 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);
@@ -344,21 +265,13 @@ void SetProxyInIO(net::URLRequestContextGetter* getter,
const net::ProxyConfig& config,
const base::Closure& callback) {
auto proxy_service = getter->GetURLRequestContext()->proxy_service();
proxy_service->ResetConfigService(base::WrapUnique(
proxy_service->ResetConfigService(make_scoped_ptr(
new net::ProxyConfigServiceFixed(config)));
// Refetches and applies the new pac script if provided.
proxy_service->ForceReloadProxyConfig();
RunCallbackInUI(callback);
}
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) {
@@ -372,102 +285,31 @@ void ClearHostResolverCacheInIO(
}
}
void ClearAuthCacheInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const ClearAuthCacheOptions& options,
const base::Closure& callback) {
auto request_context = context_getter->GetURLRequestContext();
auto network_session =
request_context->http_transaction_factory()->GetSession();
if (network_session) {
if (options.type == "password") {
auto auth_cache = network_session->http_auth_cache();
if (!options.origin.is_empty()) {
auth_cache->Remove(
options.origin, options.realm, options.auth_scheme,
net::AuthCredentials(options.username, options.password));
} else {
auth_cache->ClearEntriesAddedWithin(base::TimeDelta::Max());
}
} else if (options.type == "clientCertificate") {
auto client_auth_cache = network_session->ssl_client_auth_cache();
client_auth_cache->Remove(net::HostPortPair::FromURL(options.origin));
}
network_session->CloseAllConnections();
}
if (!callback.is_null())
RunCallbackInUI(callback);
}
void AllowNTLMCredentialsForDomainsInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter,
const std::string& domains) {
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->set_server_whitelist(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(),
content::DownloadItem::INTERRUPTED,
content::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, false,
base::Time(), false,
std::vector<content::DownloadItem::ReceivedSlice>());
}
} // namespace
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
: devtools_network_emulation_client_id_(base::GenerateGUID()),
browser_context_(browser_context) {
// Observe DownloadManager to get download notifications.
Session::Session(AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
AttachAsUserData(browser_context);
// Observe DownloadManger to get download notifications.
content::BrowserContext::GetDownloadManager(browser_context)->
AddObserver(this);
Init(isolate);
AttachAsUserData(browser_context);
}
Session::~Session() {
content::BrowserContext::GetDownloadManager(browser_context())->
RemoveObserver(this);
g_sessions.erase(weak_map_id());
}
void Session::OnDownloadCreated(content::DownloadManager* manager,
content::DownloadItem* item) {
if (item->IsSavePackageDownload())
auto web_contents = item->GetWebContents();
if (SavePageHandler::IsSavePageTypes(item->GetMimeType()))
return;
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
auto handle = DownloadItem::Create(isolate(), item);
if (item->GetState() == content::DownloadItem::INTERRUPTED)
handle->SetSavePath(item->GetTargetFilePath());
bool prevent_default = Emit("will-download", handle, item->GetWebContents());
bool prevent_default = Emit(
"will-download",
DownloadItem::Create(isolate(), item),
api::WebContents::CreateFrom(isolate(), web_contents));
if (prevent_default) {
item->Cancel(true);
item->Remove();
@@ -488,24 +330,21 @@ void Session::DoCacheAction(const net::CompletionCallback& callback) {
}
void Session::ClearStorageData(mate::Arguments* args) {
// clearStorageData([options, callback])
// clearStorageData([options, ]callback)
ClearStorageDataOptions options;
base::Closure callback;
args->GetNext(&options);
args->GetNext(&callback);
base::Closure callback;
if (!args->GetNext(&callback)) {
args->ThrowError();
return;
}
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));
base::Time(), base::Time::Max(), callback);
}
void Session::FlushStorageData() {
@@ -527,9 +366,9 @@ void Session::SetDownloadPath(const base::FilePath& path) {
}
void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
std::unique_ptr<brightray::DevToolsNetworkConditions> conditions;
scoped_ptr<brightray::DevToolsNetworkConditions> conditions;
bool offline = false;
double latency = 0.0, download_throughput = 0.0, upload_throughput = 0.0;
double latency, download_throughput, upload_throughput;
if (options.Get("offline", &offline) && offline) {
conditions.reset(new brightray::DevToolsNetworkConditions(offline));
} else {
@@ -542,19 +381,25 @@ void Session::EnableNetworkEmulation(const mate::Dictionary& options) {
download_throughput,
upload_throughput));
}
auto controller = browser_context_->GetDevToolsNetworkController();
browser_context_->network_controller_handle()->SetNetworkState(
devtools_network_emulation_client_id_, std::move(conditions));
browser_context_->network_delegate()->SetDevToolsNetworkEmulationClientId(
devtools_network_emulation_client_id_);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&brightray::DevToolsNetworkController::SetNetworkState,
base::Unretained(controller),
std::string(),
base::Passed(&conditions)));
}
void Session::DisableNetworkEmulation() {
std::unique_ptr<brightray::DevToolsNetworkConditions> conditions;
browser_context_->network_controller_handle()->SetNetworkState(
devtools_network_emulation_client_id_, std::move(conditions));
browser_context_->network_delegate()->SetDevToolsNetworkEmulationClientId(
std::string());
scoped_ptr<brightray::DevToolsNetworkConditions> conditions(
new brightray::DevToolsNetworkConditions(false));
auto controller = browser_context_->GetDevToolsNetworkController();
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&brightray::DevToolsNetworkController::SetNetworkState,
base::Unretained(controller),
std::string(),
base::Passed(&conditions)));
}
void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
@@ -565,10 +410,7 @@ void Session::SetCertVerifyProc(v8::Local<v8::Value> val,
return;
}
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&SetCertVerifyProcInIO,
make_scoped_refptr(browser_context_->GetRequestContext()),
proc));
browser_context_->cert_verifier()->SetVerifyProc(proc);
}
void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
@@ -593,108 +435,14 @@ void Session::ClearHostResolverCache(mate::Arguments* args) {
callback));
}
void Session::ClearAuthCache(mate::Arguments* args) {
ClearAuthCacheOptions options;
if (!args->GetNext(&options)) {
args->ThrowError("Must specify options object");
return;
}
base::Closure callback;
args->GetNext(&callback);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ClearAuthCacheInIO,
make_scoped_refptr(browser_context_->GetRequestContext()),
options, callback));
}
void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&AllowNTLMCredentialsForDomainsInIO,
make_scoped_refptr(browser_context_->GetRequestContext()),
domains));
}
void Session::SetUserAgent(const std::string& user_agent,
mate::Arguments* args) {
browser_context_->SetUserAgent(user_agent);
std::string accept_lang = l10n_util::GetApplicationLocale("");
args->GetNext(&accept_lang);
auto getter = browser_context_->GetRequestContext();
getter->GetNetworkTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&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::Bind(&AtomBlobReader::StartReading,
base::Unretained(blob_reader),
uuid,
callback));
}
void Session::CreateInterruptedDownload(const mate::Dictionary& options) {
int64_t offset = 0, length = 0;
double start_time = 0.0;
std::string mime_type, last_modified, etag;
base::FilePath path;
std::vector<GURL> url_chain;
options.Get("path", &path);
options.Get("urlChain", &url_chain);
options.Get("mimeType", &mime_type);
options.Get("offset", &offset);
options.Get("length", &length);
options.Get("lastModified", &last_modified);
options.Get("eTag", &etag);
options.Get("startTime", &start_time);
if (path.empty() || url_chain.empty() || length == 0) {
isolate()->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate(), "Must pass non-empty path, urlChain and length.")));
return;
}
if (offset >= length) {
isolate()->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate(), "Must pass an offset value less than length.")));
return;
}
auto download_manager =
content::BrowserContext::GetDownloadManager(browser_context());
download_manager->GetDelegate()->GetNextId(base::Bind(
&DownloadIdCallback, download_manager, path, url_chain, mime_type, offset,
length, last_modified, etag, base::Time::FromDoubleT(start_time)));
}
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
if (cookies_.IsEmpty()) {
auto handle = Cookies::Create(isolate, browser_context());
auto handle = atom::api::Cookies::Create(isolate, browser_context());
cookies_.Reset(isolate, handle.ToV8());
}
return v8::Local<v8::Value>::New(isolate, cookies_);
}
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());
@@ -710,39 +458,23 @@ mate::Handle<Session> Session::CreateFrom(
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());
auto handle = mate::CreateHandle(isolate, new Session(browser_context));
g_wrap_session.Run(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());
v8::Isolate* isolate, const std::string& partition, bool in_memory) {
auto browser_context = brightray::BrowserContext::From(partition, in_memory);
return CreateFrom(isolate,
static_cast<AtomBrowserContext*>(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())
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.MakeDestroyable()
.SetMethod("resolveProxy", &Session::ResolveProxy)
.SetMethod("getCacheSize", &Session::DoCacheAction<CacheAction::STATS>)
@@ -753,49 +485,38 @@ void Session::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setDownloadPath", &Session::SetDownloadPath)
.SetMethod("enableNetworkEmulation", &Session::EnableNetworkEmulation)
.SetMethod("disableNetworkEmulation", &Session::DisableNetworkEmulation)
.SetMethod("_setCertificateVerifyProc", &Session::SetCertVerifyProc)
.SetMethod("setCertificateVerifyProc", &Session::SetCertVerifyProc)
.SetMethod("setPermissionRequestHandler",
&Session::SetPermissionRequestHandler)
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
.SetMethod("clearAuthCache", &Session::ClearAuthCache)
.SetMethod("allowNTLMCredentialsForDomains",
&Session::AllowNTLMCredentialsForDomains)
.SetMethod("setUserAgent", &Session::SetUserAgent)
.SetMethod("getUserAgent", &Session::GetUserAgent)
.SetMethod("getBlobData", &Session::GetBlobData)
.SetMethod("createInterruptedDownload",
&Session::CreateInterruptedDownload)
.SetProperty("cookies", &Session::Cookies)
.SetProperty("protocol", &Session::Protocol)
.SetProperty("webRequest", &Session::WebRequest);
}
void ClearWrapSession() {
g_wrap_session.Reset();
}
void SetWrapSession(const WrapSessionCallback& callback) {
g_wrap_session = callback;
// Cleanup the wrapper on exit.
atom::AtomBrowserMainParts::Get()->RegisterDestructionCallback(
base::Bind(ClearWrapSession));
}
} // 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);
dict.SetMethod("fromPartition", &atom::api::Session::FromPartition);
dict.SetMethod("_setWrapSession", &atom::api::SetWrapSession);
}
} // namespace

View File

@@ -8,8 +8,6 @@
#include <string>
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/atom_blob_reader.h"
#include "base/values.h"
#include "content/public/browser/download_manager.h"
#include "native_mate/handle.h"
#include "net/base/completion_callback.h"
@@ -49,18 +47,25 @@ class Session: public mate::TrackableObject<Session>,
static mate::Handle<Session> CreateFrom(
v8::Isolate* isolate, AtomBrowserContext* browser_context);
// Gets the Session of |partition|.
// Gets the Session of |partition| and |in_memory|.
static mate::Handle<Session> FromPartition(
v8::Isolate* isolate, const std::string& partition,
const base::DictionaryValue& options = base::DictionaryValue());
v8::Isolate* isolate, const std::string& partition, bool in_memory);
AtomBrowserContext* browser_context() const { return browser_context_.get(); }
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
// Methods.
protected:
explicit Session(AtomBrowserContext* browser_context);
~Session();
// content::DownloadManager::Observer:
void OnDownloadCreated(content::DownloadManager* manager,
content::DownloadItem* item) override;
private:
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
template<CacheAction action>
void DoCacheAction(const net::CompletionCallback& callback);
@@ -74,34 +79,13 @@ class Session: public mate::TrackableObject<Session>,
void SetPermissionRequestHandler(v8::Local<v8::Value> val,
mate::Arguments* args);
void ClearHostResolverCache(mate::Arguments* args);
void ClearAuthCache(mate::Arguments* args);
void AllowNTLMCredentialsForDomains(const std::string& domains);
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
std::string GetUserAgent();
void GetBlobData(const std::string& uuid,
const AtomBlobReader::CompletionCallback& callback);
void CreateInterruptedDownload(const mate::Dictionary& options);
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
protected:
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~Session();
// content::DownloadManager::Observer:
void OnDownloadCreated(content::DownloadManager* manager,
content::DownloadItem* item) override;
private:
// Cached object.
v8::Global<v8::Value> cookies_;
v8::Global<v8::Value> protocol_;
v8::Global<v8::Value> web_request_;
// The X-DevTools-Emulate-Network-Conditions-Client-Id.
std::string devtools_network_emulation_client_id_;
scoped_refptr<AtomBrowserContext> browser_context_;
DISALLOW_COPY_AND_ASSIGN(Session);

View File

@@ -1,98 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_system_preferences.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 "native_mate/dictionary.h"
#include "ui/gfx/color_utils.h"
namespace atom {
namespace api {
SystemPreferences::SystemPreferences(v8::Isolate* isolate) {
Init(isolate);
#if defined(OS_WIN)
InitializeWindow();
#endif
}
SystemPreferences::~SystemPreferences() {
#if defined(OS_WIN)
Browser::Get()->RemoveObserver(this);
#endif
}
#if !defined(OS_MACOSX)
bool SystemPreferences::IsDarkMode() {
return false;
}
#endif
bool SystemPreferences::IsInvertedColorScheme() {
return color_utils::IsInvertedColorScheme();
}
// static
mate::Handle<SystemPreferences> SystemPreferences::Create(
v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new SystemPreferences(isolate));
}
// static
void SystemPreferences::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "SystemPreferences"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
#if defined(OS_WIN)
.SetMethod("getAccentColor", &SystemPreferences::GetAccentColor)
.SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled)
.SetMethod("getColor", &SystemPreferences::GetColor)
#elif defined(OS_MACOSX)
.SetMethod("postNotification",
&SystemPreferences::PostNotification)
.SetMethod("postLocalNotification",
&SystemPreferences::PostLocalNotification)
.SetMethod("subscribeNotification",
&SystemPreferences::SubscribeNotification)
.SetMethod("unsubscribeNotification",
&SystemPreferences::UnsubscribeNotification)
.SetMethod("subscribeLocalNotification",
&SystemPreferences::SubscribeLocalNotification)
.SetMethod("unsubscribeLocalNotification",
&SystemPreferences::UnsubscribeLocalNotification)
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
.SetMethod("setUserDefault", &SystemPreferences::SetUserDefault)
.SetMethod("removeUserDefault", &SystemPreferences::RemoveUserDefault)
.SetMethod("isSwipeTrackingFromScrollEventsEnabled",
&SystemPreferences::IsSwipeTrackingFromScrollEventsEnabled)
#endif
.SetMethod("isInvertedColorScheme",
&SystemPreferences::IsInvertedColorScheme)
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode);
}
} // namespace api
} // namespace atom
namespace {
using atom::api::SystemPreferences;
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("systemPreferences", SystemPreferences::Create(isolate));
dict.Set("SystemPreferences",
SystemPreferences::GetConstructor(isolate)->GetFunction());
}
} // namespace
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_system_preferences, Initialize);

View File

@@ -1,130 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
#define ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_
#include <string>
#include "atom/browser/api/event_emitter.h"
#include "base/callback.h"
#include "base/values.h"
#include "native_mate/handle.h"
#if defined(OS_WIN)
#include "atom/browser/browser.h"
#include "atom/browser/browser_observer.h"
#include "ui/gfx/sys_color_change_listener.h"
#endif
namespace base {
class DictionaryValue;
}
namespace atom {
namespace api {
class SystemPreferences : public mate::EventEmitter<SystemPreferences>
#if defined(OS_WIN)
, public BrowserObserver
, public gfx::SysColorChangeListener
#endif
{
public:
static mate::Handle<SystemPreferences> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
#if defined(OS_WIN)
bool IsAeroGlassEnabled();
typedef HRESULT (STDAPICALLTYPE *DwmGetColorizationColor)(DWORD *, BOOL *);
DwmGetColorizationColor dwmGetColorizationColor =
(DwmGetColorizationColor) GetProcAddress(LoadLibraryW(L"dwmapi.dll"),
"DwmGetColorizationColor");
std::string GetAccentColor();
std::string GetColor(const std::string& color, mate::Arguments* args);
void InitializeWindow();
// gfx::SysColorChangeListener:
void OnSysColorChange() override;
// BrowserObserver:
void OnFinishLaunching(const base::DictionaryValue& launch_info) override;
#elif defined(OS_MACOSX)
using NotificationCallback = base::Callback<
void(const std::string&, const base::DictionaryValue&)>;
void PostNotification(const std::string& name,
const base::DictionaryValue& user_info);
void PostLocalNotification(const std::string& name,
const base::DictionaryValue& user_info);
int SubscribeNotification(const std::string& name,
const NotificationCallback& callback);
void UnsubscribeNotification(int id);
int SubscribeLocalNotification(const std::string& name,
const NotificationCallback& callback);
void UnsubscribeLocalNotification(int request_id);
v8::Local<v8::Value> GetUserDefault(const std::string& name,
const std::string& type);
void SetUserDefault(const std::string& name,
const std::string& type,
mate::Arguments* args);
void RemoveUserDefault(const std::string& name);
bool IsSwipeTrackingFromScrollEventsEnabled();
#endif
bool IsDarkMode();
bool IsInvertedColorScheme();
protected:
explicit SystemPreferences(v8::Isolate* isolate);
~SystemPreferences() override;
#if defined(OS_MACOSX)
void DoPostNotification(const std::string& name,
const base::DictionaryValue& user_info,
bool is_local);
int DoSubscribeNotification(const std::string& name,
const NotificationCallback& callback,
bool is_local);
void DoUnsubscribeNotification(int request_id, bool is_local);
#endif
private:
#if defined(OS_WIN)
// Static callback invoked when a message comes in to our messaging window.
static LRESULT CALLBACK
WndProcStatic(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
LRESULT CALLBACK
WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
// The window class of |window_|.
ATOM atom_;
// The handle of the module that contains the window procedure of |window_|.
HMODULE instance_;
// The window used for processing events.
HWND window_;
std::string current_color_;
bool invertered_color_scheme_;
std::unique_ptr<gfx::ScopedSysColorChangeListener> color_change_listener_;
#endif
DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_SYSTEM_PREFERENCES_H_

View File

@@ -1,249 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_system_preferences.h"
#include <map>
#import <Cocoa/Cocoa.h>
#include "atom/browser/mac/dict_util.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "base/strings/sys_string_conversions.h"
#include "base/values.h"
#include "net/base/mac/url_conversions.h"
namespace atom {
namespace api {
namespace {
int g_next_id = 0;
// The map to convert |id| to |int|.
std::map<int, id> g_id_map;
} // namespace
void SystemPreferences::PostNotification(const std::string& name,
const base::DictionaryValue& user_info) {
DoPostNotification(name, user_info, false);
}
void SystemPreferences::PostLocalNotification(const std::string& name,
const base::DictionaryValue& user_info) {
DoPostNotification(name, user_info, true);
}
void SystemPreferences::DoPostNotification(const std::string& name,
const base::DictionaryValue& user_info, bool is_local) {
NSNotificationCenter* center = is_local ?
[NSNotificationCenter defaultCenter] :
[NSDistributedNotificationCenter defaultCenter];
[center
postNotificationName:base::SysUTF8ToNSString(name)
object:nil
userInfo:DictionaryValueToNSDictionary(user_info)
];
}
int SystemPreferences::SubscribeNotification(
const std::string& name, const NotificationCallback& callback) {
return DoSubscribeNotification(name, callback, false);
}
void SystemPreferences::UnsubscribeNotification(int request_id) {
DoUnsubscribeNotification(request_id, false);
}
int SystemPreferences::SubscribeLocalNotification(
const std::string& name, const NotificationCallback& callback) {
return DoSubscribeNotification(name, callback, true);
}
void SystemPreferences::UnsubscribeLocalNotification(int request_id) {
DoUnsubscribeNotification(request_id, true);
}
int SystemPreferences::DoSubscribeNotification(const std::string& name,
const NotificationCallback& callback, bool is_local) {
int request_id = g_next_id++;
__block NotificationCallback copied_callback = callback;
NSNotificationCenter* center = is_local ?
[NSNotificationCenter defaultCenter] :
[NSDistributedNotificationCenter defaultCenter];
g_id_map[request_id] = [center
addObserverForName:base::SysUTF8ToNSString(name)
object:nil
queue:nil
usingBlock:^(NSNotification* notification) {
std::unique_ptr<base::DictionaryValue> user_info =
NSDictionaryToDictionaryValue(notification.userInfo);
if (user_info) {
copied_callback.Run(
base::SysNSStringToUTF8(notification.name),
*user_info);
} else {
copied_callback.Run(
base::SysNSStringToUTF8(notification.name),
base::DictionaryValue());
}
}
];
return request_id;
}
void SystemPreferences::DoUnsubscribeNotification(int request_id, bool is_local) {
auto iter = g_id_map.find(request_id);
if (iter != g_id_map.end()) {
id observer = iter->second;
NSNotificationCenter* center = is_local ?
[NSNotificationCenter defaultCenter] :
[NSDistributedNotificationCenter defaultCenter];
[center removeObserver:observer];
g_id_map.erase(iter);
}
}
v8::Local<v8::Value> SystemPreferences::GetUserDefault(
const std::string& name, const std::string& type) {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSString* key = base::SysUTF8ToNSString(name);
if (type == "string") {
return mate::StringToV8(isolate(),
base::SysNSStringToUTF8([defaults stringForKey:key]));
} else if (type == "boolean") {
return v8::Boolean::New(isolate(), [defaults boolForKey:key]);
} else if (type == "float") {
return v8::Number::New(isolate(), [defaults floatForKey:key]);
} else if (type == "integer") {
return v8::Integer::New(isolate(), [defaults integerForKey:key]);
} else if (type == "double") {
return v8::Number::New(isolate(), [defaults doubleForKey:key]);
} else if (type == "url") {
return mate::ConvertToV8(isolate(),
net::GURLWithNSURL([defaults URLForKey:key]));
} else if (type == "array") {
std::unique_ptr<base::ListValue> list =
NSArrayToListValue([defaults arrayForKey:key]);
if (list == nullptr)
list.reset(new base::ListValue());
return mate::ConvertToV8(isolate(), *list);
} else if (type == "dictionary") {
std::unique_ptr<base::DictionaryValue> dictionary =
NSDictionaryToDictionaryValue([defaults dictionaryForKey:key]);
if (dictionary == nullptr)
dictionary.reset(new base::DictionaryValue());
return mate::ConvertToV8(isolate(), *dictionary);
} else {
return v8::Undefined(isolate());
}
}
void SystemPreferences::SetUserDefault(const std::string& name,
const std::string& type,
mate::Arguments* args) {
const auto throwConversionError = [&] {
args->ThrowError("Unable to convert value to: " + type);
};
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSString* key = base::SysUTF8ToNSString(name);
if (type == "string") {
std::string value;
if (!args->GetNext(&value)) {
throwConversionError();
return;
}
[defaults setObject:base::SysUTF8ToNSString(value) forKey:key];
} else if (type == "boolean") {
bool value;
if (!args->GetNext(&value)) {
throwConversionError();
return;
}
[defaults setBool:value forKey:key];
} else if (type == "float") {
float value;
if (!args->GetNext(&value)) {
throwConversionError();
return;
}
[defaults setFloat:value forKey:key];
} else if (type == "integer") {
int value;
if (!args->GetNext(&value)) {
throwConversionError();
return;
}
[defaults setInteger:value forKey:key];
} else if (type == "double") {
double value;
if (!args->GetNext(&value)) {
throwConversionError();
return;
}
[defaults setDouble:value forKey:key];
} else if (type == "url") {
GURL value;
if (!args->GetNext(&value)) {
throwConversionError();
return;
}
if (NSURL* url = net::NSURLWithGURL(value)) {
[defaults setURL:url forKey:key];
}
} else if (type == "array") {
base::ListValue value;
if (!args->GetNext(&value)) {
throwConversionError();
return;
}
if (NSArray* array = ListValueToNSArray(value)) {
[defaults setObject:array forKey:key];
}
} else if (type == "dictionary") {
base::DictionaryValue value;
if (!args->GetNext(&value)) {
throwConversionError();
return;
}
if (NSDictionary* dict = DictionaryValueToNSDictionary(value)) {
[defaults setObject:dict forKey:key];
}
} else {
args->ThrowError("Invalid type: " + type);
return;
}
}
void SystemPreferences::RemoveUserDefault(const std::string& name) {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:base::SysUTF8ToNSString(name)];
}
bool SystemPreferences::IsDarkMode() {
NSString* mode = [[NSUserDefaults standardUserDefaults]
stringForKey:@"AppleInterfaceStyle"];
return [mode isEqualToString:@"Dark"];
}
bool SystemPreferences::IsSwipeTrackingFromScrollEventsEnabled() {
return [NSEvent isSwipeTrackingFromScrollEventsEnabled];
}
} // namespace api
} // namespace atom

View File

@@ -1,190 +0,0 @@
// Copyright (c) 2014 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_system_preferences.h"
#include "atom/common/color_util.h"
#include "base/win/wrapped_window_proc.h"
#include "ui/base/win/shell.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/win/hwnd_util.h"
namespace atom {
namespace {
const wchar_t kSystemPreferencesWindowClass[] =
L"Electron_SystemPreferencesHostWindow";
} // namespace
namespace api {
bool SystemPreferences::IsAeroGlassEnabled() {
return ui::win::IsAeroGlassEnabled();
}
std::string hexColorDWORDToRGBA(DWORD color) {
std::ostringstream stream;
stream << std::hex << color;
std::string hexColor = stream.str();
return hexColor.substr(2) + hexColor.substr(0, 2);
}
std::string SystemPreferences::GetAccentColor() {
DWORD color = 0;
BOOL opaque = FALSE;
if (FAILED(dwmGetColorizationColor(&color, &opaque))) {
return "";
}
return hexColorDWORDToRGBA(color);
}
std::string SystemPreferences::GetColor(const std::string& color,
mate::Arguments* args) {
int id;
if (color == "3d-dark-shadow") {
id = COLOR_3DDKSHADOW;
} else if (color == "3d-face") {
id = COLOR_3DFACE;
} else if (color == "3d-highlight") {
id = COLOR_3DHIGHLIGHT;
} else if (color == "3d-light") {
id = COLOR_3DLIGHT;
} else if (color == "3d-shadow") {
id = COLOR_3DSHADOW;
} else if (color == "active-border") {
id = COLOR_ACTIVEBORDER;
} else if (color == "active-caption") {
id = COLOR_ACTIVECAPTION;
} else if (color == "active-caption-gradient") {
id = COLOR_GRADIENTACTIVECAPTION;
} else if (color == "app-workspace") {
id = COLOR_APPWORKSPACE;
} else if (color == "button-text") {
id = COLOR_BTNTEXT;
} else if (color == "caption-text") {
id = COLOR_CAPTIONTEXT;
} else if (color == "desktop") {
id = COLOR_DESKTOP;
} else if (color == "disabled-text") {
id = COLOR_GRAYTEXT;
} else if (color == "highlight") {
id = COLOR_HIGHLIGHT;
} else if (color == "highlight-text") {
id = COLOR_HIGHLIGHTTEXT;
} else if (color == "hotlight") {
id = COLOR_HOTLIGHT;
} else if (color == "inactive-border") {
id = COLOR_INACTIVEBORDER;
} else if (color == "inactive-caption") {
id = COLOR_INACTIVECAPTION;
} else if (color == "inactive-caption-gradient") {
id = COLOR_GRADIENTINACTIVECAPTION;
} else if (color == "inactive-caption-text") {
id = COLOR_INACTIVECAPTIONTEXT;
} else if (color == "info-background") {
id = COLOR_INFOBK;
} else if (color == "info-text") {
id = COLOR_INFOTEXT;
} else if (color == "menu") {
id = COLOR_MENU;
} else if (color == "menu-highlight") {
id = COLOR_MENUHILIGHT;
} else if (color == "menubar") {
id = COLOR_MENUBAR;
} else if (color == "menu-text") {
id = COLOR_MENUTEXT;
} else if (color == "scrollbar") {
id = COLOR_SCROLLBAR;
} else if (color == "window") {
id = COLOR_WINDOW;
} else if (color == "window-frame") {
id = COLOR_WINDOWFRAME;
} else if (color == "window-text") {
id = COLOR_WINDOWTEXT;
} else {
args->ThrowError("Unknown color: " + color);
return "";
}
return ToRGBHex(color_utils::GetSysSkColor(id));
}
void SystemPreferences::InitializeWindow() {
invertered_color_scheme_ = IsInvertedColorScheme();
// Wait until app is ready before creating sys color listener
// Creating this listener before the app is ready causes global shortcuts
// to not fire
if (Browser::Get()->is_ready())
color_change_listener_.reset(new gfx::ScopedSysColorChangeListener(this));
else
Browser::Get()->AddObserver(this);
WNDCLASSEX window_class;
base::win::InitializeWindowClass(
kSystemPreferencesWindowClass,
&base::win::WrappedWindowProc<SystemPreferences::WndProcStatic>,
0, 0, 0, NULL, NULL, NULL, NULL, NULL,
&window_class);
instance_ = window_class.hInstance;
atom_ = RegisterClassEx(&window_class);
// Create an offscreen window for receiving broadcast messages for the system
// colorization color. Create a hidden WS_POPUP window instead of an
// HWND_MESSAGE window, because only top-level windows such as popups can
// receive broadcast messages like "WM_DWMCOLORIZATIONCOLORCHANGED".
window_ = CreateWindow(MAKEINTATOM(atom_),
0, WS_POPUP, 0, 0, 0, 0, 0, 0, instance_, 0);
gfx::CheckWindowCreated(window_);
gfx::SetWindowUserData(window_, this);
}
LRESULT CALLBACK SystemPreferences::WndProcStatic(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam) {
SystemPreferences* msg_wnd = reinterpret_cast<SystemPreferences*>(
GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (msg_wnd)
return msg_wnd->WndProc(hwnd, message, wparam, lparam);
else
return ::DefWindowProc(hwnd, message, wparam, lparam);
}
LRESULT CALLBACK SystemPreferences::WndProc(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam) {
if (message == WM_DWMCOLORIZATIONCOLORCHANGED) {
DWORD new_color = (DWORD) wparam;
std::string new_color_string = hexColorDWORDToRGBA(new_color);
if (new_color_string != current_color_) {
Emit("accent-color-changed", hexColorDWORDToRGBA(new_color));
current_color_ = new_color_string;
}
}
return ::DefWindowProc(hwnd, message, wparam, lparam);
}
void SystemPreferences::OnSysColorChange() {
bool new_invertered_color_scheme = IsInvertedColorScheme();
if (new_invertered_color_scheme != invertered_color_scheme_) {
invertered_color_scheme_ = new_invertered_color_scheme;
Emit("inverted-color-scheme-changed", new_invertered_color_scheme);
}
Emit("color-changed");
}
void SystemPreferences::OnFinishLaunching(
const base::DictionaryValue& launch_info) {
color_change_listener_.reset(new gfx::ScopedSysColorChangeListener(this));
}
} // namespace api
} // namespace atom

View File

@@ -8,96 +8,58 @@
#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/browser.h"
#include "atom/common/api/atom_api_native_image.h"
#include "atom/browser/ui/tray_icon.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/node_includes.h"
#include "base/threading/thread_task_runner_handle.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/image/image.h"
namespace mate {
template<>
struct Converter<atom::TrayIcon::HighlightMode> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
atom::TrayIcon::HighlightMode* out) {
std::string mode;
if (ConvertFromV8(isolate, val, &mode)) {
if (mode == "always") {
*out = atom::TrayIcon::HighlightMode::ALWAYS;
return true;
}
if (mode == "selection") {
*out = atom::TrayIcon::HighlightMode::SELECTION;
return true;
}
if (mode == "never") {
*out = atom::TrayIcon::HighlightMode::NEVER;
return true;
}
}
// Support old boolean parameter
// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
bool highlight;
if (ConvertFromV8(isolate, val, &highlight)) {
if (highlight)
*out = atom::TrayIcon::HighlightMode::SELECTION;
else
*out = atom::TrayIcon::HighlightMode::NEVER;
return true;
}
return false;
}
};
} // namespace mate
namespace atom {
namespace api {
Tray::Tray(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
mate::Handle<NativeImage> image)
Tray::Tray(const gfx::Image& image)
: tray_icon_(TrayIcon::Create()) {
SetImage(isolate, image);
tray_icon_->SetImage(image);
tray_icon_->AddObserver(this);
InitWith(isolate, wrapper);
}
Tray::~Tray() {
// Destroy the native tray in next tick.
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(
FROM_HERE, tray_icon_.release());
}
// static
mate::WrappableBase* Tray::New(mate::Handle<NativeImage> image,
mate::Arguments* args) {
mate::Wrappable* Tray::New(v8::Isolate* isolate, const gfx::Image& image) {
if (!Browser::Get()->is_ready()) {
args->ThrowError("Cannot create Tray before app is ready");
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Cannot create Tray before app is ready")));
return nullptr;
}
return new Tray(args->isolate(), args->GetThis(), image);
return new Tray(image);
}
void Tray::OnClicked(const gfx::Rect& bounds,
const gfx::Point& location,
int modifiers) {
EmitWithFlags("click", modifiers, bounds, location);
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("click",
ModifiersToObject(isolate(), modifiers), bounds);
}
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
EmitWithFlags("double-click", modifiers, bounds);
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("double-click",
ModifiersToObject(isolate(), modifiers), bounds);
}
void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
EmitWithFlags("right-click", modifiers, bounds);
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitCustomEvent("right-click",
ModifiersToObject(isolate(), modifiers), bounds);
}
void Tray::OnBalloonShow() {
@@ -120,22 +82,6 @@ void Tray::OnDropFiles(const std::vector<std::string>& files) {
Emit("drop-files", files);
}
void Tray::OnDropText(const std::string& text) {
Emit("drop-text", text);
}
void Tray::OnMouseEntered(const gfx::Point& location, int modifiers) {
EmitWithFlags("mouse-enter", modifiers, location);
}
void Tray::OnMouseExited(const gfx::Point& location, int modifiers) {
EmitWithFlags("mouse-leave", modifiers, location);
}
void Tray::OnMouseMoved(const gfx::Point& location, int modifiers) {
EmitWithFlags("mouse-move", modifiers, location);
}
void Tray::OnDragEntered() {
Emit("drag-enter");
}
@@ -148,38 +94,29 @@ void Tray::OnDragEnded() {
Emit("drag-end");
}
void Tray::SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image) {
#if defined(OS_WIN)
tray_icon_->SetImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
#else
tray_icon_->SetImage(image->image());
#endif
void Tray::SetImage(mate::Arguments* args, const gfx::Image& image) {
tray_icon_->SetImage(image);
}
void Tray::SetPressedImage(v8::Isolate* isolate,
mate::Handle<NativeImage> image) {
#if defined(OS_WIN)
tray_icon_->SetPressedImage(image->GetHICON(GetSystemMetrics(SM_CXSMICON)));
#else
tray_icon_->SetPressedImage(image->image());
#endif
void Tray::SetPressedImage(mate::Arguments* args, const gfx::Image& image) {
tray_icon_->SetPressedImage(image);
}
void Tray::SetToolTip(const std::string& tool_tip) {
void Tray::SetToolTip(mate::Arguments* args, const std::string& tool_tip) {
tray_icon_->SetToolTip(tool_tip);
}
void Tray::SetTitle(const std::string& title) {
void Tray::SetTitle(mate::Arguments* args, const std::string& title) {
tray_icon_->SetTitle(title);
}
void Tray::SetHighlightMode(TrayIcon::HighlightMode mode) {
tray_icon_->SetHighlightMode(mode);
void Tray::SetHighlightMode(mate::Arguments* args, bool highlight) {
tray_icon_->SetHighlightMode(highlight);
}
void Tray::DisplayBalloon(mate::Arguments* args,
const mate::Dictionary& options) {
mate::Handle<NativeImage> icon;
gfx::Image icon;
options.Get("icon", &icon);
base::string16 title, content;
if (!options.Get("title", &title) ||
@@ -188,14 +125,7 @@ void Tray::DisplayBalloon(mate::Arguments* args,
return;
}
#if defined(OS_WIN)
tray_icon_->DisplayBalloon(
icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
title, content);
#else
tray_icon_->DisplayBalloon(
icon.IsEmpty() ? gfx::Image() : icon->image(), title, content);
#endif
tray_icon_->DisplayBalloon(icon, title, content);
}
void Tray::PopUpContextMenu(mate::Arguments* args) {
@@ -206,20 +136,24 @@ void Tray::PopUpContextMenu(mate::Arguments* args) {
tray_icon_->PopUpContextMenu(pos, menu.IsEmpty() ? nullptr : menu->model());
}
void Tray::SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu) {
menu_.Reset(isolate, menu.ToV8());
void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) {
tray_icon_->SetContextMenu(menu->model());
}
gfx::Rect Tray::GetBounds() {
return tray_icon_->GetBounds();
v8::Local<v8::Object> Tray::ModifiersToObject(v8::Isolate* isolate,
int modifiers) {
mate::Dictionary obj(isolate, v8::Object::New(isolate));
obj.Set("shiftKey", static_cast<bool>(modifiers & ui::EF_SHIFT_DOWN));
obj.Set("ctrlKey", static_cast<bool>(modifiers & ui::EF_CONTROL_DOWN));
obj.Set("altKey", static_cast<bool>(modifiers & ui::EF_ALT_DOWN));
obj.Set("metaKey", static_cast<bool>(modifiers & ui::EF_COMMAND_DOWN));
return obj.GetHandle();
}
// static
void Tray::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Tray"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.MakeDestroyable()
.SetMethod("setImage", &Tray::SetImage)
.SetMethod("setPressedImage", &Tray::SetPressedImage)
@@ -228,8 +162,7 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setHighlightMode", &Tray::SetHighlightMode)
.SetMethod("displayBalloon", &Tray::DisplayBalloon)
.SetMethod("popUpContextMenu", &Tray::PopUpContextMenu)
.SetMethod("setContextMenu", &Tray::SetContextMenu)
.SetMethod("getBounds", &Tray::GetBounds);
.SetMethod("_setContextMenu", &Tray::SetContextMenu);
}
} // namespace api
@@ -239,15 +172,14 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
namespace {
using atom::api::Tray;
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
using atom::api::Tray;
v8::Isolate* isolate = context->GetIsolate();
Tray::SetConstructor(isolate, base::Bind(&Tray::New));
v8::Local<v8::Function> constructor = mate::CreateConstructor<Tray>(
isolate, "Tray", base::Bind(&Tray::New));
mate::Dictionary dict(isolate, exports);
dict.Set("Tray", Tray::GetConstructor(isolate)->GetFunction());
dict.Set("Tray", static_cast<v8::Local<v8::Value>>(constructor));
}
} // namespace

View File

@@ -5,14 +5,12 @@
#ifndef ATOM_BROWSER_API_ATOM_API_TRAY_H_
#define ATOM_BROWSER_API_ATOM_API_TRAY_H_
#include <memory>
#include <string>
#include <vector>
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/ui/tray_icon.h"
#include "atom/browser/ui/tray_icon_observer.h"
#include "native_mate/handle.h"
#include "base/memory/scoped_ptr.h"
namespace gfx {
class Image;
@@ -30,26 +28,21 @@ class TrayIcon;
namespace api {
class Menu;
class NativeImage;
class Tray : public mate::TrackableObject<Tray>,
public TrayIconObserver {
public:
static mate::WrappableBase* New(mate::Handle<NativeImage> image,
mate::Arguments* args);
static mate::Wrappable* New(v8::Isolate* isolate, const gfx::Image& image);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
protected:
Tray(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
mate::Handle<NativeImage> image);
explicit Tray(const gfx::Image& image);
~Tray() override;
// TrayIconObserver:
void OnClicked(const gfx::Rect& bounds,
const gfx::Point& location,
int modifiers) override;
void OnClicked(const gfx::Rect& bounds, int modifiers) override;
void OnDoubleClicked(const gfx::Rect& bounds, int modifiers) override;
void OnRightClicked(const gfx::Rect& bounds, int modifiers) override;
void OnBalloonShow() override;
@@ -57,27 +50,23 @@ class Tray : public mate::TrackableObject<Tray>,
void OnBalloonClosed() override;
void OnDrop() override;
void OnDropFiles(const std::vector<std::string>& files) override;
void OnDropText(const std::string& text) override;
void OnDragEntered() override;
void OnDragExited() override;
void OnDragEnded() override;
void OnMouseEntered(const gfx::Point& location, int modifiers) override;
void OnMouseExited(const gfx::Point& location, int modifiers) override;
void OnMouseMoved(const gfx::Point& location, int modifiers) override;
void SetImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
void SetPressedImage(v8::Isolate* isolate, mate::Handle<NativeImage> image);
void SetToolTip(const std::string& tool_tip);
void SetTitle(const std::string& title);
void SetHighlightMode(TrayIcon::HighlightMode mode);
void SetImage(mate::Arguments* args, const gfx::Image& image);
void SetPressedImage(mate::Arguments* args, const gfx::Image& image);
void SetToolTip(mate::Arguments* args, const std::string& tool_tip);
void SetTitle(mate::Arguments* args, const std::string& title);
void SetHighlightMode(mate::Arguments* args, bool highlight);
void DisplayBalloon(mate::Arguments* args, const mate::Dictionary& options);
void PopUpContextMenu(mate::Arguments* args);
void SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu);
gfx::Rect GetBounds();
void SetContextMenu(mate::Arguments* args, Menu* menu);
private:
v8::Global<v8::Object> menu_;
std::unique_ptr<TrayIcon> tray_icon_;
v8::Local<v8::Object> ModifiersToObject(v8::Isolate* isolate, int modifiers);
scoped_ptr<TrayIcon> tray_icon_;
DISALLOW_COPY_AND_ASSIGN(Tray);
};

View File

@@ -1,481 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_url_request.h"
#include <string>
#include "atom/browser/api/atom_api_session.h"
#include "atom/browser/net/atom_url_request.h"
#include "atom/common/api/event_emitter_caller.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/net_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/node_includes.h"
#include "native_mate/dictionary.h"
namespace mate {
template <>
struct Converter<scoped_refptr<const net::IOBufferWithSize>> {
static v8::Local<v8::Value> ToV8(
v8::Isolate* isolate,
scoped_refptr<const net::IOBufferWithSize> buffer) {
return node::Buffer::Copy(isolate, buffer->data(), buffer->size())
.ToLocalChecked();
}
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
scoped_refptr<const net::IOBufferWithSize>* out) {
auto size = node::Buffer::Length(val);
if (size == 0) {
// Support conversion from empty buffer. A use case is
// a GET request without body.
// Since zero-sized IOBuffer(s) are not supported, we set the
// out pointer to null.
*out = nullptr;
return true;
}
auto data = node::Buffer::Data(val);
if (!data) {
// This is an error as size is positive but data is null.
return false;
}
*out = new net::IOBufferWithSize(size);
// We do a deep copy. We could have used Buffer's internal memory
// but that is much more complicated to be properly handled.
memcpy((*out)->data(), data, size);
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
template <typename Flags>
URLRequest::StateBase<Flags>::StateBase(Flags initialState)
: state_(initialState) {}
template <typename Flags>
void URLRequest::StateBase<Flags>::SetFlag(Flags flag) {
state_ =
static_cast<Flags>(static_cast<int>(state_) | static_cast<int>(flag));
}
template <typename Flags>
bool URLRequest::StateBase<Flags>::operator==(Flags flag) const {
return state_ == flag;
}
template <typename Flags>
bool URLRequest::StateBase<Flags>::IsFlagSet(Flags flag) const {
return static_cast<int>(state_) & static_cast<int>(flag);
}
URLRequest::RequestState::RequestState()
: StateBase(RequestStateFlags::kNotStarted) {}
bool URLRequest::RequestState::NotStarted() const {
return *this == RequestStateFlags::kNotStarted;
}
bool URLRequest::RequestState::Started() const {
return IsFlagSet(RequestStateFlags::kStarted);
}
bool URLRequest::RequestState::Finished() const {
return IsFlagSet(RequestStateFlags::kFinished);
}
bool URLRequest::RequestState::Canceled() const {
return IsFlagSet(RequestStateFlags::kCanceled);
}
bool URLRequest::RequestState::Failed() const {
return IsFlagSet(RequestStateFlags::kFailed);
}
bool URLRequest::RequestState::Closed() const {
return IsFlagSet(RequestStateFlags::kClosed);
}
URLRequest::ResponseState::ResponseState()
: StateBase(ResponseStateFlags::kNotStarted) {}
bool URLRequest::ResponseState::NotStarted() const {
return *this == ResponseStateFlags::kNotStarted;
}
bool URLRequest::ResponseState::Started() const {
return IsFlagSet(ResponseStateFlags::kStarted);
}
bool URLRequest::ResponseState::Ended() const {
return IsFlagSet(ResponseStateFlags::kEnded);
}
bool URLRequest::ResponseState::Failed() const {
return IsFlagSet(ResponseStateFlags::kFailed);
}
URLRequest::URLRequest(v8::Isolate* isolate, v8::Local<v8::Object> wrapper) {
InitWith(isolate, wrapper);
}
URLRequest::~URLRequest() {
// A request has been created in JS, it was not used and then
// it got collected, no close event to cleanup, only destructor
// is called.
if (atom_request_) {
atom_request_->Terminate();
}
}
// static
mate::WrappableBase* URLRequest::New(mate::Arguments* args) {
auto isolate = args->isolate();
v8::Local<v8::Object> options;
args->GetNext(&options);
mate::Dictionary dict(isolate, options);
std::string method;
dict.Get("method", &method);
std::string url;
dict.Get("url", &url);
std::string redirect_policy;
dict.Get("redirect", &redirect_policy);
std::string partition;
mate::Handle<api::Session> session;
if (dict.Get("session", &session)) {
} else if (dict.Get("partition", &partition)) {
session = Session::FromPartition(isolate, partition);
} else {
// Use the default session if not specified.
session = Session::FromPartition(isolate, "");
}
auto browser_context = session->browser_context();
auto api_url_request = new URLRequest(args->isolate(), args->GetThis());
auto atom_url_request = AtomURLRequest::Create(
browser_context, method, url, redirect_policy, api_url_request);
api_url_request->atom_request_ = atom_url_request;
return api_url_request;
}
// static
void URLRequest::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "URLRequest"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
// Request API
.MakeDestroyable()
.SetMethod("write", &URLRequest::Write)
.SetMethod("cancel", &URLRequest::Cancel)
.SetMethod("setExtraHeader", &URLRequest::SetExtraHeader)
.SetMethod("removeExtraHeader", &URLRequest::RemoveExtraHeader)
.SetMethod("setChunkedUpload", &URLRequest::SetChunkedUpload)
.SetMethod("followRedirect", &URLRequest::FollowRedirect)
.SetMethod("_setLoadFlags", &URLRequest::SetLoadFlags)
.SetProperty("notStarted", &URLRequest::NotStarted)
.SetProperty("finished", &URLRequest::Finished)
// Response APi
.SetProperty("statusCode", &URLRequest::StatusCode)
.SetProperty("statusMessage", &URLRequest::StatusMessage)
.SetProperty("rawResponseHeaders", &URLRequest::RawResponseHeaders)
.SetProperty("httpVersionMajor", &URLRequest::ResponseHttpVersionMajor)
.SetProperty("httpVersionMinor", &URLRequest::ResponseHttpVersionMinor);
}
bool URLRequest::NotStarted() const {
return request_state_.NotStarted();
}
bool URLRequest::Finished() const {
return request_state_.Finished();
}
bool URLRequest::Canceled() const {
return request_state_.Canceled();
}
bool URLRequest::Write(scoped_refptr<const net::IOBufferWithSize> buffer,
bool is_last) {
if (request_state_.Canceled() || request_state_.Failed() ||
request_state_.Finished() || request_state_.Closed()) {
return false;
}
if (request_state_.NotStarted()) {
request_state_.SetFlag(RequestStateFlags::kStarted);
// Pin on first write.
Pin();
}
if (is_last) {
request_state_.SetFlag(RequestStateFlags::kFinished);
EmitRequestEvent(true, "finish");
}
DCHECK(atom_request_);
if (atom_request_) {
return atom_request_->Write(buffer, is_last);
}
return false;
}
void URLRequest::Cancel() {
if (request_state_.Canceled() || request_state_.Closed()) {
// Cancel only once.
return;
}
// Mark as canceled.
request_state_.SetFlag(RequestStateFlags::kCanceled);
DCHECK(atom_request_);
if (atom_request_ && request_state_.Started()) {
// Really cancel if it was started.
atom_request_->Cancel();
}
EmitRequestEvent(true, "abort");
if (response_state_.Started() && !response_state_.Ended()) {
EmitResponseEvent(true, "aborted");
}
Close();
}
void URLRequest::FollowRedirect() {
if (request_state_.Canceled() || request_state_.Closed()) {
return;
}
DCHECK(atom_request_);
if (atom_request_) {
atom_request_->FollowRedirect();
}
}
bool URLRequest::SetExtraHeader(const std::string& name,
const std::string& value) {
// Request state must be in the initial non started state.
if (!request_state_.NotStarted()) {
// Cannot change headers after send.
return false;
}
if (!net::HttpUtil::IsValidHeaderName(name)) {
return false;
}
if (!net::HttpUtil::IsValidHeaderValue(value)) {
return false;
}
DCHECK(atom_request_);
if (atom_request_) {
atom_request_->SetExtraHeader(name, value);
}
return true;
}
void URLRequest::RemoveExtraHeader(const std::string& name) {
// State must be equal to not started.
if (!request_state_.NotStarted()) {
// Cannot change headers after send.
return;
}
DCHECK(atom_request_);
if (atom_request_) {
atom_request_->RemoveExtraHeader(name);
}
}
void URLRequest::SetChunkedUpload(bool is_chunked_upload) {
// State must be equal to not started.
if (!request_state_.NotStarted()) {
// Cannot change headers after send.
return;
}
DCHECK(atom_request_);
if (atom_request_) {
atom_request_->SetChunkedUpload(is_chunked_upload);
}
}
void URLRequest::SetLoadFlags(int flags) {
// State must be equal to not started.
if (!request_state_.NotStarted()) {
// Cannot change load flags after start.
return;
}
DCHECK(atom_request_);
if (atom_request_) {
atom_request_->SetLoadFlags(flags);
}
}
void URLRequest::OnReceivedRedirect(
int status_code,
const std::string& method,
const GURL& url,
scoped_refptr<net::HttpResponseHeaders> response_headers) {
if (request_state_.Canceled() || request_state_.Closed()) {
return;
}
DCHECK(atom_request_);
if (!atom_request_) {
return;
}
EmitRequestEvent(false, "redirect", status_code, method, url,
response_headers.get());
}
void URLRequest::OnAuthenticationRequired(
scoped_refptr<const net::AuthChallengeInfo> auth_info) {
if (request_state_.Canceled() || request_state_.Closed()) {
return;
}
DCHECK(atom_request_);
if (!atom_request_) {
return;
}
Emit("login", auth_info.get(),
base::Bind(&AtomURLRequest::PassLoginInformation, atom_request_));
}
void URLRequest::OnResponseStarted(
scoped_refptr<net::HttpResponseHeaders> response_headers) {
if (request_state_.Canceled() || request_state_.Failed() ||
request_state_.Closed()) {
// Don't emit any event after request cancel.
return;
}
response_headers_ = response_headers;
response_state_.SetFlag(ResponseStateFlags::kStarted);
Emit("response");
}
void URLRequest::OnResponseData(
scoped_refptr<const net::IOBufferWithSize> buffer) {
if (request_state_.Canceled() || request_state_.Closed() ||
request_state_.Failed() || response_state_.Failed()) {
// In case we received an unexpected event from Chromium net,
// don't emit any data event after request cancel/error/close.
return;
}
if (!buffer || !buffer->data() || !buffer->size()) {
return;
}
Emit("data", buffer);
}
void URLRequest::OnResponseCompleted() {
if (request_state_.Canceled() || request_state_.Closed() ||
request_state_.Failed() || response_state_.Failed()) {
// In case we received an unexpected event from Chromium net,
// don't emit any data event after request cancel/error/close.
return;
}
response_state_.SetFlag(ResponseStateFlags::kEnded);
Emit("end");
Close();
}
void URLRequest::OnError(const std::string& error, bool isRequestError) {
auto error_object = v8::Exception::Error(mate::StringToV8(isolate(), error));
if (isRequestError) {
request_state_.SetFlag(RequestStateFlags::kFailed);
EmitRequestEvent(false, "error", error_object);
} else {
response_state_.SetFlag(ResponseStateFlags::kFailed);
EmitResponseEvent(false, "error", error_object);
}
Close();
}
int URLRequest::StatusCode() const {
if (response_headers_) {
return response_headers_->response_code();
}
return -1;
}
std::string URLRequest::StatusMessage() const {
std::string result;
if (response_headers_) {
result = response_headers_->GetStatusText();
}
return result;
}
net::HttpResponseHeaders* URLRequest::RawResponseHeaders() const {
return response_headers_.get();
}
uint32_t URLRequest::ResponseHttpVersionMajor() const {
if (response_headers_) {
return response_headers_->GetHttpVersion().major_value();
}
return 0;
}
uint32_t URLRequest::ResponseHttpVersionMinor() const {
if (response_headers_) {
return response_headers_->GetHttpVersion().minor_value();
}
return 0;
}
void URLRequest::Close() {
if (!request_state_.Closed()) {
request_state_.SetFlag(RequestStateFlags::kClosed);
if (response_state_.Started()) {
// Emit a close event if we really have a response object.
EmitResponseEvent(true, "close");
}
EmitRequestEvent(true, "close");
}
Unpin();
if (atom_request_) {
// A request has been created in JS, used and then it ended.
// We release unneeded net resources.
atom_request_->Terminate();
}
atom_request_ = nullptr;
}
void URLRequest::Pin() {
if (wrapper_.IsEmpty()) {
wrapper_.Reset(isolate(), GetWrapper());
}
}
void URLRequest::Unpin() {
wrapper_.Reset();
}
template <typename... Args>
void URLRequest::EmitRequestEvent(Args... args) {
v8::HandleScope handle_scope(isolate());
mate::CustomEmit(isolate(), GetWrapper(), "_emitRequestEvent", args...);
}
template <typename... Args>
void URLRequest::EmitResponseEvent(Args... args) {
v8::HandleScope handle_scope(isolate());
mate::CustomEmit(isolate(), GetWrapper(), "_emitResponseEvent", args...);
}
} // namespace api
} // namespace atom

View File

@@ -1,213 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_ATOM_API_URL_REQUEST_H_
#define ATOM_BROWSER_API_ATOM_API_URL_REQUEST_H_
#include <array>
#include <string>
#include "atom/browser/api/event_emitter.h"
#include "atom/browser/api/trackable_object.h"
#include "base/memory/weak_ptr.h"
#include "native_mate/dictionary.h"
#include "native_mate/handle.h"
#include "native_mate/wrappable_base.h"
#include "net/base/auth.h"
#include "net/base/io_buffer.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_context.h"
namespace atom {
class AtomURLRequest;
namespace api {
//
// The URLRequest class implements the V8 binding between the JavaScript API
// and Chromium native net library. It is responsible for handling HTTP/HTTPS
// requests.
//
// The current class provides only the binding layer. Two other JavaScript
// classes (ClientRequest and IncomingMessage) in the net module provide the
// final API, including some state management and arguments validation.
//
// URLRequest's methods fall into two main categories: command and event
// methods. They are always executed on the Browser's UI thread.
// Command methods are called directly from JavaScript code via the API defined
// in BuildPrototype. A command method is generally implemented by forwarding
// the call to a corresponding method on AtomURLRequest which does the
// synchronization on the Browser IO thread. The latter then calls into Chromium
// net library. On the other hand, net library events originate on the IO
// thread in AtomURLRequest and are synchronized back on the UI thread, then
// forwarded to a corresponding event method in URLRequest and then to
// JavaScript via the EmitRequestEvent/EmitResponseEvent helpers.
//
// URLRequest lifetime management: we followed the Wrapper/Wrappable pattern
// defined in native_mate. However, we augment that pattern with a pin/unpin
// mechanism. The main reason is that we want the JS API to provide a similar
// lifetime guarantees as the XMLHttpRequest.
// https://xhr.spec.whatwg.org/#garbage-collection
//
// The primary motivation is to not garbage collect a URLInstance as long as the
// object is emitting network events. For instance, in the following JS code
//
// (function() {
// let request = new URLRequest(...);
// request.on('response', (response)=>{
// response.on('data', (data) = > {
// console.log(data.toString());
// });
// });
// })();
//
// we still want data to be logged even if the response/request objects are n
// more referenced in JavaScript.
//
// Binding by simply following the native_mate Wrapper/Wrappable pattern will
// delete the URLRequest object when the corresponding JS object is collected.
// The v8 handle is a private member in WrappableBase and it is always weak,
// there is no way to make it strong without changing native_mate.
// The solution we implement consists of maintaining some kind of state that
// prevents collection of JS wrappers as long as the request is emitting network
// events. At initialization, the object is unpinned. When the request starts,
// it is pinned. When no more events would be emitted, the object is unpinned
// and lifetime is again managed by the standard native mate Wrapper/Wrappable
// pattern.
//
// pin/unpin: are implemented by constructing/reseting a V8 strong persistent
// handle.
//
// The URLRequest/AtmURLRequest interaction could have been implemented in a
// single class. However, it implies that the resulting class lifetime will be
// managed by two conflicting mechanisms: JavaScript garbage collection and
// Chromium reference counting. Reasoning about lifetime issues become much
// more complex.
//
// We chose to split the implementation into two classes linked via a
// reference counted/raw pointers. A URLRequest instance is deleted if it is
// unpinned and the corresponding JS wrapper object is garbage collected. On the
// other hand, an AtmURLRequest instance lifetime is totally governed by
// reference counting.
//
class URLRequest : public mate::EventEmitter<URLRequest> {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// Methods for reporting events into JavaScript.
void OnReceivedRedirect(
int status_code,
const std::string& method,
const GURL& url,
scoped_refptr<net::HttpResponseHeaders> response_headers);
void OnAuthenticationRequired(
scoped_refptr<const net::AuthChallengeInfo> auth_info);
void OnResponseStarted(
scoped_refptr<net::HttpResponseHeaders> response_headers);
void OnResponseData(scoped_refptr<const net::IOBufferWithSize> data);
void OnResponseCompleted();
void OnError(const std::string& error, bool isRequestError);
protected:
explicit URLRequest(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
~URLRequest() override;
private:
template <typename Flags>
class StateBase {
public:
void SetFlag(Flags flag);
protected:
explicit StateBase(Flags initialState);
bool operator==(Flags flag) const;
bool IsFlagSet(Flags flag) const;
private:
Flags state_;
};
enum class RequestStateFlags {
kNotStarted = 0x0,
kStarted = 0x1,
kFinished = 0x2,
kCanceled = 0x4,
kFailed = 0x8,
kClosed = 0x10
};
class RequestState : public StateBase<RequestStateFlags> {
public:
RequestState();
bool NotStarted() const;
bool Started() const;
bool Finished() const;
bool Canceled() const;
bool Failed() const;
bool Closed() const;
};
enum class ResponseStateFlags {
kNotStarted = 0x0,
kStarted = 0x1,
kEnded = 0x2,
kFailed = 0x4
};
class ResponseState : public StateBase<ResponseStateFlags> {
public:
ResponseState();
bool NotStarted() const;
bool Started() const;
bool Ended() const;
bool Canceled() const;
bool Failed() const;
bool Closed() const;
};
bool NotStarted() const;
bool Finished() const;
bool Canceled() const;
bool Failed() const;
bool Write(scoped_refptr<const net::IOBufferWithSize> buffer, bool is_last);
void Cancel();
void FollowRedirect();
bool SetExtraHeader(const std::string& name, const std::string& value);
void RemoveExtraHeader(const std::string& name);
void SetChunkedUpload(bool is_chunked_upload);
void SetLoadFlags(int flags);
int StatusCode() const;
std::string StatusMessage() const;
net::HttpResponseHeaders* RawResponseHeaders() const;
uint32_t ResponseHttpVersionMajor() const;
uint32_t ResponseHttpVersionMinor() const;
void Close();
void Pin();
void Unpin();
template <typename... Args>
void EmitRequestEvent(Args... args);
template <typename... Args>
void EmitResponseEvent(Args... args);
scoped_refptr<AtomURLRequest> atom_request_;
RequestState request_state_;
ResponseState response_state_;
// Used to implement pin/unpin.
v8::Global<v8::Object> wrapper_;
scoped_refptr<net::HttpResponseHeaders> response_headers_;
DISALLOW_COPY_AND_ASSIGN(URLRequest);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_ATOM_API_URL_REQUEST_H_

File diff suppressed because it is too large Load Diff

View File

@@ -12,13 +12,10 @@
#include "atom/browser/api/save_page_handler.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/common_web_contents_delegate.h"
#include "atom/browser/ui/autofill_popup.h"
#include "content/common/cursors/webcursor.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/favicon_url.h"
#include "content/common/cursors/webcursor.h"
#include "native_mate/handle.h"
#include "printing/backend/print_backend.h"
#include "ui/gfx/image/image.h"
namespace blink {
@@ -29,10 +26,6 @@ namespace brightray {
class InspectableWebContents;
}
namespace content {
class ResourceRequestBodyImpl;
}
namespace mate {
class Arguments;
class Dictionary;
@@ -42,8 +35,6 @@ namespace atom {
struct SetSizeParams;
class AtomBrowserContext;
class AtomJavaScriptDialogManager;
class WebContentsZoomController;
class WebViewGuestDelegate;
namespace api {
@@ -52,15 +43,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
public CommonWebContentsDelegate,
public content::WebContentsObserver {
public:
enum Type {
BACKGROUND_PAGE, // A DevTools extension background page.
BROWSER_WINDOW, // Used by BrowserWindow.
BROWSER_VIEW, // Used by BrowserView.
REMOTE, // Thin wrap around an existing WebContents.
WEB_VIEW, // Used by <webview>.
OFF_SCREEN, // Used for offscreen rendering
};
// For node.js callback function type: function(error, buffer)
using PrintToPDFCallback =
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
@@ -68,40 +50,26 @@ class WebContents : public mate::TrackableObject<WebContents>,
// Create from an existing WebContents.
static mate::Handle<WebContents> CreateFrom(
v8::Isolate* isolate, content::WebContents* web_contents);
static mate::Handle<WebContents> CreateFrom(
v8::Isolate* isolate, content::WebContents* web_contents, Type type);
// Create a new WebContents.
static mate::Handle<WebContents> Create(
v8::Isolate* isolate, const mate::Dictionary& options);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// Notifies to destroy any guest web contents before destroying self.
void DestroyWebContents(bool async);
int64_t GetID() const;
int GetProcessID() const;
base::ProcessId GetOSProcessID() const;
Type GetType() const;
int GetID() const;
bool Equal(const WebContents* web_contents) const;
void LoadURL(const GURL& url, const mate::Dictionary& options);
void DownloadURL(const GURL& url);
GURL GetURL() const;
base::string16 GetTitle() const;
bool IsLoading() const;
bool IsLoadingMainFrame() const;
bool IsWaitingForResponse() const;
void Stop();
void ReloadIgnoringCache();
void GoBack();
void GoForward();
void GoToOffset(int offset);
const std::string GetWebRTCIPHandlingPolicy() const;
void SetWebRTCIPHandlingPolicy(const std::string& webrtc_ip_handling_policy);
bool IsCrashed() const;
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
void SetUserAgent(const std::string& user_agent);
std::string GetUserAgent();
void InsertCSS(const std::string& css);
bool SavePage(const base::FilePath& full_file_path,
@@ -116,16 +84,11 @@ class WebContents : public mate::TrackableObject<WebContents>,
void DisableDeviceEmulation();
void InspectElement(int x, int y);
void InspectServiceWorker();
void HasServiceWorker(
const base::Callback<void(bool)>&);
void HasServiceWorker(const base::Callback<void(bool)>&);
void UnregisterServiceWorker(const base::Callback<void(bool)>&);
void SetIgnoreMenuShortcuts(bool ignore);
void SetAudioMuted(bool muted);
bool IsAudioMuted();
void Print(mate::Arguments* args);
std::vector<printing::PrinterBasicInfo> GetPrinterList();
void SetEmbedder(const WebContents* embedder);
v8::Local<v8::Value> GetNativeView() const;
// Print current page as PDF.
void PrintToPDF(const base::DictionaryValue& setting,
@@ -147,119 +110,71 @@ class WebContents : public mate::TrackableObject<WebContents>,
void Unselect();
void Replace(const base::string16& word);
void ReplaceMisspelling(const base::string16& word);
uint32_t FindInPage(mate::Arguments* args);
uint32 FindInPage(mate::Arguments* args);
void StopFindInPage(content::StopFindAction action);
void ShowDefinitionForSelection();
void CopyImageAt(int x, int y);
// Focus.
void Focus();
bool IsFocused() const;
void TabTraverse(bool reverse);
// Send messages to browser.
bool SendIPCMessage(bool all_frames,
const base::string16& channel,
bool SendIPCMessage(const base::string16& channel,
const base::ListValue& args);
// Send WebInputEvent to the page.
void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);
// Subscribe to the frame updates.
void BeginFrameSubscription(mate::Arguments* args);
void BeginFrameSubscription(
const FrameSubscriber::FrameCaptureCallback& callback);
void EndFrameSubscription();
// Dragging native items.
void StartDrag(const mate::Dictionary& item, mate::Arguments* args);
// Captures the page with |rect|, |callback| would be called when capturing is
// done.
void CapturePage(mate::Arguments* args);
// Methods for creating <webview>.
void SetSize(const SetSizeParams& params);
void SetAllowTransparency(bool allow);
bool IsGuest() const;
// Methods for offscreen rendering
bool IsOffScreen() const;
bool IsOffScreenOrEmbedderOffscreen() const;
void OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap);
void StartPainting();
void StopPainting();
bool IsPainting() const;
void SetFrameRate(int frame_rate);
int GetFrameRate() const;
void Invalidate();
gfx::Size GetSizeForNewRenderView(content::WebContents*) const override;
// Methods for zoom handling.
void SetZoomLevel(double level);
double GetZoomLevel();
void SetZoomFactor(double factor);
double GetZoomFactor();
// Callback triggered on permission response.
void OnEnterFullscreenModeForTab(content::WebContents* source,
const GURL& origin,
bool allowed);
// Create window with the given disposition.
void OnCreateWindow(
const GURL& target_url,
const std::string& frame_name,
WindowOpenDisposition disposition,
const std::vector<std::string>& features,
const scoped_refptr<content::ResourceRequestBodyImpl>& body);
// Returns the web preferences of current WebContents.
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
// Returns the owner window.
v8::Local<v8::Value> GetOwnerBrowserWindow();
// Grants the child process the capability to access URLs with the origin of
// the specified URL.
void GrantOriginAccess(const GURL& url);
// Properties.
int32_t ID() const;
v8::Local<v8::Value> Session(v8::Isolate* isolate);
content::WebContents* HostWebContents();
v8::Local<v8::Value> DevToolsWebContents(v8::Isolate* isolate);
v8::Local<v8::Value> Debugger(v8::Isolate* isolate);
WebContentsZoomController* GetZoomController() { return zoom_controller_; }
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> prototype);
protected:
WebContents(v8::Isolate* isolate,
content::WebContents* web_contents,
Type type);
explicit WebContents(content::WebContents* web_contents);
WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
~WebContents();
void InitWithSessionAndOptions(v8::Isolate* isolate,
content::WebContents *web_contents,
mate::Handle<class Session> session,
const mate::Dictionary& options);
// content::WebContentsDelegate:
bool DidAddMessageToConsole(content::WebContents* source,
int32_t level,
const base::string16& message,
int32_t line_no,
const base::string16& source_id) override;
void WebContentsCreated(content::WebContents* source_contents,
int opener_render_process_id,
int opener_render_frame_id,
const std::string& frame_name,
const GURL& target_url,
content::WebContents* new_contents) override;
void AddNewContents(content::WebContents* source,
content::WebContents* new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture,
bool* was_blocked) override;
bool AddMessageToConsole(content::WebContents* source,
int32 level,
const base::string16& message,
int32 line_no,
const base::string16& source_id) override;
bool ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,
int main_frame_route_id,
WindowContainerType window_container_type,
const std::string& frame_name,
const GURL& target_url,
const std::string& partition_id,
content::SessionStorageNamespace* session_storage_namespace) override;
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
@@ -270,20 +185,14 @@ class WebContents : public mate::TrackableObject<WebContents>,
const gfx::Rect& pos) override;
void CloseContents(content::WebContents* source) override;
void ActivateContents(content::WebContents* contents) override;
void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
bool IsPopupOrPanel(const content::WebContents* source) const override;
void HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
void EnterFullscreenModeForTab(content::WebContents* source,
const GURL& origin) override;
void ExitFullscreenModeForTab(content::WebContents* source) override;
void RendererUnresponsive(
content::WebContents* source,
const content::WebContentsUnresponsiveState& unresponsive_state) override;
void RendererUnresponsive(content::WebContents* source) override;
void RendererResponsive(content::WebContents* source) override;
bool HandleContextMenu(const content::ContextMenuParams& params) override;
bool OnGoToEntryOffset(int offset) override;
@@ -305,15 +214,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
content::WebContents* web_contents,
bool user_gesture,
bool last_unlocked_by_target) override;
std::unique_ptr<content::BluetoothChooser> RunBluetoothChooser(
content::RenderFrameHost* frame,
const content::BluetoothChooser::EventHandler& handler) override;
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
content::WebContents* source) override;
// content::WebContentsObserver:
void BeforeUnloadFired(const base::TimeTicks& proceed_time) override;
void RenderViewCreated(content::RenderViewHost*) override;
void RenderViewDeleted(content::RenderViewHost*) override;
void RenderProcessGone(base::TerminationStatus status) override;
void DocumentLoadedInFrame(
@@ -325,17 +228,22 @@ class WebContents : public mate::TrackableObject<WebContents>,
int error_code,
const base::string16& error_description,
bool was_ignored_by_handler) override;
void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code,
const base::string16& error_description,
bool was_ignored_by_handler) override;
void DidStartLoading() override;
void DidStopLoading() override;
void DidGetResourceResponseStart(
const content::ResourceRequestDetails& details) override;
void DidGetRedirectForResourceRequest(
content::RenderFrameHost* render_frame_host,
const content::ResourceRedirectDetails& details) override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
void DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) override;
bool OnMessageReceived(const IPC::Message& message) override;
bool OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* frame_host) override;
void WebContentsDestroyed() override;
void NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) override;
@@ -344,24 +252,25 @@ class WebContents : public mate::TrackableObject<WebContents>,
const std::vector<content::FaviconURL>& urls) override;
void PluginCrashed(const base::FilePath& plugin_path,
base::ProcessId plugin_pid) override;
void MediaStartedPlaying(const MediaPlayerInfo& video_type,
const MediaPlayerId& id) override;
void MediaStoppedPlaying(const MediaPlayerInfo& video_type,
const MediaPlayerId& id) override;
void MediaStartedPlaying() override;
void MediaPaused() override;
void DidChangeThemeColor(SkColor theme_color) override;
// brightray::InspectableWebContentsDelegate:
void DevToolsReloadPage() override;
// brightray::InspectableWebContentsViewDelegate:
void DevToolsFocused() override;
void DevToolsOpened() override;
void DevToolsClosed() override;
private:
enum Type {
BROWSER_WINDOW, // Used by BrowserWindow.
WEB_VIEW, // Used by <webview>.
REMOTE, // Thin wrap around an existing WebContents.
};
AtomBrowserContext* GetBrowserContext() const;
uint32_t GetNextRequestId() {
uint32 GetNextRequestId() {
return ++request_id_;
}
@@ -377,38 +286,20 @@ class WebContents : public mate::TrackableObject<WebContents>,
const base::ListValue& args,
IPC::Message* message);
// Called when received a synchronous message from renderer to
// set temporary zoom level.
void OnSetTemporaryZoomLevel(double level, IPC::Message* reply_msg);
// Called when received a synchronous message from renderer to
// get the zoom level.
void OnGetZoomLevel(IPC::Message* reply_msg);
v8::Global<v8::Value> session_;
v8::Global<v8::Value> devtools_web_contents_;
v8::Global<v8::Value> debugger_;
std::unique_ptr<AtomJavaScriptDialogManager> dialog_manager_;
std::unique_ptr<WebViewGuestDelegate> guest_delegate_;
scoped_ptr<WebViewGuestDelegate> guest_delegate_;
// The host webcontents that may contain this webcontents.
WebContents* embedder_;
// The zoom controller for this webContents.
WebContentsZoomController* zoom_controller_;
// The type of current WebContents.
Type type_;
// Request id used for findInPage request.
uint32_t request_id_;
// Whether background throttling is disabled.
bool background_throttling_;
// Whether to enable devtools.
bool enable_devtools_;
uint32 request_id_;
DISALLOW_COPY_AND_ASSIGN(WebContents);
};

View File

@@ -1,30 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/atom_api_web_contents.h"
#import <Cocoa/Cocoa.h>
namespace atom {
namespace api {
bool WebContents::IsFocused() const {
auto view = web_contents()->GetRenderWidgetHostView();
if (!view) return false;
if (GetType() != BACKGROUND_PAGE) {
auto window = [web_contents()->GetNativeView() window];
// On Mac the render widget host view does not lose focus when the window
// loses focus so check if the top level window is the key window.
if (window && ![window isKeyWindow])
return false;
}
return view->HasFocus();
}
} // namespace api
} // namespace atom

View File

@@ -20,14 +20,13 @@ using content::BrowserThread;
namespace mate {
template<>
struct Converter<URLPattern> {
struct Converter<extensions::URLPattern> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
URLPattern* out) {
extensions::URLPattern* out) {
std::string pattern;
if (!ConvertFromV8(isolate, val, &pattern))
return false;
*out = URLPattern(URLPattern::SCHEME_ALL);
return out->Parse(pattern) == URLPattern::PARSE_SUCCESS;
return out->Parse(pattern) == extensions::URLPattern::PARSE_SUCCESS;
}
};
@@ -37,10 +36,8 @@ namespace atom {
namespace api {
WebRequest::WebRequest(v8::Isolate* isolate,
AtomBrowserContext* browser_context)
WebRequest::WebRequest(AtomBrowserContext* browser_context)
: browser_context_(browser_context) {
Init(isolate);
}
WebRequest::~WebRequest() {
@@ -84,14 +81,13 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
mate::Handle<WebRequest> WebRequest::Create(
v8::Isolate* isolate,
AtomBrowserContext* browser_context) {
return mate::CreateHandle(isolate, new WebRequest(isolate, browser_context));
return mate::CreateHandle(isolate, new WebRequest(browser_context));
}
// static
void WebRequest::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "WebRequest"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.SetMethod("onBeforeRequest",
&WebRequest::SetResponseListener<
AtomNetworkDelegate::kOnBeforeRequest>)

View File

@@ -21,12 +21,13 @@ class WebRequest : public mate::TrackableObject<WebRequest> {
static mate::Handle<WebRequest> Create(v8::Isolate* isolate,
AtomBrowserContext* browser_context);
// mate::TrackableObject:
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
protected:
WebRequest(v8::Isolate* isolate, AtomBrowserContext* browser_context);
~WebRequest() override;
explicit WebRequest(AtomBrowserContext* browser_context);
~WebRequest();
// C++ can not distinguish overloaded member function.
template<AtomNetworkDelegate::SimpleEvent type>

View File

@@ -2,41 +2,59 @@
// 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_web_contents.h"
#include "atom/browser/web_contents_preferences.h"
#include "atom/browser/web_contents_zoom_controller.h"
#include "atom/browser/web_view_manager.h"
#include "atom/common/native_mate_converters/content_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "atom/common/options_switches.h"
#include "content/public/browser/browser_context.h"
#include "native_mate/dictionary.h"
using atom::WebContentsPreferences;
namespace mate {
template<>
struct Converter<content::WebContents*> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
content::WebContents** out) {
atom::api::WebContents* contents;
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
return false;
*out = contents->web_contents();
return true;
}
};
} // namespace mate
namespace {
atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) {
auto context = web_contents->GetBrowserContext();
if (context) {
auto manager = context->GetGuestManager();
return static_cast<atom::WebViewManager*>(manager);
} else {
return nullptr;
}
}
void AddGuest(int guest_instance_id,
int element_instance_id,
content::WebContents* embedder,
content::WebContents* guest_web_contents,
const base::DictionaryValue& options) {
auto manager = atom::WebViewManager::GetWebViewManager(embedder);
auto manager = GetWebViewManager(embedder);
if (manager)
manager->AddGuest(guest_instance_id, element_instance_id, embedder,
guest_web_contents);
double zoom_factor;
if (options.GetDouble(atom::options::kZoomFactor, &zoom_factor)) {
atom::WebContentsZoomController::FromWebContents(guest_web_contents)
->SetDefaultZoomFactor(zoom_factor);
}
WebContentsPreferences::FromWebContents(guest_web_contents)->Merge(options);
}
void RemoveGuest(content::WebContents* embedder, int guest_instance_id) {
auto manager = atom::WebViewManager::GetWebViewManager(embedder);
auto manager = GetWebViewManager(embedder);
if (manager)
manager->RemoveGuest(guest_instance_id);
}

View File

@@ -5,38 +5,27 @@
#include "atom/browser/api/atom_api_window.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/browser/api/atom_api_browser_view.h"
#include "atom/browser/api/atom_api_menu.h"
#include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/browser.h"
#include "atom/browser/native_window.h"
#include "atom/browser/web_contents_preferences.h"
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/file_path_converter.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/node_includes.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "native_mate/constructor.h"
#include "native_mate/dictionary.h"
#include "ui/gfx/geometry/rect.h"
#if defined(TOOLKIT_VIEWS)
#include "atom/browser/native_window_views.h"
#endif
#if defined(OS_WIN)
#include "atom/browser/native_window_views.h"
#include "atom/browser/ui/win/taskbar_host.h"
#include "ui/base/win/shell.h"
#endif
#include "atom/common/node_includes.h"
#if defined(OS_WIN)
namespace mate {
@@ -63,6 +52,61 @@ namespace api {
namespace {
void OnCapturePageDone(
v8::Isolate* isolate,
const base::Callback<void(const gfx::Image&)>& callback,
const SkBitmap& bitmap) {
v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
}
// Converts min-width to minWidth, returns false if no conversion is needed.
bool TranslateOldKey(const std::string& key, std::string* new_key) {
if (key.find('-') == std::string::npos)
return false;
new_key->reserve(key.size());
bool next_upper_case = false;
for (char c : key) {
if (c == '-') {
next_upper_case = true;
} else if (next_upper_case) {
new_key->push_back(base::ToUpperASCII(c));
next_upper_case = false;
} else {
new_key->push_back(c);
}
}
return true;
}
// Converts min-width to minWidth recursively in the dictionary.
void TranslateOldOptions(v8::Isolate* isolate, v8::Local<v8::Object> options) {
auto context = isolate->GetCurrentContext();
auto maybe_keys = options->GetOwnPropertyNames(context);
if (maybe_keys.IsEmpty())
return;
std::vector<std::string> keys;
if (!mate::ConvertFromV8(isolate, maybe_keys.ToLocalChecked(), &keys))
return;
mate::Dictionary dict(isolate, options);
for (const auto& key : keys) {
v8::Local<v8::Value> value;
if (!dict.Get(key, &value)) // Shouldn't happen, but guard it anyway.
continue;
// Go recursively.
v8::Local<v8::Object> sub_options;
if (mate::ConvertFromV8(isolate, value, &sub_options))
TranslateOldOptions(isolate, sub_options);
// Translate key.
std::string new_key;
if (TranslateOldKey(key, &new_key)) {
dict.Set(new_key, value);
dict.Delete(key);
}
}
}
// Converts binary data to Buffer.
v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
auto buffer = node::Buffer::Copy(isolate, static_cast<char*>(val), size);
@@ -75,93 +119,39 @@ v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
} // namespace
Window::Window(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
const mate::Dictionary& options) {
mate::Handle<class WebContents> web_contents;
Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
// Be compatible with old style field names like min-width.
TranslateOldOptions(isolate, options.GetHandle());
// Use options.webPreferences in WebContents.
// Use options.webPreferences to create WebContents.
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
// Copy the backgroundColor to webContents.
// Be compatible with old options which are now in web_preferences.
v8::Local<v8::Value> value;
if (options.Get(options::kBackgroundColor, &value))
web_preferences.Set(options::kBackgroundColor, value);
if (options.Get(options::kNodeIntegration, &value))
web_preferences.Set(options::kNodeIntegration, value);
if (options.Get(options::kPreloadScript, &value))
web_preferences.Set(options::kPreloadScript, value);
if (options.Get(options::kZoomFactor, &value))
web_preferences.Set(options::kZoomFactor, value);
v8::Local<v8::Value> transparent;
if (options.Get("transparent", &transparent))
web_preferences.Set("transparent", transparent);
#if defined(ENABLE_OSR)
// Offscreen windows are always created frameless.
bool offscreen;
if (web_preferences.Get("offscreen", &offscreen) && offscreen) {
auto window_options = const_cast<mate::Dictionary&>(options);
window_options.Set(options::kFrame, false);
}
#endif
if (options.Get("webContents", &web_contents)) {
// Set webPreferences from options if using an existing webContents.
// These preferences will be used when the webContent launches new
// render processes.
auto* existing_preferences =
WebContentsPreferences::FromWebContents(web_contents->web_contents());
base::DictionaryValue web_preferences_dict;
if (mate::ConvertFromV8(isolate, web_preferences.GetHandle(),
&web_preferences_dict)) {
existing_preferences->web_preferences()->Clear();
existing_preferences->Merge(web_preferences_dict);
}
} else {
// Creates the WebContents used by BrowserWindow.
web_contents = WebContents::Create(isolate, web_preferences);
}
Init(isolate, wrapper, options, web_contents);
}
void Window::Init(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options,
mate::Handle<class WebContents> web_contents) {
// Creates the WebContents used by BrowserWindow.
auto web_contents = WebContents::Create(isolate, web_preferences);
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
// Keep a copy of the options for later use.
mate::Dictionary(isolate, web_contents->GetWrapper()).Set(
mate::Dictionary(isolate, web_contents->GetWrapper(isolate)).Set(
"browserWindowOptions", options);
// The parent window.
mate::Handle<Window> parent;
if (options.Get("parent", &parent))
parent_window_.Reset(isolate, parent.ToV8());
// Creates BrowserWindow.
window_.reset(NativeWindow::Create(
web_contents->managed_web_contents(),
options,
parent.IsEmpty() ? nullptr : parent->window_.get()));
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(),
options));
web_contents->SetOwnerWindow(window_.get());
#if defined(TOOLKIT_VIEWS)
// Sets the window icon.
mate::Handle<NativeImage> icon;
if (options.Get(options::kIcon, &icon))
SetIcon(icon);
#endif
window_->InitFromOptions(options);
window_->AddObserver(this);
InitWith(isolate, wrapper);
AttachAsUserData(window_.get());
// We can only append this window to parent window's child windows after this
// window's JS wrapper gets initialized.
if (!parent.IsEmpty())
parent->child_windows_.Set(isolate, ID(), wrapper);
}
Window::~Window() {
@@ -170,26 +160,15 @@ Window::~Window() {
// Destroy the native window in next tick because the native code might be
// iterating all windows.
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release());
base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
}
void Window::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close");
}
void Window::WillDestroyNativeObject() {
// Close all child windows before closing current window.
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
for (v8::Local<v8::Value> value : child_windows_.Values(isolate())) {
mate::Handle<Window> child;
if (mate::ConvertFromV8(isolate(), value, &child))
child->window_->CloseImmediately();
}
}
void Window::OnWindowClosed() {
api_web_contents_->DestroyWebContents(true /* async */);
api_web_contents_->DestroyWebContents();
RemoveFromWeakMap();
window_->RemoveObserver(this);
@@ -200,17 +179,8 @@ void Window::OnWindowClosed() {
Emit("closed");
RemoveFromParentChildWindows();
ResetBrowserView();
// Destroy the native class when window is closed.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, GetDestroyClosure());
}
void Window::OnWindowEndSession() {
Emit("session-end");
base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure());
}
void Window::OnWindowBlur() {
@@ -229,10 +199,6 @@ void Window::OnWindowHide() {
Emit("hide");
}
void Window::OnReadyToShow() {
Emit("ready-to-show");
}
void Window::OnWindowMaximize() {
Emit("maximize");
}
@@ -277,22 +243,6 @@ void Window::OnWindowScrollTouchEnd() {
Emit("scroll-touch-end");
}
void Window::OnWindowScrollTouchEdge() {
Emit("scroll-touch-edge");
}
void Window::OnWindowSwipe(const std::string& direction) {
Emit("swipe", direction);
}
void Window::OnWindowSheetBegin() {
Emit("sheet-begin");
}
void Window::OnWindowSheetEnd() {
Emit("sheet-end");
}
void Window::OnWindowEnterHtmlFullScreen() {
Emit("enter-html-full-screen");
}
@@ -313,15 +263,6 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) {
Emit("app-command", command_name);
}
void Window::OnTouchBarItemResult(const std::string& item_id,
const base::DictionaryValue& details) {
Emit("-touch-bar-interaction", item_id, details);
}
void Window::OnNewWindowForTab() {
Emit("new-window-for-tab");
}
#if defined(OS_WIN)
void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
if (IsWindowMessageHooked(message)) {
@@ -333,9 +274,10 @@ void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
#endif
// static
mate::WrappableBase* Window::New(mate::Arguments* args) {
mate::Wrappable* Window::New(v8::Isolate* isolate, mate::Arguments* args) {
if (!Browser::Get()->is_ready()) {
args->ThrowError("Cannot create BrowserWindow before app is ready");
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
isolate, "Cannot create BrowserWindow before app is ready")));
return nullptr;
}
@@ -346,10 +288,10 @@ mate::WrappableBase* Window::New(mate::Arguments* args) {
mate::Dictionary options;
if (!(args->Length() == 1 && args->GetNext(&options))) {
options = mate::Dictionary::CreateEmpty(args->isolate());
options = mate::Dictionary::CreateEmpty(isolate);
}
return new Window(args->isolate(), args->GetThis(), options);
return new Window(isolate, options);
}
void Window::Close() {
@@ -373,10 +315,6 @@ void Window::Show() {
}
void Window::ShowInactive() {
// This method doesn't make sense for modal window..
if (IsModal())
return;
window_->ShowInactive();
}
@@ -388,10 +326,6 @@ bool Window::IsVisible() {
return window_->IsVisible();
}
bool Window::IsEnabled() {
return window_->IsEnabled();
}
void Window::Maximize() {
window_->Maximize();
}
@@ -434,16 +368,6 @@ gfx::Rect Window::GetBounds() {
return window_->GetBounds();
}
void Window::SetContentBounds(const gfx::Rect& bounds, mate::Arguments* args) {
bool animate = false;
args->GetNext(&animate);
window_->SetContentBounds(bounds, animate);
}
gfx::Rect Window::GetContentBounds() {
return window_->GetContentBounds();
}
void Window::SetSize(int width, int height, mate::Arguments* args) {
bool animate = false;
args->GetNext(&animate);
@@ -496,12 +420,6 @@ std::vector<int> Window::GetMaximumSize() {
return result;
}
void Window::SetSheetOffset(double offsetY, mate::Arguments* args) {
double offsetX = 0.0;
args->GetNext(&offsetX);
window_->SetSheetOffset(offsetX, offsetY);
}
void Window::SetResizable(bool resizable) {
window_->SetResizable(resizable);
}
@@ -550,19 +468,8 @@ bool Window::IsClosable() {
return window_->IsClosable();
}
void Window::SetAlwaysOnTop(bool top, mate::Arguments* args) {
std::string level = "floating";
int relativeLevel = 0;
std::string error;
args->GetNext(&level);
args->GetNext(&relativeLevel);
window_->SetAlwaysOnTop(top, level, relativeLevel, &error);
if (!error.empty()) {
args->ThrowError(error);
}
void Window::SetAlwaysOnTop(bool top) {
window_->SetAlwaysOnTop(top);
}
bool Window::IsAlwaysOnTop() {
@@ -603,14 +510,6 @@ void Window::SetSkipTaskbar(bool skip) {
window_->SetSkipTaskbar(skip);
}
void Window::SetSimpleFullScreen(bool simple_fullscreen) {
window_->SetSimpleFullScreen(simple_fullscreen);
}
bool Window::IsSimpleFullScreen() {
return window_->IsSimpleFullScreen();
}
void Window::SetKiosk(bool kiosk) {
window_->SetKiosk(kiosk);
}
@@ -631,14 +530,6 @@ bool Window::HasShadow() {
return window_->HasShadow();
}
void Window::SetOpacity(const double opacity) {
window_->SetOpacity(opacity);
}
double Window::GetOpacity() {
return window_->GetOpacity();
}
void Window::FocusOnWebView() {
window_->FocusOnWebView();
}
@@ -667,39 +558,27 @@ bool Window::IsDocumentEdited() {
return window_->IsDocumentEdited();
}
void Window::SetIgnoreMouseEvents(bool ignore, mate::Arguments* args) {
mate::Dictionary options;
bool forward = false;
args->GetNext(&options) && options.Get("forward", &forward);
return window_->SetIgnoreMouseEvents(ignore, forward);
void Window::SetIgnoreMouseEvents(bool ignore) {
return window_->SetIgnoreMouseEvents(ignore);
}
void Window::SetContentProtection(bool enable) {
return window_->SetContentProtection(enable);
}
void Window::CapturePage(mate::Arguments* args) {
gfx::Rect rect;
base::Callback<void(const gfx::Image&)> callback;
void Window::SetFocusable(bool focusable) {
return window_->SetFocusable(focusable);
}
void Window::SetProgressBar(double progress, mate::Arguments* args) {
mate::Dictionary options;
std::string mode;
NativeWindow::ProgressState state = NativeWindow::PROGRESS_NORMAL;
args->GetNext(&options) && options.Get("mode", &mode);
if (mode == "error") {
state = NativeWindow::PROGRESS_ERROR;
} else if (mode == "paused") {
state = NativeWindow::PROGRESS_PAUSED;
} else if (mode == "indeterminate") {
state = NativeWindow::PROGRESS_INDETERMINATE;
} else if (mode == "none") {
state = NativeWindow::PROGRESS_NONE;
if (!(args->Length() == 1 && args->GetNext(&callback)) &&
!(args->Length() == 2 && args->GetNext(&rect)
&& args->GetNext(&callback))) {
args->ThrowError();
return;
}
window_->SetProgressBar(progress, state);
window_->CapturePage(
rect, base::Bind(&OnCapturePageDone, args->isolate(), callback));
}
void Window::SetProgressBar(double progress) {
window_->SetProgressBar(progress);
}
void Window::SetOverlayIcon(const gfx::Image& overlay,
@@ -716,7 +595,7 @@ bool Window::SetThumbarButtons(mate::Arguments* args) {
}
auto window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbarButtons(
window_->GetAcceleratedWidget(), buttons);
window->GetAcceleratedWidget(), buttons);
#else
return false;
#endif
@@ -775,49 +654,11 @@ bool Window::IsWindowMessageHooked(UINT message) {
void Window::UnhookAllWindowMessages() {
messages_callback_map_.clear();
}
bool Window::SetThumbnailClip(const gfx::Rect& region) {
auto window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbnailClip(
window_->GetAcceleratedWidget(), region);
}
bool Window::SetThumbnailToolTip(const std::string& tooltip) {
auto window = static_cast<NativeWindowViews*>(window_.get());
return window->taskbar_host().SetThumbnailToolTip(
window_->GetAcceleratedWidget(), tooltip);
}
void Window::SetAppDetails(const mate::Dictionary& options) {
base::string16 app_id;
base::FilePath app_icon_path;
int app_icon_index = 0;
base::string16 relaunch_command;
base::string16 relaunch_display_name;
options.Get("appId", &app_id);
options.Get("appIconPath", &app_icon_path);
options.Get("appIconIndex", &app_icon_index);
options.Get("relaunchCommand", &relaunch_command);
options.Get("relaunchDisplayName", &relaunch_display_name);
ui::win::SetAppDetailsForWindow(
app_id, app_icon_path, app_icon_index,
relaunch_command, relaunch_display_name,
window_->GetAcceleratedWidget());
}
#endif
#if defined(TOOLKIT_VIEWS)
void Window::SetIcon(mate::Handle<NativeImage> icon) {
#if defined(OS_WIN)
static_cast<NativeWindowViews*>(window_.get())->SetIcon(
icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
icon->GetHICON(GetSystemMetrics(SM_CXICON)));
#elif defined(USE_X11)
static_cast<NativeWindowViews*>(window_.get())->SetIcon(
icon->image().AsImageSkia());
#endif
#if defined(OS_MACOSX)
void Window::ShowDefinitionForSelection() {
window_->ShowDefinitionForSelection();
}
#endif
@@ -827,87 +668,6 @@ void Window::SetAspectRatio(double aspect_ratio, mate::Arguments* args) {
window_->SetAspectRatio(aspect_ratio, extra_size);
}
void Window::PreviewFile(const std::string& path, mate::Arguments* args) {
std::string display_name;
if (!args->GetNext(&display_name))
display_name = path;
window_->PreviewFile(path, display_name);
}
void Window::CloseFilePreview() {
window_->CloseFilePreview();
}
void Window::SetParentWindow(v8::Local<v8::Value> value,
mate::Arguments* args) {
if (IsModal()) {
args->ThrowError("Can not be called for modal window");
return;
}
mate::Handle<Window> parent;
if (value->IsNull()) {
RemoveFromParentChildWindows();
parent_window_.Reset();
window_->SetParentWindow(nullptr);
} else if (mate::ConvertFromV8(isolate(), value, &parent)) {
parent_window_.Reset(isolate(), value);
window_->SetParentWindow(parent->window_.get());
parent->child_windows_.Set(isolate(), ID(), GetWrapper());
} else {
args->ThrowError("Must pass BrowserWindow instance or null");
}
}
v8::Local<v8::Value> Window::GetParentWindow() const {
if (parent_window_.IsEmpty())
return v8::Null(isolate());
else
return v8::Local<v8::Value>::New(isolate(), parent_window_);
}
std::vector<v8::Local<v8::Object>> Window::GetChildWindows() const {
return child_windows_.Values(isolate());
}
v8::Local<v8::Value> Window::GetBrowserView() const {
if (browser_view_.IsEmpty()) {
return v8::Null(isolate());
}
return v8::Local<v8::Value>::New(isolate(), browser_view_);
}
void Window::SetBrowserView(v8::Local<v8::Value> value) {
ResetBrowserView();
mate::Handle<BrowserView> browser_view;
if (value->IsNull()) {
window_->SetBrowserView(nullptr);
} else if (mate::ConvertFromV8(isolate(), value, &browser_view)) {
window_->SetBrowserView(browser_view->view());
browser_view->web_contents()->SetOwnerWindow(window_.get());
browser_view_.Reset(isolate(), value);
}
}
void Window::ResetBrowserView() {
if (browser_view_.IsEmpty()) {
return;
}
mate::Handle<BrowserView> browser_view;
if (mate::ConvertFromV8(isolate(), GetBrowserView(), &browser_view)) {
browser_view->web_contents()->SetOwnerWindow(nullptr);
}
browser_view_.Reset();
}
bool Window::IsModal() const {
return window_->is_modal();
}
v8::Local<v8::Value> Window::GetNativeWindowHandle() {
gfx::AcceleratedWidget handle = window_->GetAcceleratedWidget();
return ToBuffer(
@@ -922,81 +682,21 @@ bool Window::IsVisibleOnAllWorkspaces() {
return window_->IsVisibleOnAllWorkspaces();
}
void Window::SetAutoHideCursor(bool auto_hide) {
window_->SetAutoHideCursor(auto_hide);
}
void Window::SelectPreviousTab() {
window_->SelectPreviousTab();
}
void Window::SelectNextTab() {
window_->SelectNextTab();
}
void Window::MergeAllWindows() {
window_->MergeAllWindows();
}
void Window::MoveTabToNewWindow() {
window_->MoveTabToNewWindow();
}
void Window::ToggleTabBar() {
window_->ToggleTabBar();
}
void Window::AddTabbedWindow(NativeWindow* window) {
window_->AddTabbedWindow(window);
}
void Window::SetVibrancy(mate::Arguments* args) {
std::string type;
args->GetNext(&type);
window_->SetVibrancy(type);
}
void Window::SetTouchBar(const std::vector<mate::PersistentDictionary>& items) {
window_->SetTouchBar(items);
}
void Window::RefreshTouchBarItem(const std::string& item_id) {
window_->RefreshTouchBarItem(item_id);
}
void Window::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) {
window_->SetEscapeTouchBarItem(item);
}
int32_t Window::ID() const {
return weak_map_id();
}
v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
if (web_contents_.IsEmpty()) {
if (web_contents_.IsEmpty())
return v8::Null(isolate);
}
return v8::Local<v8::Value>::New(isolate, web_contents_);
}
void Window::RemoveFromParentChildWindows() {
if (parent_window_.IsEmpty())
return;
mate::Handle<Window> parent;
if (!mate::ConvertFromV8(isolate(), GetParentWindow(), &parent))
return;
parent->child_windows_.Remove(ID());
else
return v8::Local<v8::Value>::New(isolate, web_contents_);
}
// static
void Window::BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "BrowserWindow"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
v8::Local<v8::ObjectTemplate> prototype) {
mate::ObjectTemplateBuilder(isolate, prototype)
.MakeDestroyable()
.SetMethod("close", &Window::Close)
.SetMethod("focus", &Window::Focus)
@@ -1006,7 +706,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("showInactive", &Window::ShowInactive)
.SetMethod("hide", &Window::Hide)
.SetMethod("isVisible", &Window::IsVisible)
.SetMethod("isEnabled", &Window::IsEnabled)
.SetMethod("maximize", &Window::Maximize)
.SetMethod("unmaximize", &Window::Unmaximize)
.SetMethod("isMaximized", &Window::IsMaximized)
@@ -1016,30 +715,17 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setFullScreen", &Window::SetFullScreen)
.SetMethod("isFullScreen", &Window::IsFullscreen)
.SetMethod("setAspectRatio", &Window::SetAspectRatio)
.SetMethod("previewFile", &Window::PreviewFile)
.SetMethod("closeFilePreview", &Window::CloseFilePreview)
#if !defined(OS_WIN)
.SetMethod("setParentWindow", &Window::SetParentWindow)
#endif
.SetMethod("getParentWindow", &Window::GetParentWindow)
.SetMethod("getChildWindows", &Window::GetChildWindows)
.SetMethod("getBrowserView", &Window::GetBrowserView)
.SetMethod("setBrowserView", &Window::SetBrowserView)
.SetMethod("isModal", &Window::IsModal)
.SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle)
.SetMethod("getBounds", &Window::GetBounds)
.SetMethod("setBounds", &Window::SetBounds)
.SetMethod("getSize", &Window::GetSize)
.SetMethod("setSize", &Window::SetSize)
.SetMethod("getContentBounds", &Window::GetContentBounds)
.SetMethod("setContentBounds", &Window::SetContentBounds)
.SetMethod("getContentSize", &Window::GetContentSize)
.SetMethod("setContentSize", &Window::SetContentSize)
.SetMethod("setMinimumSize", &Window::SetMinimumSize)
.SetMethod("getMinimumSize", &Window::GetMinimumSize)
.SetMethod("setMaximumSize", &Window::SetMaximumSize)
.SetMethod("getMaximumSize", &Window::GetMaximumSize)
.SetMethod("setSheetOffset", &Window::SetSheetOffset)
.SetMethod("setResizable", &Window::SetResizable)
.SetMethod("isResizable", &Window::IsResizable)
.SetMethod("setMovable", &Window::SetMovable)
@@ -1061,25 +747,20 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("getTitle", &Window::GetTitle)
.SetMethod("flashFrame", &Window::FlashFrame)
.SetMethod("setSkipTaskbar", &Window::SetSkipTaskbar)
.SetMethod("setSimpleFullScreen", &Window::SetSimpleFullScreen)
.SetMethod("isSimpleFullScreen", &Window::IsSimpleFullScreen)
.SetMethod("setKiosk", &Window::SetKiosk)
.SetMethod("isKiosk", &Window::IsKiosk)
.SetMethod("setBackgroundColor", &Window::SetBackgroundColor)
.SetMethod("setHasShadow", &Window::SetHasShadow)
.SetMethod("hasShadow", &Window::HasShadow)
.SetMethod("setOpacity", &Window::SetOpacity)
.SetMethod("getOpacity", &Window::GetOpacity)
.SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
.SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
.SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents)
.SetMethod("setContentProtection", &Window::SetContentProtection)
.SetMethod("setFocusable", &Window::SetFocusable)
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
.SetMethod("blurWebView", &Window::BlurWebView)
.SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
.SetMethod("capturePage", &Window::CapturePage)
.SetMethod("setProgressBar", &Window::SetProgressBar)
.SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
.SetMethod("setThumbarButtons", &Window::SetThumbarButtons)
@@ -1092,30 +773,15 @@ void Window::BuildPrototype(v8::Isolate* isolate,
&Window::SetVisibleOnAllWorkspaces)
.SetMethod("isVisibleOnAllWorkspaces",
&Window::IsVisibleOnAllWorkspaces)
#if defined(OS_MACOSX)
.SetMethod("setAutoHideCursor", &Window::SetAutoHideCursor)
.SetMethod("mergeAllWindows", &Window::MergeAllWindows)
.SetMethod("selectPreviousTab", &Window::SelectPreviousTab)
.SetMethod("selectNextTab", &Window::SelectNextTab)
.SetMethod("moveTabToNewWindow", &Window::MoveTabToNewWindow)
.SetMethod("toggleTabBar", &Window::ToggleTabBar)
.SetMethod("addTabbedWindow", &Window::AddTabbedWindow)
#endif
.SetMethod("setVibrancy", &Window::SetVibrancy)
.SetMethod("_setTouchBarItems", &Window::SetTouchBar)
.SetMethod("_refreshTouchBarItem", &Window::RefreshTouchBarItem)
.SetMethod("_setEscapeTouchBarItem", &Window::SetEscapeTouchBarItem)
#if defined(OS_WIN)
.SetMethod("hookWindowMessage", &Window::HookWindowMessage)
.SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
.SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage)
.SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages)
.SetMethod("setThumbnailClip", &Window::SetThumbnailClip)
.SetMethod("setThumbnailToolTip", &Window::SetThumbnailToolTip)
.SetMethod("setAppDetails", &Window::SetAppDetails)
#endif
#if defined(TOOLKIT_VIEWS)
.SetMethod("setIcon", &Window::SetIcon)
#if defined(OS_MACOSX)
.SetMethod("showDefinitionForSelection",
&Window::ShowDefinitionForSelection)
#endif
.SetProperty("id", &Window::ID)
.SetProperty("webContents", &Window::WebContents);
@@ -1126,7 +792,7 @@ v8::Local<v8::Value> Window::From(v8::Isolate* isolate,
NativeWindow* native_window) {
auto existing = TrackableObject::FromWrappedClass(isolate, native_window);
if (existing)
return existing->GetWrapper();
return existing->GetWrapper(isolate);
else
return v8::Null(isolate);
}
@@ -1143,10 +809,9 @@ using atom::api::Window;
void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
v8::Isolate* isolate = context->GetIsolate();
Window::SetConstructor(isolate, base::Bind(&Window::New));
mate::Dictionary browser_window(
isolate, Window::GetConstructor(isolate)->GetFunction());
v8::Local<v8::Function> constructor = mate::CreateConstructor<Window>(
isolate, "BrowserWindow", base::Bind(&Window::New));
mate::Dictionary browser_window(isolate, constructor);
browser_window.SetMethod("fromId",
&mate::TrackableObject<Window>::FromWeakMapID);
browser_window.SetMethod("getAllWindows",

View File

@@ -6,18 +6,15 @@
#define ATOM_BROWSER_API_ATOM_API_WINDOW_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/image/image.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/native_window.h"
#include "atom/browser/native_window_observer.h"
#include "atom/common/api/atom_api_native_image.h"
#include "atom/common/key_weak_map.h"
#include "native_mate/handle.h"
#include "native_mate/persistent_dictionary.h"
#include "ui/gfx/image/image.h"
class GURL;
@@ -41,10 +38,10 @@ class WebContents;
class Window : public mate::TrackableObject<Window>,
public NativeWindowObserver {
public:
static mate::WrappableBase* New(mate::Arguments* args);
static mate::Wrappable* New(v8::Isolate* isolate, mate::Arguments* args);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
v8::Local<v8::ObjectTemplate> prototype);
// Returns the BrowserWindow object from |native_window|.
static v8::Local<v8::Value> From(v8::Isolate* isolate,
@@ -52,23 +49,17 @@ class Window : public mate::TrackableObject<Window>,
NativeWindow* window() const { return window_.get(); }
int32_t ID() const;
protected:
Window(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
const mate::Dictionary& options);
~Window() override;
Window(v8::Isolate* isolate, const mate::Dictionary& options);
virtual ~Window();
// NativeWindowObserver:
void WillCloseWindow(bool* prevent_default) override;
void WillDestroyNativeObject() override;
void OnWindowClosed() override;
void OnWindowEndSession() override;
void OnWindowBlur() override;
void OnWindowFocus() override;
void OnWindowShow() override;
void OnWindowHide() override;
void OnReadyToShow() override;
void OnWindowMaximize() override;
void OnWindowUnmaximize() override;
void OnWindowMinimize() override;
@@ -78,10 +69,6 @@ class Window : public mate::TrackableObject<Window>,
void OnWindowMoved() override;
void OnWindowScrollTouchBegin() override;
void OnWindowScrollTouchEnd() override;
void OnWindowScrollTouchEdge() override;
void OnWindowSwipe(const std::string& direction) override;
void OnWindowSheetBegin() override;
void OnWindowSheetEnd() override;
void OnWindowEnterFullScreen() override;
void OnWindowLeaveFullScreen() override;
void OnWindowEnterHtmlFullScreen() override;
@@ -89,19 +76,12 @@ class Window : public mate::TrackableObject<Window>,
void OnRendererUnresponsive() override;
void OnRendererResponsive() override;
void OnExecuteWindowsCommand(const std::string& command_name) override;
void OnTouchBarItemResult(const std::string& item_id,
const base::DictionaryValue& details) override;
void OnNewWindowForTab() override;
#if defined(OS_WIN)
void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override;
#endif
private:
void Init(v8::Isolate* isolate,
v8::Local<v8::Object> wrapper,
const mate::Dictionary& options,
mate::Handle<class WebContents> web_contents);
// APIs for NativeWindow.
void Close();
void Focus();
@@ -111,7 +91,6 @@ class Window : public mate::TrackableObject<Window>,
void ShowInactive();
void Hide();
bool IsVisible();
bool IsEnabled();
void Maximize();
void Unmaximize();
bool IsMaximized();
@@ -126,13 +105,10 @@ class Window : public mate::TrackableObject<Window>,
std::vector<int> GetSize();
void SetContentSize(int width, int height, mate::Arguments* args);
std::vector<int> GetContentSize();
void SetContentBounds(const gfx::Rect& bounds, mate::Arguments* args);
gfx::Rect GetContentBounds();
void SetMinimumSize(int width, int height);
std::vector<int> GetMinimumSize();
void SetMaximumSize(int width, int height);
std::vector<int> GetMaximumSize();
void SetSheetOffset(double offsetY, mate::Arguments* args);
void SetResizable(bool resizable);
bool IsResizable();
void SetMovable(bool movable);
@@ -145,7 +121,7 @@ class Window : public mate::TrackableObject<Window>,
bool IsFullScreenable();
void SetClosable(bool closable);
bool IsClosable();
void SetAlwaysOnTop(bool top, mate::Arguments* args);
void SetAlwaysOnTop(bool top);
bool IsAlwaysOnTop();
void Center();
void SetPosition(int x, int y, mate::Arguments* args);
@@ -154,15 +130,11 @@ class Window : public mate::TrackableObject<Window>,
std::string GetTitle();
void FlashFrame(bool flash);
void SetSkipTaskbar(bool skip);
void SetSimpleFullScreen(bool simple_fullscreen);
bool IsSimpleFullScreen();
void SetKiosk(bool kiosk);
bool IsKiosk();
void SetBackgroundColor(const std::string& color_name);
void SetHasShadow(bool has_shadow);
bool HasShadow();
void SetOpacity(const double opacity);
double GetOpacity();
void FocusOnWebView();
void BlurWebView();
bool IsWebViewFocused();
@@ -170,10 +142,9 @@ class Window : public mate::TrackableObject<Window>,
std::string GetRepresentedFilename();
void SetDocumentEdited(bool edited);
bool IsDocumentEdited();
void SetIgnoreMouseEvents(bool ignore, mate::Arguments* args);
void SetContentProtection(bool enable);
void SetFocusable(bool focusable);
void SetProgressBar(double progress, mate::Arguments* args);
void SetIgnoreMouseEvents(bool ignore);
void CapturePage(mate::Arguments* args);
void SetProgressBar(double progress);
void SetOverlayIcon(const gfx::Image& overlay,
const std::string& description);
bool SetThumbarButtons(mate::Arguments* args);
@@ -183,15 +154,6 @@ class Window : public mate::TrackableObject<Window>,
void SetMenuBarVisibility(bool visible);
bool IsMenuBarVisible();
void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
void PreviewFile(const std::string& path, mate::Arguments* args);
void CloseFilePreview();
void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
v8::Local<v8::Value> GetParentWindow() const;
std::vector<v8::Local<v8::Object>> GetChildWindows() const;
v8::Local<v8::Value> GetBrowserView() const;
void SetBrowserView(v8::Local<v8::Value> value);
void ResetBrowserView();
bool IsModal() const;
v8::Local<v8::Value> GetNativeWindowHandle();
#if defined(OS_WIN)
@@ -202,51 +164,29 @@ class Window : public mate::TrackableObject<Window>,
bool IsWindowMessageHooked(UINT message);
void UnhookWindowMessage(UINT message);
void UnhookAllWindowMessages();
bool SetThumbnailClip(const gfx::Rect& region);
bool SetThumbnailToolTip(const std::string& tooltip);
void SetAppDetails(const mate::Dictionary& options);
#endif
#if defined(TOOLKIT_VIEWS)
void SetIcon(mate::Handle<NativeImage> icon);
#if defined(OS_MACOSX)
void ShowDefinitionForSelection();
#endif
void SetVisibleOnAllWorkspaces(bool visible);
bool IsVisibleOnAllWorkspaces();
void SetAutoHideCursor(bool auto_hide);
void SelectPreviousTab();
void SelectNextTab();
void MergeAllWindows();
void MoveTabToNewWindow();
void ToggleTabBar();
void AddTabbedWindow(NativeWindow* window);
void SetVibrancy(mate::Arguments* args);
void SetTouchBar(const std::vector<mate::PersistentDictionary>& items);
void RefreshTouchBarItem(const std::string& item_id);
void SetEscapeTouchBarItem(const mate::PersistentDictionary& item);
int32_t ID() const;
v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
// Remove this window from parent window's |child_windows_|.
void RemoveFromParentChildWindows();
#if defined(OS_WIN)
typedef std::map<UINT, MessageCallback> MessageCallbackMap;
MessageCallbackMap messages_callback_map_;
#endif
v8::Global<v8::Value> browser_view_;
v8::Global<v8::Value> web_contents_;
v8::Global<v8::Value> menu_;
v8::Global<v8::Value> parent_window_;
KeyWeakMap<int> child_windows_;
api::WebContents* api_web_contents_;
std::unique_ptr<NativeWindow> window_;
scoped_ptr<NativeWindow> window_;
DISALLOW_COPY_AND_ASSIGN(Window);
};

View File

@@ -11,15 +11,31 @@
namespace mate {
Event::Event(v8::Isolate* isolate)
: sender_(nullptr),
message_(nullptr) {
Init(isolate);
namespace {
v8::Persistent<v8::ObjectTemplate> template_;
} // namespace
Event::Event()
: sender_(NULL),
message_(NULL) {
}
Event::~Event() {
}
ObjectTemplateBuilder Event::GetObjectTemplateBuilder(v8::Isolate* isolate) {
if (template_.IsEmpty())
template_.Reset(isolate, ObjectTemplateBuilder(isolate)
.SetMethod("preventDefault", &Event::PreventDefault)
.SetMethod("sendReply", &Event::SendReply)
.Build());
return ObjectTemplateBuilder(
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
}
void Event::SetSenderAndMessage(content::WebContents* sender,
IPC::Message* message) {
DCHECK(!sender_);
@@ -31,38 +47,26 @@ void Event::SetSenderAndMessage(content::WebContents* sender,
}
void Event::WebContentsDestroyed() {
sender_ = nullptr;
message_ = nullptr;
sender_ = NULL;
message_ = NULL;
}
void Event::PreventDefault(v8::Isolate* isolate) {
GetWrapper()->Set(StringToV8(isolate, "defaultPrevented"),
GetWrapper(isolate)->Set(StringToV8(isolate, "defaultPrevented"),
v8::True(isolate));
}
bool Event::SendReply(const base::string16& json) {
if (message_ == nullptr || sender_ == nullptr)
if (message_ == NULL || sender_ == NULL)
return false;
AtomViewHostMsg_Message_Sync::WriteReplyParams(message_, json);
bool success = sender_->Send(message_);
message_ = nullptr;
sender_ = nullptr;
return success;
return sender_->Send(message_);
}
// static
Handle<Event> Event::Create(v8::Isolate* isolate) {
return mate::CreateHandle(isolate, new Event(isolate));
}
// static
void Event::BuildPrototype(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(mate::StringToV8(isolate, "Event"));
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.SetMethod("preventDefault", &Event::PreventDefault)
.SetMethod("sendReply", &Event::SendReply);
return CreateHandle(isolate, new Event);
}
} // namespace mate

View File

@@ -6,8 +6,8 @@
#define ATOM_BROWSER_API_EVENT_H_
#include "content/public/browser/web_contents_observer.h"
#include "native_mate/handle.h"
#include "native_mate/wrappable.h"
#include "native_mate/handle.h"
namespace IPC {
class Message;
@@ -15,14 +15,11 @@ class Message;
namespace mate {
class Event : public Wrappable<Event>,
class Event : public Wrappable,
public content::WebContentsObserver {
public:
static Handle<Event> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
// Pass the sender and message to be replied.
void SetSenderAndMessage(content::WebContents* sender, IPC::Message* message);
@@ -33,8 +30,11 @@ class Event : public Wrappable<Event>,
bool SendReply(const base::string16& json);
protected:
explicit Event(v8::Isolate* isolate);
~Event() override;
Event();
virtual ~Event();
// Wrappable implementations:
ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
// content::WebContentsObserver implementations:
void WebContentsDestroyed() override;

View File

@@ -8,9 +8,6 @@
#include "native_mate/arguments.h"
#include "native_mate/dictionary.h"
#include "native_mate/object_template_builder.h"
#include "ui/events/event_constants.h"
#include "atom/common/node_includes.h"
namespace mate {
@@ -37,13 +34,11 @@ v8::Local<v8::Object> CreateEventObject(v8::Isolate* isolate) {
} // namespace
namespace internal {
EventEmitter::EventEmitter() {
}
v8::Local<v8::Object> CreateJSEvent(
v8::Isolate* isolate,
v8::Local<v8::Object> object,
content::WebContents* sender,
IPC::Message* message) {
v8::Local<v8::Object> EventEmitter::CreateJSEvent(
v8::Isolate* isolate, content::WebContents* sender, IPC::Message* message) {
v8::Local<v8::Object> event;
bool use_native_event = sender && message;
@@ -54,29 +49,16 @@ v8::Local<v8::Object> CreateJSEvent(
} else {
event = CreateEventObject(isolate);
}
mate::Dictionary(isolate, event).Set("sender", object);
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate));
return event;
}
v8::Local<v8::Object> CreateCustomEvent(
v8::Isolate* isolate,
v8::Local<v8::Object> object,
v8::Local<v8::Object> custom_event) {
v8::Local<v8::Object> EventEmitter::CreateCustomEvent(
v8::Isolate* isolate, v8::Local<v8::Object> custom_event) {
v8::Local<v8::Object> event = CreateEventObject(isolate);
(void)event->SetPrototype(custom_event->CreationContext(), custom_event);
mate::Dictionary(isolate, event).Set("sender", object);
mate::Dictionary(isolate, event).Set("sender", GetWrapper(isolate));
return event;
}
v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags) {
mate::Dictionary obj = mate::Dictionary::CreateEmpty(isolate);
obj.Set("shiftKey", static_cast<bool>(flags & ui::EF_SHIFT_DOWN));
obj.Set("ctrlKey", static_cast<bool>(flags & ui::EF_CONTROL_DOWN));
obj.Set("altKey", static_cast<bool>(flags & ui::EF_ALT_DOWN));
obj.Set("metaKey", static_cast<bool>(flags & ui::EF_COMMAND_DOWN));
return obj.GetHandle();
}
} // namespace internal
} // namespace mate

View File

@@ -20,49 +20,17 @@ class Message;
namespace mate {
namespace internal {
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
v8::Local<v8::Object> object,
content::WebContents* sender,
IPC::Message* message);
v8::Local<v8::Object> CreateCustomEvent(
v8::Isolate* isolate,
v8::Local<v8::Object> object,
v8::Local<v8::Object> event);
v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags);
} // namespace internal
// Provide helperers to emit event in JavaScript.
template<typename T>
class EventEmitter : public Wrappable<T> {
class EventEmitter : public Wrappable {
public:
typedef std::vector<v8::Local<v8::Value>> ValueArray;
// Make the convinient methods visible:
// https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
v8::Local<v8::Object> GetWrapper() { return Wrappable<T>::GetWrapper(); }
v8::Isolate* isolate() const { return Wrappable<T>::isolate(); }
// this.emit(name, event, args...);
template<typename... Args>
bool EmitCustomEvent(const base::StringPiece& name,
v8::Local<v8::Object> event,
const Args&... args) {
return EmitWithEvent(
name,
internal::CreateCustomEvent(isolate(), GetWrapper(), event), args...);
}
// this.emit(name, new Event(flags), args...);
template<typename... Args>
bool EmitWithFlags(const base::StringPiece& name,
int flags,
const Args&... args) {
return EmitCustomEvent(
name,
internal::CreateEventFromFlags(isolate(), flags), args...);
return EmitWithEvent(name, CreateCustomEvent(isolate(), event), args...);
}
// this.emit(name, new Event(), args...);
@@ -79,13 +47,12 @@ class EventEmitter : public Wrappable<T> {
const Args&... args) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Object> event = internal::CreateJSEvent(
isolate(), GetWrapper(), sender, message);
v8::Local<v8::Object> event = CreateJSEvent(isolate(), sender, message);
return EmitWithEvent(name, event, args...);
}
protected:
EventEmitter() {}
EventEmitter();
private:
// this.emit(name, event, args...);
@@ -95,11 +62,17 @@ class EventEmitter : public Wrappable<T> {
const Args&... args) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
EmitEvent(isolate(), GetWrapper(), name, event, args...);
EmitEvent(isolate(), GetWrapper(isolate()), name, event, args...);
return event->Get(
StringToV8(isolate(), "defaultPrevented"))->BooleanValue();
}
v8::Local<v8::Object> CreateJSEvent(v8::Isolate* isolate,
content::WebContents* sender,
IPC::Message* message);
v8::Local<v8::Object> CreateCustomEvent(
v8::Isolate* isolate, v8::Local<v8::Object> event);
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
};

View File

@@ -4,13 +4,9 @@
#include "atom/browser/api/frame_subscriber.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "base/bind.h"
#include "content/public/browser/render_widget_host.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "atom/common/node_includes.h"
#include "content/public/browser/render_widget_host.h"
namespace atom {
@@ -18,92 +14,50 @@ namespace api {
FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
content::RenderWidgetHostView* view,
const FrameCaptureCallback& callback,
bool only_dirty)
: isolate_(isolate),
view_(view),
callback_(callback),
only_dirty_(only_dirty),
source_id_for_copy_request_(base::UnguessableToken::Create()),
weak_factory_(this) {
const FrameCaptureCallback& callback)
: isolate_(isolate), view_(view), callback_(callback), weak_factory_(this) {
}
bool FrameSubscriber::ShouldCaptureFrame(
const gfx::Rect& dirty_rect,
const gfx::Rect& damage_rect,
base::TimeTicks present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) {
if (!view_)
const auto host = view_ ? view_->GetRenderWidgetHost() : nullptr;
if (!view_ || !host)
return false;
if (dirty_rect.IsEmpty())
return false;
const auto size = view_->GetVisibleViewportSize();
gfx::Rect rect = gfx::Rect(view_->GetVisibleViewportSize());
if (only_dirty_)
rect = dirty_rect;
gfx::Size view_size = rect.size();
gfx::Size bitmap_size = view_size;
gfx::NativeView native_view = view_->GetNativeView();
const float scale =
display::Screen::GetScreen()->GetDisplayNearestView(native_view)
.device_scale_factor();
if (scale > 1.0f)
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
rect = gfx::Rect(rect.origin(), bitmap_size);
view_->CopyFromSurface(
rect,
rect.size(),
host->CopyFromBackingStore(
gfx::Rect(size),
size,
base::Bind(&FrameSubscriber::OnFrameDelivered,
weak_factory_.GetWeakPtr(), callback_, rect),
weak_factory_.GetWeakPtr(), callback_),
kBGRA_8888_SkColorType);
return false;
}
const base::UnguessableToken& FrameSubscriber::GetSourceIdForCopyRequest() {
return source_id_for_copy_request_;
}
void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback,
const gfx::Rect& damage_rect,
const SkBitmap& bitmap,
content::ReadbackResponse response) {
if (response != content::ReadbackResponse::READBACK_SUCCESS)
const SkBitmap& bitmap, content::ReadbackResponse response) {
if (bitmap.computeSize64() == 0)
return;
v8::Locker locker(isolate_);
v8::HandleScope handle_scope(isolate_);
size_t rgb_row_size = bitmap.width() * bitmap.bytesPerPixel();
v8::MaybeLocal<v8::Object> buffer =
node::Buffer::New(isolate_, rgb_row_size * bitmap.height());
size_t rgb_arr_size = bitmap.width() * bitmap.height() *
bitmap.bytesPerPixel();
v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate_, rgb_arr_size);
if (buffer.IsEmpty())
return;
auto local_buffer = buffer.ToLocalChecked();
bitmap.copyPixelsTo(
reinterpret_cast<uint8*>(node::Buffer::Data(buffer.ToLocalChecked())),
rgb_arr_size);
{
SkAutoLockPixels lock(bitmap);
auto source = static_cast<const unsigned char*>(bitmap.getPixels());
auto target = node::Buffer::Data(local_buffer);
for (int y = 0; y < bitmap.height(); ++y) {
memcpy(target, source, rgb_row_size);
source += bitmap.rowBytes();
target += rgb_row_size;
}
}
v8::Local<v8::Value> damage =
mate::Converter<gfx::Rect>::ToV8(isolate_, damage_rect);
callback_.Run(local_buffer, damage);
callback_.Run(buffer.ToLocalChecked());
}
} // namespace api

View File

@@ -7,9 +7,9 @@
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/renderer_host/render_widget_host_view_frame_subscriber.h"
#include "content/public/browser/readback_types.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
#include "content/public/browser/readback_types.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/geometry/size.h"
#include "v8/include/v8.h"
@@ -20,32 +20,24 @@ namespace api {
class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
public:
using FrameCaptureCallback =
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
using FrameCaptureCallback = base::Callback<void(v8::Local<v8::Value>)>;
FrameSubscriber(v8::Isolate* isolate,
content::RenderWidgetHostView* view,
const FrameCaptureCallback& callback,
bool only_dirty);
const FrameCaptureCallback& callback);
bool ShouldCaptureFrame(const gfx::Rect& damage_rect,
base::TimeTicks present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) override;
const base::UnguessableToken& GetSourceIdForCopyRequest() override;
private:
void OnFrameDelivered(const FrameCaptureCallback& callback,
const gfx::Rect& damage_rect,
const SkBitmap& bitmap,
content::ReadbackResponse response);
const SkBitmap& bitmap, content::ReadbackResponse response);
v8::Isolate* isolate_;
content::RenderWidgetHostView* view_;
FrameCaptureCallback callback_;
bool only_dirty_;
base::UnguessableToken source_id_for_copy_request_;
base::WeakPtrFactory<FrameSubscriber> weak_factory_;

View File

@@ -73,6 +73,11 @@ void SavePageHandler::Destroy(content::DownloadItem* item) {
delete this;
}
// static
bool SavePageHandler::IsSavePageTypes(const std::string& type) {
return type == "multipart/related" || type == "text/html";
}
} // namespace api
} // namespace atom

View File

@@ -37,6 +37,8 @@ class SavePageHandler : public content::DownloadManager::Observer,
bool Handle(const base::FilePath& full_path,
const content::SavePageType& save_type);
static bool IsSavePageTypes(const std::string& type);
private:
void Destroy(content::DownloadItem* item);

View File

@@ -6,7 +6,6 @@
#include "atom/browser/atom_browser_main_parts.h"
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/supports_user_data.h"
namespace mate {
@@ -30,7 +29,7 @@ class IDUserData : public base::SupportsUserData::Data {
} // namespace
TrackableObjectBase::TrackableObjectBase()
: weak_map_id_(0), weak_factory_(this) {
: weak_map_id_(0), wrapped_(nullptr), weak_factory_(this) {
cleanup_ = RegisterDestructionCallback(GetDestroyClosure());
}
@@ -38,6 +37,15 @@ TrackableObjectBase::~TrackableObjectBase() {
cleanup_.Run();
}
void TrackableObjectBase::AfterInit(v8::Isolate* isolate) {
if (wrapped_)
AttachAsUserData(wrapped_);
}
void TrackableObjectBase::MarkDestroyed() {
GetWrapper(isolate())->SetAlignedPointerInInternalField(0, nullptr);
}
base::Closure TrackableObjectBase::GetDestroyClosure() {
return base::Bind(&TrackableObjectBase::Destroy, weak_factory_.GetWeakPtr());
}
@@ -47,19 +55,23 @@ void TrackableObjectBase::Destroy() {
}
void TrackableObjectBase::AttachAsUserData(base::SupportsUserData* wrapped) {
wrapped->SetUserData(kTrackedObjectKey,
base::MakeUnique<IDUserData>(weak_map_id_));
if (weak_map_id_ != 0) {
wrapped->SetUserData(kTrackedObjectKey, new IDUserData(weak_map_id_));
wrapped_ = nullptr;
} else {
// If the TrackableObjectBase is not ready yet then delay SetUserData until
// AfterInit is called.
wrapped_ = wrapped;
}
}
// static
int32_t TrackableObjectBase::GetIDFromWrappedClass(
base::SupportsUserData* wrapped) {
if (wrapped) {
auto id = static_cast<IDUserData*>(wrapped->GetUserData(kTrackedObjectKey));
if (id)
return *id;
}
return 0;
int32_t TrackableObjectBase::GetIDFromWrappedClass(base::SupportsUserData* w) {
auto id = static_cast<IDUserData*>(w->GetUserData(kTrackedObjectKey));
if (id)
return *id;
else
return 0;
}
// static

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