mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5155cd9214 | ||
|
|
8f2b01a97d |
2597
.circleci/config.yml
2597
.circleci/config.yml
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
mkdir -p ~/.ssh
|
||||
echo "|1|B3r+7aO0/x90IdefihIjxIoJrrk=|OJddGDfhbuLFc1bUyy84hhIw57M= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|
||||
|1|rGlEvW55DtzNZp+pzw9gvyOyKi4=|LLWr+7qlkAlw3YGGVfLHHxB/kR0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts
|
||||
@@ -1,35 +0,0 @@
|
||||
# Defines the Chromium style for automatic reformatting.
|
||||
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
BasedOnStyle: Chromium
|
||||
# This defaults to 'Auto'. Explicitly set it for a while, so that
|
||||
# 'vector<vector<int> >' in existing files gets formatted to
|
||||
# 'vector<vector<int>>'. ('Auto' means that clang-format will only use
|
||||
# 'int>>' if the file already contains at least one such instance.)
|
||||
Standard: Cpp11
|
||||
# Make sure code like:
|
||||
# IPC_BEGIN_MESSAGE_MAP()
|
||||
# IPC_MESSAGE_HANDLER(WidgetHostViewHost_Update, OnUpdate)
|
||||
# IPC_END_MESSAGE_MAP()
|
||||
# gets correctly indented.
|
||||
MacroBlockBegin: "^\
|
||||
BEGIN_MSG_MAP|\
|
||||
BEGIN_MSG_MAP_EX|\
|
||||
BEGIN_SAFE_MSG_MAP_EX|\
|
||||
CR_BEGIN_MSG_MAP_EX|\
|
||||
IPC_BEGIN_MESSAGE_MAP|\
|
||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM|\
|
||||
IPC_PROTOBUF_MESSAGE_TRAITS_BEGIN|\
|
||||
IPC_STRUCT_BEGIN|\
|
||||
IPC_STRUCT_BEGIN_WITH_PARENT|\
|
||||
IPC_STRUCT_TRAITS_BEGIN|\
|
||||
POLPARAMS_BEGIN|\
|
||||
PPAPI_BEGIN_MESSAGE_MAP$"
|
||||
MacroBlockEnd: "^\
|
||||
CR_END_MSG_MAP|\
|
||||
END_MSG_MAP|\
|
||||
IPC_END_MESSAGE_MAP|\
|
||||
IPC_PROTOBUF_MESSAGE_TRAITS_END|\
|
||||
IPC_STRUCT_END|\
|
||||
IPC_STRUCT_TRAITS_END|\
|
||||
POLPARAMS_END|\
|
||||
PPAPI_END_MESSAGE_MAP$"
|
||||
@@ -1,59 +0,0 @@
|
||||
# Electron Dev on Codespaces
|
||||
|
||||
Welcome to the Codespaces Electron Developer Environment.
|
||||
|
||||
## Quick Start
|
||||
|
||||
Upon creation of your codespace you should have [build tools](https://github.com/electron/build-tools) installed and an initialized gclient checkout of Electron. In order to build electron you'll need to run the following commands.
|
||||
|
||||
```bash
|
||||
e sync -vv
|
||||
e build
|
||||
```
|
||||
|
||||
The initial sync will take approximately ~30 minutes and the build will take ~8 minutes. Incremental syncs and incremental builds are substantially quicker.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
Codespaces doesn't lean very well into gclient based checkouts, the directory structure is slightly strange. There are two locations for the `electron` checkout that both map to the same files under the hood.
|
||||
|
||||
```graphql
|
||||
# Primary gclient checkout container
|
||||
/workspaces/gclient/*
|
||||
└─ src/* - # Chromium checkout
|
||||
└─ electron - # Electron checkout
|
||||
# Symlinked Electron checkout (identical to the above)
|
||||
/workspaces/electron
|
||||
```
|
||||
|
||||
## Goma
|
||||
|
||||
If you are a maintainer [with Goma access](../docs/development/goma.md) it should be automatically configured and authenticated when you spin up a new codespaces instance. You can validate this by checking `e d goma_auth info` or by checking that your build-tools configuration has a goma mode of `cluster`.
|
||||
|
||||
## Running Electron
|
||||
|
||||
You can run Electron in a few ways. If you just want to see if it launches:
|
||||
|
||||
```bash
|
||||
# Enter an interactive JS prompt headlessly
|
||||
xvfb-run e start -i
|
||||
```
|
||||
|
||||
But if you want to actually see Electron you will need to use the built-in VNC capability. If you click "Ports" in codespaces and then open the `VNC web client` forwarded port you should see a web based VNC portal in your browser. When you are asked for a password use `builduser`.
|
||||
|
||||
Once in the VNC UI you can open `Applications -> System -> XTerm` which will open a VNC based terminal app and then you can run `e start` like normal and Electron will open in your VNC session.
|
||||
|
||||
## Running Tests
|
||||
|
||||
You run tests via build-tools and `xvfb`.
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
xvfb-run e test
|
||||
|
||||
# Run the main process tests
|
||||
xvfb-run e test --runners=main
|
||||
|
||||
# Run the old remote tests
|
||||
xvfb-run e test --runners=remote
|
||||
```
|
||||
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"service": "buildtools",
|
||||
"onCreateCommand": ".devcontainer/on-create-command.sh",
|
||||
"workspaceFolder": "/workspaces/gclient/src/electron",
|
||||
"extensions": [
|
||||
"joeleinbinder.mojom-language",
|
||||
"rafaelmaiolla.diff",
|
||||
"surajbarkale.ninja",
|
||||
"ms-vscode.cpptools",
|
||||
"mutantdino.resourcemonitor",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"shakram02.bash-beautify",
|
||||
"marshallofsound.gnls-electron"
|
||||
],
|
||||
"settings": {
|
||||
"[gn]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"editor.tabSize": 2,
|
||||
"bashBeautify.tabSize": 2
|
||||
},
|
||||
"forwardPorts": [8088, 6080, 5901],
|
||||
"portsAttributes": {
|
||||
"8088": {
|
||||
"label": "Goma Control Panel",
|
||||
"onAutoForward": "silent"
|
||||
},
|
||||
"6080": {
|
||||
"label": "VNC web client (noVNC)",
|
||||
"onAutoForward": "silent"
|
||||
},
|
||||
"5901": {
|
||||
"label": "VNC TCP port",
|
||||
"onAutoForward": "silent"
|
||||
}
|
||||
},
|
||||
"hostRequirements": {
|
||||
"storage": "32gb",
|
||||
"cpus": 8
|
||||
},
|
||||
"remoteUser": "builduser"
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
buildtools:
|
||||
image: ghcr.io/electron/devcontainer:27db4a3e3512bfd2e47f58cea69922da0835f1d9
|
||||
|
||||
volumes:
|
||||
- ..:/workspaces/gclient/src/electron:cached
|
||||
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
command: /bin/sh -c "while sleep 1000; do :; done"
|
||||
|
||||
user: builduser
|
||||
|
||||
cap_add:
|
||||
- SYS_PTRACE
|
||||
security_opt:
|
||||
- seccomp:unconfined
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
buildtools=$HOME/.electron_build_tools
|
||||
gclient_root=/workspaces/gclient
|
||||
buildtools_configs=/workspaces/buildtools-configs
|
||||
|
||||
export PATH="$PATH:$buildtools/src"
|
||||
|
||||
# Create the persisted buildtools config folder
|
||||
mkdir -p $buildtools_configs
|
||||
rm -f $buildtools/configs
|
||||
ln -s $buildtools_configs $buildtools/configs
|
||||
|
||||
# Write the gclient config if it does not already exist
|
||||
if [ ! -f $gclient_root/.gclient ]; then
|
||||
echo "solutions = [
|
||||
{ \"name\" : \"src/electron\",
|
||||
\"url\" : \"https://github.com/electron/electron\",
|
||||
\"deps_file\" : \"DEPS\",
|
||||
\"managed\" : False,
|
||||
\"custom_deps\" : {
|
||||
},
|
||||
\"custom_vars\": {},
|
||||
},
|
||||
]
|
||||
" >$gclient_root/.gclient
|
||||
fi
|
||||
|
||||
# Write the default buildtools config file if it does
|
||||
# not already exist
|
||||
if [ ! -f $buildtools/configs/evm.testing.json ]; then
|
||||
write_config() {
|
||||
echo "
|
||||
{
|
||||
\"root\": \"/workspaces/gclient\",
|
||||
\"goma\": \"$1\",
|
||||
\"gen\": {
|
||||
\"args\": [
|
||||
\"import(\\\"//electron/build/args/testing.gn\\\")\",
|
||||
\"import(\\\"/home/builduser/.electron_build_tools/third_party/goma.gn\\\")\"
|
||||
],
|
||||
\"out\": \"Testing\"
|
||||
},
|
||||
\"env\": {
|
||||
\"CHROMIUM_BUILDTOOLS_PATH\": \"/workspaces/gclient/src/buildtools\",
|
||||
\"GIT_CACHE_PATH\": \"/workspaces/gclient/.git-cache\"
|
||||
},
|
||||
\"remotes\": {
|
||||
\"electron\": {
|
||||
\"origin\": \"https://github.com/electron/electron.git\"
|
||||
}
|
||||
}
|
||||
}
|
||||
" >$buildtools/configs/evm.testing.json
|
||||
}
|
||||
|
||||
# Start out as cache only
|
||||
write_config cache-only
|
||||
|
||||
e use testing
|
||||
|
||||
# Attempt to auth to the goma service via codespaces tokens
|
||||
# if it works we can use the goma cluster
|
||||
export NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN
|
||||
if e d goma_auth login; then
|
||||
write_config cluster
|
||||
fi
|
||||
else
|
||||
# Even if the config file existed we still need to re-auth with the goma
|
||||
# cluster
|
||||
NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN e d goma_auth login || true
|
||||
fi
|
||||
@@ -1,2 +0,0 @@
|
||||
*
|
||||
!tools/xvfb-init.sh
|
||||
@@ -1,6 +0,0 @@
|
||||
# These env vars are only necessary for creating Electron releases.
|
||||
# See docs/development/releasing.md
|
||||
|
||||
APPVEYOR_CLOUD_TOKEN=
|
||||
CIRCLE_TOKEN=
|
||||
ELECTRON_GITHUB_TOKEN=
|
||||
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"extends": "standard",
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"rules": {
|
||||
"semi": ["error", "always"],
|
||||
"no-var": "error",
|
||||
"no-unused-vars": "off",
|
||||
"no-global-assign": "off",
|
||||
"guard-for-in": "error",
|
||||
"@typescript-eslint/no-unused-vars": ["error", {
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": true
|
||||
}],
|
||||
"prefer-const": ["error", {
|
||||
"destructuring": "all"
|
||||
}],
|
||||
"standard/no-callback-literal": "off",
|
||||
"node/no-deprecated-api": "off"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.js",
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": "*.ts",
|
||||
"rules": {
|
||||
"no-undef": "off",
|
||||
"no-redeclare": "off",
|
||||
"@typescript-eslint/no-redeclare": ["error"],
|
||||
"no-use-before-define": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": "*.d.ts",
|
||||
"rules": {
|
||||
"no-useless-constructor": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
14
.gitattributes
vendored
14
.gitattributes
vendored
@@ -1,14 +0,0 @@
|
||||
# `git apply` and friends don't understand CRLF, even on windows. Force those
|
||||
# files to be checked out with LF endings even if core.autocrlf is true.
|
||||
*.patch text eol=lf
|
||||
patches/**/.patches merge=union
|
||||
|
||||
# Source code and markdown files should always use LF as line ending.
|
||||
*.cc text eol=lf
|
||||
*.mm text eol=lf
|
||||
*.h text eol=lf
|
||||
*.js text eol=lf
|
||||
*.ts text eol=lf
|
||||
*.py text eol=lf
|
||||
*.ps1 text eol=lf
|
||||
*.md text eol=lf
|
||||
19
.github/CODEOWNERS
vendored
19
.github/CODEOWNERS
vendored
@@ -1,19 +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
|
||||
|
||||
# Upgrades WG
|
||||
/patches/ @electron/wg-upgrades
|
||||
DEPS @electron/wg-upgrades
|
||||
|
||||
# Releases WG
|
||||
/npm/ @electron/wg-releases
|
||||
/script/release @electron/wg-releases
|
||||
|
||||
# Security WG
|
||||
/lib/browser/devtools.ts @electron/wg-security
|
||||
/lib/browser/guest-view-manager.ts @electron/wg-security
|
||||
/lib/browser/guest-window-proxy.ts @electron/wg-security
|
||||
/lib/browser/rpc-server.ts @electron/wg-security
|
||||
/lib/renderer/security-warnings.ts @electron/wg-security
|
||||
77
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
77
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,77 +0,0 @@
|
||||
name: Bug Report
|
||||
description: Report an Electron bug
|
||||
title: "[Bug]: "
|
||||
labels: "bug :beetle:"
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Preflight Checklist
|
||||
description: Please ensure you've completed all of the following.
|
||||
options:
|
||||
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
|
||||
required: true
|
||||
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
|
||||
required: true
|
||||
- label: I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a feature request that matches the one I want to file, without success.
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Electron Version
|
||||
description: What version of Electron are you using?
|
||||
placeholder: 12.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: What operating system are you using?
|
||||
options:
|
||||
- Windows
|
||||
- macOS
|
||||
- Ubuntu
|
||||
- Other Linux
|
||||
- Other (specify below)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Operating System Version
|
||||
description: What operating system version are you using? On Windows, click Start button > Settings > System > About. On macOS, click the Apple Menu > About This Mac. On Linux, use lsb_release or uname -a.
|
||||
placeholder: "e.g. Windows 10 version 1909, macOS Catalina 10.15.7, or Ubuntu 20.04"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: What arch are you using?
|
||||
options:
|
||||
- x64
|
||||
- ia32
|
||||
- arm64 (including Apple Silicon)
|
||||
- Other (specify below)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Last Known Working Electron version
|
||||
description: What is the last version of Electron this worked in, if applicable?
|
||||
placeholder: 11.0.0
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Actual Behavior
|
||||
description: A clear description of what actually happens.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Testcase Gist URL
|
||||
description: If you can reproduce the issue in a standalone test case, please use [Electron Fiddle](https://github.com/electron/fiddle) to create one and to publish it as a [GitHub gist](https://gist.github.com) and put the gist URL here. This is **the best way** to ensure this issue is triaged quickly.
|
||||
placeholder: https://gist.github.com/...
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional Information
|
||||
description: If your problem needs further explanation, or if the issue you're seeing cannot be reproduced in a gist, please add more information here.
|
||||
40
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
40
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,40 +0,0 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for Electron
|
||||
title: "[Feature Request]: "
|
||||
labels: "enhancement :sparkles:"
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Preflight Checklist
|
||||
description: Please ensure you've completed all of the following.
|
||||
options:
|
||||
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
|
||||
required: true
|
||||
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
|
||||
required: true
|
||||
- label: I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a feature request that matches the one I want to file, without success.
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Problem Description
|
||||
description: Please add a clear and concise description of the problem you are seeking to solve with this feature request.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Proposed Solution
|
||||
description: Describe the solution you'd like in a clear and concise manner.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Alternatives Considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional Information
|
||||
description: Add any other context about the problem here.
|
||||
validations:
|
||||
required: false
|
||||
@@ -1,30 +0,0 @@
|
||||
name: Report Mac App Store Private API Rejection
|
||||
description: Your app was rejected from the Mac App Store for using private API's
|
||||
title: "[MAS Rejection]: "
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Preflight Checklist
|
||||
description: Please ensure you've completed all of the following.
|
||||
options:
|
||||
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
|
||||
required: true
|
||||
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Electron Version
|
||||
description: What version of Electron are you using?
|
||||
placeholder: 12.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Rejection Email
|
||||
description: Paste the contents of your rejection email here, censoring any private information such as app names.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional Information
|
||||
description: Add any other context about the problem here.
|
||||
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,20 +0,0 @@
|
||||
#### Description of Change
|
||||
<!--
|
||||
Thank you for your Pull Request. Please provide a description above and review
|
||||
the requirements below.
|
||||
|
||||
Contributors guide: https://github.com/electron/electron/blob/main/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
#### Checklist
|
||||
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->
|
||||
|
||||
- [ ] PR description included and stakeholders cc'd
|
||||
- [ ] `npm test` passes
|
||||
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/main/docs/development/testing.md)
|
||||
- [ ] relevant documentation is changed or added
|
||||
- [ ] [PR release notes](https://github.com/electron/clerk/blob/master/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/master/README.md#examples).
|
||||
|
||||
#### Release Notes
|
||||
|
||||
Notes: <!-- Please add a one-line description for app developers to read in the release notes, or 'none' if no notes relevant to app developers. Examples and help on special cases: https://github.com/electron/clerk/blob/master/README.md#examples -->
|
||||
41
.github/config.yml
vendored
41
.github/config.yml
vendored
@@ -1,41 +0,0 @@
|
||||
# Comment to be posted to on PRs from first time contributors in your repository
|
||||
newPRWelcomeComment: |
|
||||
💖 Thanks for opening this pull request! 💖
|
||||
|
||||
We use [semantic commit messages](https://github.com/electron/electron/blob/main/docs/development/pull-requests.md#commit-message-guidelines) to streamline the release process. Before your pull request can be merged, you should **update your pull request title** to start with a semantic prefix.
|
||||
|
||||
Examples of commit messages with semantic prefixes:
|
||||
|
||||
- `fix: don't overwrite prevent_default if default wasn't prevented`
|
||||
- `feat: add app.isPackaged() method`
|
||||
- `docs: app.isDefaultProtocolClient is now available on Linux`
|
||||
|
||||
Things that will help get your PR across the finish line:
|
||||
|
||||
- Follow the JavaScript, C++, and Python [coding style](https://github.com/electron/electron/blob/main/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/main/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! 🎉🎉🎉
|
||||
|
||||
# Users authorized to run manual trop backports
|
||||
authorizedUsers:
|
||||
- alexeykuzmin
|
||||
- ckerr
|
||||
- codebytere
|
||||
- deepak1556
|
||||
- jkleinsc
|
||||
- loc
|
||||
- MarshallOfSound
|
||||
- miniak
|
||||
- mlaurencin
|
||||
- nornagon
|
||||
- zcbenz
|
||||
2
.github/semantic.yml
vendored
2
.github/semantic.yml
vendored
@@ -1,2 +0,0 @@
|
||||
# Always validate the PR title, and ignore the commits
|
||||
titleOnly: true
|
||||
61
.gitignore
vendored
61
.gitignore
vendored
@@ -1,56 +1,11 @@
|
||||
.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/
|
||||
/build/
|
||||
/dist/
|
||||
/frameworks/
|
||||
/out/
|
||||
/vendor/brightray/vendor/download/
|
||||
/vendor/python_26/
|
||||
node_modules/
|
||||
SHASUMS256.txt
|
||||
**/package-lock.json
|
||||
compile_commands.json
|
||||
.envrc
|
||||
|
||||
# npm package
|
||||
/npm/dist
|
||||
/npm/path.txt
|
||||
/npm/checksums.json
|
||||
|
||||
.npmrc
|
||||
|
||||
# Generated API definitions
|
||||
electron-api.json
|
||||
electron.d.ts
|
||||
|
||||
# Spec hash calculation
|
||||
spec/.hash
|
||||
|
||||
# Eslint Cache
|
||||
.eslintcache*
|
||||
|
||||
# Generated native addon files
|
||||
/spec-main/fixtures/native-addon/echo/build/
|
||||
|
||||
# If someone runs tsc this is where stuff will end up
|
||||
ts-gen
|
||||
|
||||
# Used to accelerate CI builds
|
||||
.depshash
|
||||
.depshash-target
|
||||
|
||||
# Used to accelerate builds after sync
|
||||
patches/mtime-cache.json
|
||||
|
||||
spec/fixtures/logo.png
|
||||
*.xcodeproj
|
||||
*.swp
|
||||
*.pyc
|
||||
|
||||
15
.gitmodules
vendored
Normal file
15
.gitmodules
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
[submodule "vendor/brightray"]
|
||||
path = vendor/brightray
|
||||
url = https://github.com/brightray/brightray.git
|
||||
[submodule "vendor/node"]
|
||||
path = vendor/node
|
||||
url = https://github.com/atom/node.git
|
||||
[submodule "vendor/gyp"]
|
||||
path = vendor/gyp
|
||||
url = https://github.com/svn2github/gyp.git
|
||||
[submodule "vendor/depot_tools"]
|
||||
path = vendor/depot_tools
|
||||
url = https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
[submodule "vendor/apm"]
|
||||
path = vendor/apm
|
||||
url = https://github.com/atom/apm.git
|
||||
1
.husky/.gitignore
vendored
1
.husky/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
_
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npm run precommit
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npm run prepack
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"default": false,
|
||||
"no-trailing-spaces": {
|
||||
"br_spaces": 0
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"commands-show-output": false,
|
||||
"first-line-h1": false,
|
||||
"header-increment": false,
|
||||
"line-length": {
|
||||
"code_blocks": false,
|
||||
"tables": false,
|
||||
"stern": true,
|
||||
"line_length": -1
|
||||
},
|
||||
"no-bare-urls": false,
|
||||
"no-blanks-blockquote": false,
|
||||
"no-duplicate-header": {
|
||||
"allow_different_nesting": true
|
||||
},
|
||||
"no-emphasis-as-header": false,
|
||||
"no-hard-tabs": {
|
||||
"code_blocks": false
|
||||
},
|
||||
"no-space-in-emphasis": false,
|
||||
"no-trailing-punctuation": false,
|
||||
"no-trailing-spaces": {
|
||||
"br_spaces": 0
|
||||
},
|
||||
"single-h1": false,
|
||||
"no-inline-html": {
|
||||
"allowed_elements": ["br"]
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"plugins": [
|
||||
["remark-lint-code-block-style", "fenced"],
|
||||
["remark-lint-fenced-code-flag"]
|
||||
]
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
# Code of Conduct
|
||||
|
||||
As a member project of the OpenJS Foundation, Electron uses [Contributor Covenant v2.0](https://contributor-covenant.org/version/2/0/code_of_conduct) as their code of conduct. The full text is included [below](#contributor-covenant-code-of-conduct) in English, and translations are available from the Contributor Covenant organisation:
|
||||
|
||||
* [contributor-covenant.org/translations](https://www.contributor-covenant.org/translations)
|
||||
* [github.com/ContributorCovenant](https://github.com/ContributorCovenant/contributor_covenant/tree/release/content/version/2/0)
|
||||
|
||||
## Contributor Covenant Code of Conduct
|
||||
|
||||
### Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
### Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
### Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders 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, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
### Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
### Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
[coc@electronjs.org](mailto:coc@electronjs.org).
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
### Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
#### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
#### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
#### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
#### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
### Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
@@ -1,70 +0,0 @@
|
||||
# Contributing to Electron
|
||||
|
||||
:+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 coc@electronjs.org.
|
||||
|
||||
The following is a set of guidelines for contributing to Electron.
|
||||
These are just guidelines, not rules, use your best judgment and feel free to
|
||||
propose changes to this document in a pull request.
|
||||
|
||||
## [Issues](https://electronjs.org/docs/development/issues)
|
||||
|
||||
Issues are created [here](https://github.com/electron/electron/issues/new).
|
||||
|
||||
* [How to Contribute in Issues](https://electronjs.org/docs/development/issues#how-to-contribute-in-issues)
|
||||
* [Asking for General Help](https://electronjs.org/docs/development/issues#asking-for-general-help)
|
||||
* [Submitting a Bug Report](https://electronjs.org/docs/development/issues#submitting-a-bug-report)
|
||||
* [Triaging a Bug Report](https://electronjs.org/docs/development/issues#triaging-a-bug-report)
|
||||
* [Resolving a Bug Report](https://electronjs.org/docs/development/issues#resolving-a-bug-report)
|
||||
|
||||
### Issue Closure
|
||||
|
||||
Bug reports will be closed if the issue has been inactive and the latest affected version no longer receives support. At the moment, Electron maintains its three latest major versions, with a new major version being released every 8 weeks. (For more information on Electron's release cadence, see [this blog post](https://electronjs.org/blog/8-week-cadence).)
|
||||
|
||||
_If an issue has been closed and you still feel it's relevant, feel free to ping a maintainer or add a comment!_
|
||||
|
||||
### Languages
|
||||
|
||||
We accept issues in *any* language.
|
||||
When an issue is posted in a language besides English, it is acceptable and encouraged to post an English-translated copy as a reply.
|
||||
Anyone may post the translated reply.
|
||||
In most cases, a quick pass through translation software is sufficient.
|
||||
Having the original text _as well as_ the translation can help mitigate translation errors.
|
||||
|
||||
Responses to posted issues may or may not be in the original language.
|
||||
|
||||
**Please note** that using non-English as an attempt to circumvent our [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) will be an immediate, and possibly indefinite, ban from the project.
|
||||
|
||||
## [Pull Requests](https://electronjs.org/docs/development/pull-requests)
|
||||
|
||||
Pull Requests are the way concrete changes are made to the code, documentation,
|
||||
dependencies, and tools contained in the `electron/electron` repository.
|
||||
|
||||
* [Setting up your local environment](https://electronjs.org/docs/development/pull-requests#setting-up-your-local-environment)
|
||||
* [Step 1: Fork](https://electronjs.org/docs/development/pull-requests#step-1-fork)
|
||||
* [Step 2: Build](https://electronjs.org/docs/development/pull-requests#step-2-build)
|
||||
* [Step 3: Branch](https://electronjs.org/docs/development/pull-requests#step-3-branch)
|
||||
* [Making Changes](https://electronjs.org/docs/development/pull-requests#making-changes)
|
||||
* [Step 4: Code](https://electronjs.org/docs/development/pull-requests#step-4-code)
|
||||
* [Step 5: Commit](https://electronjs.org/docs/development/pull-requests#step-5-commit)
|
||||
* [Commit message guidelines](https://electronjs.org/docs/development/pull-requests#commit-message-guidelines)
|
||||
* [Step 6: Rebase](https://electronjs.org/docs/development/pull-requests#step-6-rebase)
|
||||
* [Step 7: Test](https://electronjs.org/docs/development/pull-requests#step-7-test)
|
||||
* [Step 8: Push](https://electronjs.org/docs/development/pull-requests#step-8-push)
|
||||
* [Step 9: Opening the Pull Request](https://electronjs.org/docs/development/pull-requests#step-9-opening-the-pull-request)
|
||||
* [Step 10: Discuss and Update](https://electronjs.org/docs/development/pull-requests#step-10-discuss-and-update)
|
||||
* [Approval and Request Changes Workflow](https://electronjs.org/docs/development/pull-requests#approval-and-request-changes-workflow)
|
||||
* [Step 11: Landing](https://electronjs.org/docs/development/pull-requests#step-11-landing)
|
||||
* [Continuous Integration Testing](https://electronjs.org/docs/development/pull-requests#continuous-integration-testing)
|
||||
|
||||
## Style Guides
|
||||
|
||||
See [Coding Style](https://electronjs.org/docs/development/coding-style) for information about which standards Electron adheres to in different parts of its codebase.
|
||||
|
||||
## Further Reading
|
||||
|
||||
For more in-depth guides on developing Electron, see
|
||||
[/docs/development](/docs/development/README.md)
|
||||
169
DEPS
169
DEPS
@@ -1,169 +0,0 @@
|
||||
gclient_gn_args_file = 'src/build/config/gclient_args.gni'
|
||||
gclient_gn_args = [
|
||||
'build_with_chromium',
|
||||
'checkout_android',
|
||||
'checkout_android_native_support',
|
||||
'checkout_libaom',
|
||||
'checkout_nacl',
|
||||
'checkout_pgo_profiles',
|
||||
'checkout_oculus_sdk',
|
||||
'checkout_openxr',
|
||||
'checkout_google_benchmark',
|
||||
'mac_xcode_version',
|
||||
'generate_location_tags',
|
||||
]
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'96.0.4664.45',
|
||||
'node_version':
|
||||
'v16.9.1',
|
||||
'nan_version':
|
||||
# The following commit hash of NAN is v2.14.2 with *only* changes to the
|
||||
# test suite. This should be updated to a specific tag when one becomes
|
||||
# available.
|
||||
'65b32af46e9d7fab2e4ff657751205b3865f4920',
|
||||
'squirrel.mac_version':
|
||||
'0e5d146ba13101a1302d59ea6e6e0b3cace4ae38',
|
||||
|
||||
'pyyaml_version': '3.12',
|
||||
|
||||
'chromium_git': 'https://chromium.googlesource.com',
|
||||
'electron_git': 'https://github.com/electron',
|
||||
'nodejs_git': 'https://github.com/nodejs',
|
||||
'yaml_git': 'https://github.com/yaml',
|
||||
'squirrel_git': 'https://github.com/Squirrel',
|
||||
|
||||
# KEEP IN SYNC WITH utils.js FILE
|
||||
'yarn_version': '1.15.2',
|
||||
|
||||
# To be able to build clean Chromium from sources.
|
||||
'apply_patches': True,
|
||||
|
||||
# To use an mtime cache for patched files to speed up builds.
|
||||
'use_mtime_cache': True,
|
||||
|
||||
# To allow in-house builds to checkout those manually.
|
||||
'checkout_chromium': True,
|
||||
'checkout_node': True,
|
||||
'checkout_nan': True,
|
||||
'checkout_pgo_profiles': True,
|
||||
|
||||
# It's only needed to parse the native tests configurations.
|
||||
'checkout_pyyaml': False,
|
||||
|
||||
'use_rts': False,
|
||||
|
||||
'mac_xcode_version': 'default',
|
||||
|
||||
'generate_location_tags': False,
|
||||
|
||||
# To allow running hooks without parsing the DEPS tree
|
||||
'process_deps': True,
|
||||
|
||||
'checkout_nacl':
|
||||
False,
|
||||
'checkout_libaom':
|
||||
True,
|
||||
'checkout_oculus_sdk':
|
||||
False,
|
||||
'checkout_openxr':
|
||||
False,
|
||||
'build_with_chromium':
|
||||
True,
|
||||
'checkout_android':
|
||||
False,
|
||||
'checkout_android_native_support':
|
||||
False,
|
||||
'checkout_google_benchmark':
|
||||
False,
|
||||
'checkout_clang_tidy':
|
||||
True,
|
||||
}
|
||||
|
||||
deps = {
|
||||
'src': {
|
||||
'url': (Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
|
||||
'condition': 'checkout_chromium and process_deps',
|
||||
},
|
||||
'src/third_party/nan': {
|
||||
'url': (Var("nodejs_git")) + '/nan.git@' + (Var("nan_version")),
|
||||
'condition': 'checkout_nan and process_deps',
|
||||
},
|
||||
'src/third_party/electron_node': {
|
||||
'url': (Var("nodejs_git")) + '/node.git@' + (Var("node_version")),
|
||||
'condition': 'checkout_node and process_deps',
|
||||
},
|
||||
'src/third_party/pyyaml': {
|
||||
'url': (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
|
||||
'condition': 'checkout_pyyaml and process_deps',
|
||||
},
|
||||
'src/third_party/squirrel.mac': {
|
||||
'url': Var("squirrel_git") + '/Squirrel.Mac.git@' + Var("squirrel.mac_version"),
|
||||
'condition': 'process_deps',
|
||||
},
|
||||
'src/third_party/squirrel.mac/vendor/ReactiveObjC': {
|
||||
'url': 'https://github.com/ReactiveCocoa/ReactiveObjC.git@74ab5baccc6f7202c8ac69a8d1e152c29dc1ea76',
|
||||
'condition': 'process_deps'
|
||||
},
|
||||
'src/third_party/squirrel.mac/vendor/Mantle': {
|
||||
'url': 'https://github.com/Mantle/Mantle.git@78d3966b3c331292ea29ec38661b25df0a245948',
|
||||
'condition': 'process_deps',
|
||||
}
|
||||
}
|
||||
|
||||
pre_deps_hooks = [
|
||||
{
|
||||
'name': 'generate_mtime_cache',
|
||||
'condition': '(checkout_chromium and apply_patches and use_mtime_cache) and process_deps',
|
||||
'pattern': 'src/electron',
|
||||
'action': [
|
||||
'python3',
|
||||
'src/electron/script/patches-mtime-cache.py',
|
||||
'generate',
|
||||
'--cache-file',
|
||||
'src/electron/patches/mtime-cache.json',
|
||||
'--patches-config',
|
||||
'src/electron/patches/config.json',
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
hooks = [
|
||||
{
|
||||
'name': 'patch_chromium',
|
||||
'condition': '(checkout_chromium and apply_patches) and process_deps',
|
||||
'pattern': 'src/electron',
|
||||
'action': [
|
||||
'python3',
|
||||
'src/electron/script/apply_all_patches.py',
|
||||
'src/electron/patches/config.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'apply_mtime_cache',
|
||||
'condition': '(checkout_chromium and apply_patches and use_mtime_cache) and process_deps',
|
||||
'pattern': 'src/electron',
|
||||
'action': [
|
||||
'python3',
|
||||
'src/electron/script/patches-mtime-cache.py',
|
||||
'apply',
|
||||
'--cache-file',
|
||||
'src/electron/patches/mtime-cache.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'electron_npm_deps',
|
||||
'pattern': 'src/electron/package.json',
|
||||
'action': [
|
||||
'python3',
|
||||
'-c',
|
||||
'import os, subprocess; os.chdir(os.path.join("src", "electron")); subprocess.check_call(["python3", "script/lib/npx.py", "yarn@' + (Var("yarn_version")) + '", "install", "--frozen-lockfile"]);',
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
recursedeps = [
|
||||
'src',
|
||||
'src/third_party/squirrel.mac',
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
16.0.1
|
||||
49
LICENSE
49
LICENSE
@@ -1,21 +1,28 @@
|
||||
Copyright (c) Electron contributors
|
||||
Copyright (c) 2013-2020 GitHub Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
106
README.md
106
README.md
@@ -1,102 +1,20 @@
|
||||
[](https://electronjs.org)
|
||||
# Atom Shell
|
||||
|
||||
[](https://circleci.com/gh/electron/electron/tree/main)
|
||||
[](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/main)
|
||||
[](https://discord.com/invite/electron)
|
||||
Native layer for the [Atom](https://github.com/github/atom).
|
||||
|
||||
:memo: Available Translations: 🇨🇳 🇧🇷 🇪🇸 🇯🇵 🇷🇺 🇫🇷 🇺🇸 🇩🇪.
|
||||
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).
|
||||
## Features
|
||||
|
||||
The Electron framework lets you write cross-platform desktop applications
|
||||
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
|
||||
[Chromium](https://www.chromium.org) and is used by the [Atom
|
||||
editor](https://github.com/atom/atom) and many other [apps](https://electronjs.org/apps).
|
||||
* Write desktop applications with web techniques
|
||||
* Support built-in and third-party modules of node.js
|
||||
* Support native node.js modules
|
||||
* Extended built-in modules for desktop programming
|
||||
* JavaScript on browser side
|
||||
* Easy API for cross-process communication
|
||||
|
||||
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
||||
announcements.
|
||||
## Usage & Development
|
||||
|
||||
This project adheres to the Contributor Covenant
|
||||
[code of conduct](https://github.com/electron/electron/tree/main/CODE_OF_CONDUCT.md).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable
|
||||
behavior to [coc@electronjs.org](mailto:coc@electronjs.org).
|
||||
|
||||
## Installation
|
||||
|
||||
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:
|
||||
|
||||
```sh
|
||||
npm install electron --save-dev
|
||||
```
|
||||
|
||||
For more installation options and troubleshooting tips, see
|
||||
[installation](docs/tutorial/installation.md). For info on how to manage Electron versions in your apps, see
|
||||
[Electron versioning](docs/tutorial/electron-versioning.md).
|
||||
|
||||
## Quick start & Electron Fiddle
|
||||
|
||||
Use [`Electron Fiddle`](https://github.com/electron/fiddle)
|
||||
to build, run, and package small Electron experiments, to see code examples for all of Electron's APIs, and
|
||||
to try out different versions of Electron. It's designed to make the start of your journey with
|
||||
Electron easier.
|
||||
|
||||
Alternatively, clone and run the
|
||||
[electron/electron-quick-start](https://github.com/electron/electron-quick-start)
|
||||
repository to see a minimal Electron app in action:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/electron/electron-quick-start
|
||||
cd electron-quick-start
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
## Resources for learning Electron
|
||||
|
||||
- [electronjs.org/docs](https://electronjs.org/docs) - All of Electron's documentation
|
||||
- [electron/fiddle](https://github.com/electron/fiddle) - A tool to build, run, and package small Electron experiments
|
||||
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - A very basic starter Electron app
|
||||
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - Sample starter apps created by the community
|
||||
- [electron/simple-samples](https://github.com/electron/simple-samples) - Small applications with ideas for taking them further
|
||||
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - An Electron app that teaches you how to use Electron
|
||||
|
||||
## 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)
|
||||
```
|
||||
|
||||
### Mirrors
|
||||
|
||||
- [China](https://npm.taobao.org/mirrors/electron)
|
||||
|
||||
## Documentation Translations
|
||||
|
||||
Find documentation translations in [electron/i18n](https://github.com/electron/i18n).
|
||||
|
||||
## Contributing
|
||||
|
||||
If you are interested in reporting/fixing issues and contributing directly to the code base, please see [CONTRIBUTING.md](CONTRIBUTING.md) for more information on what we're looking for and how to get started.
|
||||
|
||||
## Community
|
||||
|
||||
Info on reporting bugs, getting help, finding third-party tools and sample apps,
|
||||
and more can be found in the [support document](docs/tutorial/support.md#finding-support).
|
||||
See the docs [here](https://github.com/atom/atom-shell/tree/master/docs).
|
||||
|
||||
## License
|
||||
|
||||
[MIT](https://github.com/electron/electron/blob/main/LICENSE)
|
||||
|
||||
When using the Electron or other GitHub logos, be sure to follow the [GitHub logo guidelines](https://github.com/logos).
|
||||
See the [`LICENSE`](LICENSE) file.
|
||||
|
||||
17
SECURITY.md
17
SECURITY.md
@@ -1,17 +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 [security@electronjs.org](mailto:security@electronjs.org) and include the word "SECURITY" in the subject line.
|
||||
|
||||
The Electron team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
||||
|
||||
Report security bugs in third-party modules to the person or team maintaining the module. You can also report a vulnerability through the [npm contact form](https://www.npmjs.com/support) by selecting "I'm reporting a security vulnerability".
|
||||
|
||||
## The Electron Security Notification Process
|
||||
|
||||
For context on Electron's security notification process, please see the [Notifications](https://github.com/electron/governance/blob/main/wg-security/membership-and-notifications.md#notifications) section of the Security WG's [Membership and Notifications](https://github.com/electron/governance/blob/main/wg-security/membership-and-notifications.md) Governance document.
|
||||
|
||||
## Learning More About Security
|
||||
|
||||
To learn more about securing an Electron application, please see the [security tutorial](docs/tutorial/security.md).
|
||||
15
app/atom_library_main.cc
Normal file
15
app/atom_library_main.cc
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "app/atom_library_main.h"
|
||||
|
||||
#include "app/atom_main_delegate.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
int AtomMain(int argc, const char* argv[]) {
|
||||
atom::AtomMainDelegate delegate;
|
||||
return content::ContentMain(argc, argv, &delegate);
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
17
app/atom_library_main.h
Normal file
17
app/atom_library_main.h
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_ATOM_LIBRARY_MAIN_
|
||||
#define ATOM_APP_ATOM_LIBRARY_MAIN_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
extern "C" {
|
||||
__attribute__((visibility("default")))
|
||||
int AtomMain(int argc, const char* argv[]);
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
|
||||
#endif // ATOM_APP_ATOM_LIBRARY_MAIN_
|
||||
83
app/atom_main.cc
Normal file
83
app/atom_main.cc
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "content/public/app/content_main.h"
|
||||
|
||||
namespace node {
|
||||
int Start(int argc, char *argv[]);
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
||||
#include <windows.h> // NOLINT
|
||||
#include <shellapi.h> // NOLINT
|
||||
|
||||
#include "app/atom_main_delegate.h"
|
||||
#include "content/public/app/startup_helper_win.h"
|
||||
#include "sandbox/win/src/sandbox_types.h"
|
||||
|
||||
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
||||
int argc = 0;
|
||||
wchar_t** wargv = ::CommandLineToArgvW(cmd, &argc);
|
||||
if (argc > 1 && wcscmp(wargv[1], L"--atom-child_process-fork") == 0) {
|
||||
// Convert argv to to UTF8
|
||||
char** argv = new char*[argc];
|
||||
for (int i = 0; i < argc; i++) {
|
||||
// Compute the size of the required buffer
|
||||
DWORD size = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wargv[i],
|
||||
-1,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (size == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
// Do the actual conversion
|
||||
argv[i] = new char[size];
|
||||
DWORD result = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
wargv[i],
|
||||
-1,
|
||||
argv[i],
|
||||
size,
|
||||
NULL,
|
||||
NULL);
|
||||
if (result == 0) {
|
||||
// This should never happen.
|
||||
fprintf(stderr, "Could not convert arguments to utf8.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
// Now that conversion is done, we can finally start.
|
||||
argv[1] = argv[0];
|
||||
return node::Start(argc - 1, argv + 1);
|
||||
}
|
||||
|
||||
sandbox::SandboxInterfaceInfo sandbox_info = {0};
|
||||
content::InitializeSandboxInfo(&sandbox_info);
|
||||
atom::AtomMainDelegate delegate;
|
||||
return content::ContentMain(instance, &sandbox_info, &delegate);
|
||||
}
|
||||
|
||||
#else // defined(OS_WIN)
|
||||
|
||||
#include "app/atom_library_main.h"
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
if (argc > 1 && strcmp(argv[1], "--atom-child_process-fork") == 0) {
|
||||
argv[1] = argv[0];
|
||||
return node::Start(argc - 1, const_cast<char**>(argv + 1));
|
||||
}
|
||||
|
||||
return AtomMain(argc, argv);
|
||||
}
|
||||
|
||||
#endif
|
||||
59
app/atom_main_delegate.cc
Normal file
59
app/atom_main_delegate.cc
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "app/atom_main_delegate.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/logging.h"
|
||||
#include "browser/atom_browser_client.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "renderer/atom_renderer_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomMainDelegate::AtomMainDelegate() {
|
||||
}
|
||||
|
||||
AtomMainDelegate::~AtomMainDelegate() {
|
||||
}
|
||||
|
||||
bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
// Disable logging out to debug.log on Windows
|
||||
#if defined(OS_WIN)
|
||||
logging::InitLogging(
|
||||
L"debug.log",
|
||||
#if defined(DEBUG)
|
||||
logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG ,
|
||||
#else
|
||||
logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
|
||||
#endif // defined(NDEBUG)
|
||||
logging::LOCK_LOG_FILE,
|
||||
logging::DELETE_OLD_LOG_FILE,
|
||||
logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS);
|
||||
logging::SetLogItems(true, false, true, false);
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
return brightray::MainDelegate::BasicStartupComplete(exit_code);
|
||||
}
|
||||
|
||||
void AtomMainDelegate::PreSandboxStartup() {
|
||||
brightray::MainDelegate::PreSandboxStartup();
|
||||
|
||||
// Disable renderer sandbox for most of node's functions.
|
||||
CommandLine* command_line = CommandLine::ForCurrentProcess();
|
||||
command_line->AppendSwitch(switches::kNoSandbox);
|
||||
}
|
||||
|
||||
content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
|
||||
browser_client_.reset(new AtomBrowserClient);
|
||||
return browser_client_.get();
|
||||
}
|
||||
|
||||
content::ContentRendererClient*
|
||||
AtomMainDelegate::CreateContentRendererClient() {
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
return renderer_client_.get();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
34
app/atom_main_delegate.h
Normal file
34
app/atom_main_delegate.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_APP_ATOM_MAIN_DELEGATE_
|
||||
#define ATOM_APP_ATOM_MAIN_DELEGATE_
|
||||
|
||||
#include "brightray/common/main_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomMainDelegate : public brightray::MainDelegate {
|
||||
public:
|
||||
AtomMainDelegate();
|
||||
~AtomMainDelegate();
|
||||
|
||||
protected:
|
||||
virtual bool BasicStartupComplete(int* exit_code) OVERRIDE;
|
||||
virtual void PreSandboxStartup() OVERRIDE;
|
||||
|
||||
private:
|
||||
virtual content::ContentBrowserClient* CreateContentBrowserClient() OVERRIDE;
|
||||
virtual content::ContentRendererClient*
|
||||
CreateContentRendererClient() OVERRIDE;
|
||||
|
||||
scoped_ptr<content::ContentBrowserClient> browser_client_;
|
||||
scoped_ptr<content::ContentRendererClient> renderer_client_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomMainDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_APP_ATOM_MAIN_DELEGATE_
|
||||
BIN
app/win/atom.rc
Normal file
BIN
app/win/atom.rc
Normal file
Binary file not shown.
14
app/win/resource.h
Normal file
14
app/win/resource.h
Normal file
@@ -0,0 +1,14 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by brightray_example.rc
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
233
appveyor.yml
233
appveyor.yml
@@ -1,233 +0,0 @@
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
|
||||
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
|
||||
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
|
||||
# https://gn.googlesource.com/gn/+/master/docs/reference.md#target_cpu
|
||||
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordningly
|
||||
# if you pass a custom value for 'target_cpu'.
|
||||
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
|
||||
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "TARGET_ARCH" value.
|
||||
# - "TARGET_ARCH" Choose from {'ia32', 'x64', 'arm', 'arm64', 'mips64el'}.
|
||||
# Is used in some publishing scripts, but does NOT affect the Electron binary.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
|
||||
# - "UPLOAD_TO_S3" Set it to '1' upload a release to the S3 bucket.
|
||||
# Otherwise the release will be uploaded to the Github Releases.
|
||||
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
|
||||
#
|
||||
# The publishing scripts expect access tokens to be defined as env vars,
|
||||
# but those are not covered here.
|
||||
#
|
||||
# AppVeyor docs on variables:
|
||||
# https://www.appveyor.com/docs/environment-variables/
|
||||
# https://www.appveyor.com/docs/build-configuration/#secure-variables
|
||||
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
|
||||
|
||||
# Uncomment these lines to enable RDP
|
||||
#on_finish:
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electron-16-core
|
||||
image: vs2019bt-16.6.2
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\electron\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
GOMA_FALLBACK_ON_AUTH_FAILURE: true
|
||||
notifications:
|
||||
- provider: Webhook
|
||||
url: https://electron-mission-control.herokuapp.com/rest/appveyor-hook
|
||||
method: POST
|
||||
headers:
|
||||
x-mission-control-secret:
|
||||
secure: 90BLVPcqhJPG7d24v0q/RRray6W3wDQ8uVQlQjOHaBWkw1i8FoA1lsjr2C/v1dVok+tS2Pi6KxDctPUkwIb4T27u4RhvmcPzQhVpfwVJAG9oNtq+yKN7vzHfg7k/pojEzVdJpQLzeJGcSrZu7VY39Q==
|
||||
on_build_success: false
|
||||
on_build_failure: true
|
||||
on_build_status_changed: false
|
||||
build_script:
|
||||
- ps: >-
|
||||
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
|
||||
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
|
||||
} else {
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
|
||||
$result = node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
|
||||
Write-Output $result
|
||||
if ($result.ExitCode -eq 0) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
}
|
||||
- echo "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
- cd ..
|
||||
- mkdir src
|
||||
- update_depot_tools.bat
|
||||
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
|
||||
}
|
||||
- >-
|
||||
gclient config
|
||||
--name "src\electron"
|
||||
--unmanaged
|
||||
%GCLIENT_EXTRA_ARGS%
|
||||
"https://github.com/electron/electron"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
} else {
|
||||
cd src\electron
|
||||
node script\generate-deps-hash.js
|
||||
$depshash = Get-Content .\.depshash -Raw
|
||||
$zipfile = "Z:\$depshash.7z"
|
||||
cd ..\..
|
||||
if (Test-Path -Path $zipfile) {
|
||||
# file exists, unzip and then gclient sync
|
||||
7z x -y $zipfile -mmt=30 -aoa
|
||||
if (-not (Test-Path -Path "src\buildtools")) {
|
||||
# the zip file must be corrupt - resync
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
if ($env:TARGET_ARCH -ne 'ia32') {
|
||||
# only save on x64/woa to avoid contention saving
|
||||
$env:SAVE_GCLIENT_SRC="true"
|
||||
}
|
||||
} else {
|
||||
# update angle
|
||||
cd src\third_party\angle
|
||||
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
|
||||
git fetch
|
||||
cd ..\..\..
|
||||
}
|
||||
} else {
|
||||
# file does not exist, gclient sync, then zip
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
if ($env:TARGET_ARCH -ne 'ia32') {
|
||||
# only save on x64/woa to avoid contention saving
|
||||
$env:SAVE_GCLIENT_SRC="true"
|
||||
}
|
||||
}
|
||||
}
|
||||
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync )
|
||||
- ps: >-
|
||||
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
|
||||
# archive current source for future use
|
||||
# only run on x64/woa to avoid contention saving
|
||||
$(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30)
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-warning "Could not save source to shared drive; continuing anyway"
|
||||
}
|
||||
# build time generation of file gen/angle/angle_commit.h depends on
|
||||
# third_party/angle/.git
|
||||
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
|
||||
$(7z a $zipfile src\third_party\angle\.git)
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-warning "Failed to add third_party\angle\.git; continuing anyway"
|
||||
}
|
||||
}
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
|
||||
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
|
||||
}
|
||||
- git clone https://github.com/electron/build-tools.git
|
||||
- cd build-tools
|
||||
- npm install
|
||||
- mkdir third_party
|
||||
- ps: >-
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
- cd ..
|
||||
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
- cd src
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron/shell/common/api:mojo
|
||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
|
||||
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- ninja -C out/Default electron:electron_dist_zip
|
||||
- ninja -C out/Default shell_browser_ui_unittests
|
||||
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
|
||||
- ninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- cd out\Default
|
||||
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
|
||||
- cd ..\..
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- appveyor PushArtifact out/Default/windows_toolchain_profile.json
|
||||
- appveyor PushArtifact out/Default/dist.zip
|
||||
- appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
|
||||
- appveyor PushArtifact out/Default/chromedriver.zip
|
||||
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- appveyor PushArtifact node_headers.zip
|
||||
- appveyor PushArtifact out/Default/mksnapshot.zip
|
||||
- appveyor PushArtifact out/Default/hunspell_dictionaries.zip
|
||||
- appveyor PushArtifact out/Default/electron.lib
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python electron\script\zip-symbols.py
|
||||
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
|
||||
} else {
|
||||
# It's useful to have pdb files when debugging testing builds that are
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
appveyor-retry appveyor PushArtifact pdb.zip
|
||||
}
|
||||
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
- ps: >-
|
||||
if ((-Not (Test-Path Env:\TEST_WOA)) -And (-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
|
||||
$env:RUN_TESTS="true"
|
||||
}
|
||||
- ps: >-
|
||||
if ($env:RUN_TESTS -eq 'true') {
|
||||
New-Item .\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
|
||||
} else {
|
||||
echo "Skipping tests for $env:GN_CONFIG build"
|
||||
}
|
||||
- cd electron
|
||||
# CalculateNativeWinOcclusion is disabled due to https://bugs.chromium.org/p/chromium/issues/detail?id=1139022
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --trace-uncaught --enable-logging --disable-features=CalculateNativeWinOcclusion )
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying mksnapshot"
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
|
||||
- echo "Done verifying chromedriver"
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\UPLOAD_TO_S3) {
|
||||
Write-Output "Uploading Electron release distribution to s3"
|
||||
& python script\release\uploaders\upload.py --verbose --upload_to_s3
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python script\release\uploaders\upload.py --verbose
|
||||
}
|
||||
} elseif (Test-Path Env:\TEST_WOA) {
|
||||
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
}
|
||||
473
atom.gyp
Normal file
473
atom.gyp
Normal file
@@ -0,0 +1,473 @@
|
||||
{
|
||||
'variables': {
|
||||
'project_name': 'atom',
|
||||
'product_name': 'Atom',
|
||||
'app_sources': [
|
||||
'app/atom_main.cc',
|
||||
],
|
||||
'bundle_sources': [
|
||||
'browser/mac/atom.icns',
|
||||
],
|
||||
'coffee_sources': [
|
||||
'browser/api/lib/app.coffee',
|
||||
'browser/api/lib/atom-delegate.coffee',
|
||||
'browser/api/lib/auto-updater.coffee',
|
||||
'browser/api/lib/browser-window.coffee',
|
||||
'browser/api/lib/crash-reporter.coffee',
|
||||
'browser/api/lib/dialog.coffee',
|
||||
'browser/api/lib/ipc.coffee',
|
||||
'browser/api/lib/menu.coffee',
|
||||
'browser/api/lib/menu-item.coffee',
|
||||
'browser/api/lib/power-monitor.coffee',
|
||||
'browser/atom/atom.coffee',
|
||||
'browser/atom/objects-registry.coffee',
|
||||
'browser/atom/rpc-server.coffee',
|
||||
'common/api/lib/callbacks-registry.coffee',
|
||||
'common/api/lib/clipboard.coffee',
|
||||
'common/api/lib/id-weak-map.coffee',
|
||||
'common/api/lib/shell.coffee',
|
||||
'renderer/api/lib/ipc.coffee',
|
||||
'renderer/api/lib/remote.coffee',
|
||||
],
|
||||
'lib_sources': [
|
||||
'app/atom_main_delegate.cc',
|
||||
'app/atom_main_delegate.h',
|
||||
'browser/api/atom_api_app.cc',
|
||||
'browser/api/atom_api_app.h',
|
||||
'browser/api/atom_api_auto_updater.cc',
|
||||
'browser/api/atom_api_auto_updater.h',
|
||||
'browser/api/atom_api_browser_ipc.cc',
|
||||
'browser/api/atom_api_browser_ipc.h',
|
||||
'browser/api/atom_api_crash_reporter.h',
|
||||
'browser/api/atom_api_crash_reporter.cc',
|
||||
'browser/api/atom_api_dialog.cc',
|
||||
'browser/api/atom_api_dialog.h',
|
||||
'browser/api/atom_api_event.cc',
|
||||
'browser/api/atom_api_event.h',
|
||||
'browser/api/atom_api_event_emitter.cc',
|
||||
'browser/api/atom_api_event_emitter.h',
|
||||
'browser/api/atom_api_menu.cc',
|
||||
'browser/api/atom_api_menu.h',
|
||||
'browser/api/atom_api_menu_mac.h',
|
||||
'browser/api/atom_api_menu_mac.mm',
|
||||
'browser/api/atom_api_menu_win.cc',
|
||||
'browser/api/atom_api_menu_win.h',
|
||||
'browser/api/atom_api_power_monitor.cc',
|
||||
'browser/api/atom_api_power_monitor.h',
|
||||
'browser/api/atom_api_window.cc',
|
||||
'browser/api/atom_api_window.h',
|
||||
'browser/api/atom_browser_bindings.cc',
|
||||
'browser/api/atom_browser_bindings.h',
|
||||
'browser/auto_updater.cc',
|
||||
'browser/auto_updater.h',
|
||||
'browser/auto_updater_delegate.cc',
|
||||
'browser/auto_updater_delegate.h',
|
||||
'browser/auto_updater_mac.mm',
|
||||
'browser/auto_updater_win.cc',
|
||||
'browser/atom_application_mac.h',
|
||||
'browser/atom_application_mac.mm',
|
||||
'browser/atom_application_delegate_mac.h',
|
||||
'browser/atom_application_delegate_mac.mm',
|
||||
'browser/atom_browser_client.cc',
|
||||
'browser/atom_browser_client.h',
|
||||
'browser/atom_browser_context.cc',
|
||||
'browser/atom_browser_context.h',
|
||||
'browser/atom_browser_main_parts.cc',
|
||||
'browser/atom_browser_main_parts.h',
|
||||
'browser/atom_browser_main_parts_mac.mm',
|
||||
'browser/atom_event_processing_window.h',
|
||||
'browser/atom_event_processing_window.mm',
|
||||
'browser/atom_javascript_dialog_manager.cc',
|
||||
'browser/atom_javascript_dialog_manager.h',
|
||||
'browser/browser.cc',
|
||||
'browser/browser.h',
|
||||
'browser/browser_mac.mm',
|
||||
'browser/browser_win.cc',
|
||||
'browser/browser_observer.h',
|
||||
'browser/crash_reporter.h',
|
||||
'browser/crash_reporter_mac.mm',
|
||||
'browser/crash_reporter_win.cc',
|
||||
'browser/native_window.cc',
|
||||
'browser/native_window.h',
|
||||
'browser/native_window_mac.h',
|
||||
'browser/native_window_mac.mm',
|
||||
'browser/native_window_win.cc',
|
||||
'browser/native_window_win.h',
|
||||
'browser/native_window_observer.h',
|
||||
'browser/ui/accelerator_util.cc',
|
||||
'browser/ui/accelerator_util.h',
|
||||
'browser/ui/accelerator_util_mac.mm',
|
||||
'browser/ui/accelerator_util_win.cc',
|
||||
'browser/ui/atom_menu_controller_mac.h',
|
||||
'browser/ui/atom_menu_controller_mac.mm',
|
||||
'browser/ui/file_dialog.h',
|
||||
'browser/ui/file_dialog_mac.mm',
|
||||
'browser/ui/file_dialog_win.cc',
|
||||
'browser/ui/message_box.h',
|
||||
'browser/ui/message_box_mac.mm',
|
||||
'browser/ui/message_box_win.cc',
|
||||
'browser/ui/nsalert_synchronous_sheet_mac.h',
|
||||
'browser/ui/nsalert_synchronous_sheet_mac.mm',
|
||||
'browser/ui/win/menu_2.cc',
|
||||
'browser/ui/win/menu_2.h',
|
||||
'browser/ui/win/native_menu_win.cc',
|
||||
'browser/ui/win/native_menu_win.h',
|
||||
'browser/window_list.cc',
|
||||
'browser/window_list.h',
|
||||
'browser/window_list_observer.h',
|
||||
'common/api/api_messages.cc',
|
||||
'common/api/api_messages.h',
|
||||
'common/api/atom_api_clipboard.cc',
|
||||
'common/api/atom_api_clipboard.h',
|
||||
'common/api/atom_api_id_weak_map.cc',
|
||||
'common/api/atom_api_id_weak_map.h',
|
||||
'common/api/atom_api_shell.cc',
|
||||
'common/api/atom_api_shell.h',
|
||||
'common/api/atom_api_v8_util.cc',
|
||||
'common/api/atom_bindings.cc',
|
||||
'common/api/atom_bindings.h',
|
||||
'common/api/atom_extensions.cc',
|
||||
'common/api/atom_extensions.h',
|
||||
'common/api/object_life_monitor.cc',
|
||||
'common/api/object_life_monitor.h',
|
||||
'common/node_bindings.cc',
|
||||
'common/node_bindings.h',
|
||||
'common/node_bindings_mac.cc',
|
||||
'common/node_bindings_mac.h',
|
||||
'common/node_bindings_win.cc',
|
||||
'common/node_bindings_win.h',
|
||||
'common/options_switches.cc',
|
||||
'common/options_switches.h',
|
||||
'common/platform_util.h',
|
||||
'common/platform_util_mac.mm',
|
||||
'common/platform_util_win.cc',
|
||||
'common/v8_value_converter_impl.cc',
|
||||
'common/v8_value_converter_impl.h',
|
||||
'renderer/api/atom_api_renderer_ipc.cc',
|
||||
'renderer/api/atom_api_renderer_ipc.h',
|
||||
'renderer/api/atom_renderer_bindings.cc',
|
||||
'renderer/api/atom_renderer_bindings.h',
|
||||
'renderer/atom_render_view_observer.cc',
|
||||
'renderer/atom_render_view_observer.h',
|
||||
'renderer/atom_renderer_client.cc',
|
||||
'renderer/atom_renderer_client.h',
|
||||
],
|
||||
'framework_sources': [
|
||||
'app/atom_library_main.cc',
|
||||
'app/atom_library_main.h',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'app_sources': [
|
||||
'app/win/resource.h',
|
||||
'app/win/atom.rc',
|
||||
'<(libchromiumcontent_src_dir)/content/app/startup_helper_win.cc',
|
||||
],
|
||||
}], # OS=="win"
|
||||
],
|
||||
'fix_framework_link_command': [
|
||||
'install_name_tool',
|
||||
'-change',
|
||||
'@loader_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle',
|
||||
'@rpath/Sparkle.framework/Versions/A/Sparkle',
|
||||
'-change',
|
||||
'@executable_path/../Frameworks/Quincy.framework/Versions/A/Quincy',
|
||||
'@rpath/Quincy.framework/Versions/A/Quincy',
|
||||
'${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}'
|
||||
],
|
||||
'atom_source_root': '<!(python tools/atom_source_root.py)',
|
||||
},
|
||||
'target_defaults': {
|
||||
'mac_framework_dirs': [
|
||||
'<(atom_source_root)/frameworks',
|
||||
],
|
||||
'includes': [
|
||||
# Rules for excluding e.g. foo_win.cc from the build on non-Windows.
|
||||
'filename_rules.gypi',
|
||||
],
|
||||
'configurations': {
|
||||
'Debug': {
|
||||
'defines': [
|
||||
'DEBUG',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': '<(project_name)',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'generated_sources',
|
||||
'<(project_name)_lib',
|
||||
],
|
||||
'sources': [
|
||||
'<@(app_sources)',
|
||||
],
|
||||
'include_dirs': [
|
||||
'.',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'product_name': '<(product_name)',
|
||||
'mac_bundle': 1,
|
||||
'dependencies!': [
|
||||
'<(project_name)_lib',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(project_name)_framework',
|
||||
'<(project_name)_helper',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'INFOPLIST_FILE': 'browser/mac/Info.plist',
|
||||
'LD_RUNPATH_SEARCH_PATHS': [
|
||||
'@executable_path/../Frameworks',
|
||||
],
|
||||
},
|
||||
'mac_bundle_resources': [
|
||||
'<@(bundle_sources)',
|
||||
],
|
||||
'copies': [
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Frameworks',
|
||||
'files': [
|
||||
'<(PRODUCT_DIR)/<(product_name) Helper.app',
|
||||
'<(PRODUCT_DIR)/<(product_name).framework',
|
||||
'frameworks/Sparkle.framework',
|
||||
'frameworks/Quincy.framework',
|
||||
],
|
||||
},
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name).app/Contents/Resources/browser',
|
||||
'files': [
|
||||
'browser/default_app',
|
||||
],
|
||||
},
|
||||
],
|
||||
'postbuilds': [
|
||||
{
|
||||
'postbuild_name': 'Fix Framework Link',
|
||||
'action': [
|
||||
'<@(fix_framework_link_command)',
|
||||
],
|
||||
},
|
||||
{
|
||||
# This postbuid step is responsible for creating the following
|
||||
# helpers:
|
||||
#
|
||||
# <(product_name) EH.app and <(product_name) NP.app are created
|
||||
# from <(product_name).app.
|
||||
#
|
||||
# The EH helper is marked for an executable heap. The NP helper
|
||||
# is marked for no PIE (ASLR).
|
||||
'postbuild_name': 'Make More Helpers',
|
||||
'action': [
|
||||
'vendor/brightray/tools/mac/make_more_helpers.sh',
|
||||
'Frameworks',
|
||||
'<(product_name)',
|
||||
],
|
||||
},
|
||||
]
|
||||
}], # OS=="mac"
|
||||
['OS=="win"', {
|
||||
'copies': [
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)',
|
||||
'files': [
|
||||
'<(libchromiumcontent_library_dir)/chromiumcontent.dll',
|
||||
'<(libchromiumcontent_library_dir)/icudt.dll',
|
||||
'<(libchromiumcontent_library_dir)/libGLESv2.dll',
|
||||
'<(libchromiumcontent_resources_dir)/content_shell.pak',
|
||||
],
|
||||
},
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/resources/browser',
|
||||
'files': [
|
||||
'browser/default_app',
|
||||
]
|
||||
},
|
||||
],
|
||||
}], # OS=="win"
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': '<(project_name)_lib',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'vendor/brightray/brightray.gyp:brightray',
|
||||
'vendor/node/node.gyp:node',
|
||||
],
|
||||
'sources': [
|
||||
'<@(lib_sources)',
|
||||
],
|
||||
'include_dirs': [
|
||||
'.',
|
||||
'vendor',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'.',
|
||||
],
|
||||
},
|
||||
'export_dependent_settings': [
|
||||
'vendor/brightray/brightray.gyp:brightray',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'-limm32.lib',
|
||||
'-loleacc.lib',
|
||||
'-lComdlg32.lib',
|
||||
'<(atom_source_root)/<(libchromiumcontent_library_dir)/chromiumviews.lib',
|
||||
],
|
||||
},
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'generated_sources',
|
||||
'type': 'none',
|
||||
'sources': [
|
||||
'<@(coffee_sources)',
|
||||
],
|
||||
'rules': [
|
||||
{
|
||||
'rule_name': 'coffee',
|
||||
'extension': 'coffee',
|
||||
'inputs': [
|
||||
'script/compile-coffee.py',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'outputs': [
|
||||
'<(PRODUCT_DIR)/<(product_name).app/Contents/Resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'script/compile-coffee.py',
|
||||
'<(RULE_INPUT_PATH)',
|
||||
'<(PRODUCT_DIR)/<(product_name).app/Contents/Resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
|
||||
],
|
||||
}], # OS=="mac"
|
||||
['OS=="win"', {
|
||||
'outputs': [
|
||||
'<(PRODUCT_DIR)/resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
|
||||
],
|
||||
'action': [
|
||||
'python',
|
||||
'script/compile-coffee.py',
|
||||
'<(RULE_INPUT_PATH)',
|
||||
'<(PRODUCT_DIR)/resources/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).js',
|
||||
],
|
||||
}], # OS=="win"
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': '<(project_name)_framework',
|
||||
'product_name': '<(product_name)',
|
||||
'type': 'shared_library',
|
||||
'dependencies': [
|
||||
'<(project_name)_lib',
|
||||
],
|
||||
'sources': [
|
||||
'<@(framework_sources)',
|
||||
],
|
||||
'include_dirs': [
|
||||
'.',
|
||||
'vendor',
|
||||
'<(libchromiumcontent_include_dir)',
|
||||
],
|
||||
'export_dependent_settings': [
|
||||
'<(project_name)_lib',
|
||||
],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
|
||||
'frameworks/Sparkle.framework',
|
||||
'frameworks/Quincy.framework',
|
||||
],
|
||||
},
|
||||
'mac_bundle': 1,
|
||||
'mac_bundle_resources': [
|
||||
'browser/mac/MainMenu.xib',
|
||||
'<(libchromiumcontent_resources_dir)/content_shell.pak',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'LIBRARY_SEARCH_PATHS': [
|
||||
'<(libchromiumcontent_library_dir)',
|
||||
],
|
||||
'LD_DYLIB_INSTALL_NAME': '@rpath/<(product_name).framework/<(product_name)',
|
||||
'LD_RUNPATH_SEARCH_PATHS': [
|
||||
'@loader_path/Libraries',
|
||||
],
|
||||
'OTHER_LDFLAGS': [
|
||||
'-ObjC',
|
||||
],
|
||||
},
|
||||
'copies': [
|
||||
{
|
||||
'destination': '<(PRODUCT_DIR)/<(product_name).framework/Versions/A/Libraries',
|
||||
'files': [
|
||||
'<(libchromiumcontent_library_dir)/ffmpegsumo.so',
|
||||
'<(libchromiumcontent_library_dir)/libchromiumcontent.dylib',
|
||||
],
|
||||
},
|
||||
],
|
||||
'postbuilds': [
|
||||
{
|
||||
'postbuild_name': 'Fix Framework Link',
|
||||
'action': [
|
||||
'<@(fix_framework_link_command)',
|
||||
],
|
||||
},
|
||||
{
|
||||
'postbuild_name': 'Add symlinks for framework subdirectories',
|
||||
'action': [
|
||||
'tools/mac/create-framework-subdir-symlinks.sh',
|
||||
'<(product_name)',
|
||||
'Libraries',
|
||||
'Frameworks',
|
||||
],
|
||||
},
|
||||
],
|
||||
}, # target framework
|
||||
{
|
||||
'target_name': '<(project_name)_helper',
|
||||
'product_name': '<(product_name) Helper',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'<(project_name)_framework',
|
||||
],
|
||||
'sources': [
|
||||
'<@(app_sources)',
|
||||
],
|
||||
'include_dirs': [
|
||||
'.',
|
||||
],
|
||||
'mac_bundle': 1,
|
||||
'xcode_settings': {
|
||||
'INFOPLIST_FILE': 'renderer/mac/Info.plist',
|
||||
'LD_RUNPATH_SEARCH_PATHS': [
|
||||
'@executable_path/../../..',
|
||||
],
|
||||
},
|
||||
'postbuilds': [
|
||||
{
|
||||
'postbuild_name': 'Fix Framework Link',
|
||||
'action': [
|
||||
'<@(fix_framework_link_command)',
|
||||
],
|
||||
},
|
||||
],
|
||||
}, # target helper
|
||||
],
|
||||
}], # OS==Mac
|
||||
],
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
steps:
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Files to: src/electron'
|
||||
inputs:
|
||||
TargetFolder: src/electron
|
||||
|
||||
- bash: |
|
||||
cd src/electron
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
displayName: 'Yarn install'
|
||||
|
||||
- bash: |
|
||||
export ZIP_DEST=$PWD/src/out/Default
|
||||
echo "##vso[task.setvariable variable=ZIP_DEST]$ZIP_DEST"
|
||||
mkdir -p $ZIP_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=dist.zip --dest=$ZIP_DEST
|
||||
cd $ZIP_DEST
|
||||
unzip -o dist.zip
|
||||
xattr -cr Electron.app
|
||||
displayName: 'Download and unzip dist files for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export FFMPEG_ZIP_DEST=$PWD/src/out/ffmpeg
|
||||
mkdir -p $FFMPEG_ZIP_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=ffmpeg.zip --dest=$FFMPEG_ZIP_DEST
|
||||
cd $FFMPEG_ZIP_DEST
|
||||
unzip -o ffmpeg.zip
|
||||
displayName: 'Download and unzip ffmpeg for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export NODE_HEADERS_DEST=$PWD/src/out/Default/gen
|
||||
mkdir -p $NODE_HEADERS_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=node_headers.tar.gz --dest=$NODE_HEADERS_DEST
|
||||
cd $NODE_HEADERS_DEST
|
||||
tar xzf node_headers.tar.gz
|
||||
displayName: 'Download and untar node header files for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export CROSS_ARCH_SNAPSHOTS=$PWD/src/out/Default/cross-arch-snapshots
|
||||
mkdir -p $CROSS_ARCH_SNAPSHOTS
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/snapshot_blob.bin --dest=$CROSS_ARCH_SNAPSHOTS
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/v8_context_snapshot.arm64.bin --dest=$CROSS_ARCH_SNAPSHOTS
|
||||
displayName: 'Download cross arch snapshot files'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
export ELECTRON_OUT_DIR=Default
|
||||
export npm_config_arch=arm64
|
||||
(cd electron && node script/yarn test --enable-logging --runners main)
|
||||
displayName: 'Run Electron main tests'
|
||||
timeoutInMinutes: 20
|
||||
env:
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
export ELECTRON_OUT_DIR=Default
|
||||
export npm_config_arch=arm64
|
||||
(cd electron && node script/yarn test --enable-logging --runners remote)
|
||||
displayName: 'Run Electron remote tests'
|
||||
timeoutInMinutes: 20
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
python electron/script/verify-ffmpeg.py --source-root "$PWD" --build-dir out/Default --ffmpeg-path out/ffmpeg
|
||||
displayName: Verify non proprietary ffmpeg
|
||||
timeoutInMinutes: 5
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
TARGET_ARCH: arm64
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
echo Verify cross arch snapshot
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/out/Default/cross-arch-snapshots
|
||||
displayName: Verify cross arch snapshot
|
||||
timeoutInMinutes: 5
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results'
|
||||
inputs:
|
||||
testResultsFiles: '*.xml'
|
||||
|
||||
searchFolder: '$(System.DefaultWorkingDirectory)/src/junit/'
|
||||
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- bash: killall Electron || echo "No Electron processes left running"
|
||||
displayName: 'Kill processes left running from last test run'
|
||||
condition: always()
|
||||
|
||||
- bash: |
|
||||
rm -rf ~/Library/Application\ Support/Electron*
|
||||
rm -rf ~/Library/Application\ Support/electron*
|
||||
displayName: 'Delete user app data directories'
|
||||
condition: always()
|
||||
|
||||
- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
|
||||
displayName: 'Clean Agent Directories'
|
||||
|
||||
condition: always()
|
||||
@@ -1,129 +0,0 @@
|
||||
steps:
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Files to: src\electron'
|
||||
inputs:
|
||||
TargetFolder: src\electron
|
||||
|
||||
- script: |
|
||||
cd src\electron
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
displayName: 'Yarn install'
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$pwd\dist.zip"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/dist.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\Default -y $localArtifactPath
|
||||
displayName: 'Download and extract dist.zip for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$pwd\src\out\Default\shell_browser_ui_unittests.exe"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/shell_browser_ui_unittests.exe"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
displayName: 'Download and extract native test executables for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$pwd\ffmpeg.zip"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/ffmpeg.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\ffmpeg $localArtifactPath
|
||||
displayName: 'Download and extract ffmpeg.zip for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$pwd\src\node_headers.zip"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/node_headers.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
cd src
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y node_headers.zip
|
||||
displayName: 'Download node headers for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
$localArtifactPath = "$pwd\src\out\Default\electron.lib"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/electron.lib"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
displayName: 'Download electron.lib for test'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
try {
|
||||
$localArtifactPath = "$pwd\src\pdb.zip"
|
||||
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/pdb.zip"
|
||||
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
|
||||
cd src
|
||||
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y pdb.zip
|
||||
} catch {
|
||||
Write-Host "There was an exception encountered while downloading pdb files:" $_.Exception.Message
|
||||
} finally {
|
||||
$global:LASTEXITCODE = 0
|
||||
}
|
||||
displayName: 'Download pdb files for detailed stacktraces'
|
||||
env:
|
||||
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
|
||||
|
||||
- powershell: |
|
||||
New-Item src\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path src\out\Default\electron.lib -destination src\out\Default\gen\node_headers\Release\node.lib
|
||||
displayName: 'Setup node headers'
|
||||
|
||||
- script: |
|
||||
cd src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=main --runTestFilesSeperately --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
displayName: 'Run Electron Main process tests'
|
||||
env:
|
||||
ELECTRON_ENABLE_STACK_DUMPING: true
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
|
||||
- script: |
|
||||
cd src
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
displayName: 'Run Electron Remote based tests'
|
||||
env:
|
||||
ELECTRON_OUT_DIR: Default
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
condition: always()
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results'
|
||||
inputs:
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: '$(System.DefaultWorkingDirectory)/src/junit/'
|
||||
condition: always()
|
||||
|
||||
- script: |
|
||||
cd src
|
||||
echo "Verifying non proprietary ffmpeg"
|
||||
python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
displayName: 'Verify ffmpeg'
|
||||
|
||||
- powershell: |
|
||||
Get-Process | Where Name –Like "electron*" | Stop-Process
|
||||
Get-Process | Where Name –Like "msedge*" | Stop-Process
|
||||
displayName: 'Kill processes left running from last test run'
|
||||
condition: always()
|
||||
|
||||
- powershell: |
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse -Force -ErrorAction Ignore
|
||||
displayName: 'Delete user app data directories'
|
||||
condition: always()
|
||||
211
browser/api/atom_api_app.cc
Normal file
211
browser/api/atom_api_app.cc
Normal file
@@ -0,0 +1,211 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_app.h"
|
||||
|
||||
#include "base/values.h"
|
||||
#include "base/command_line.h"
|
||||
#include "browser/browser.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
App::App(v8::Handle<v8::Object> wrapper)
|
||||
: EventEmitter(wrapper) {
|
||||
Browser::Get()->AddObserver(this);
|
||||
}
|
||||
|
||||
App::~App() {
|
||||
Browser::Get()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void App::OnWillQuit(bool* prevent_default) {
|
||||
*prevent_default = Emit("will-quit");
|
||||
}
|
||||
|
||||
void App::OnWindowAllClosed() {
|
||||
Emit("window-all-closed");
|
||||
}
|
||||
|
||||
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
|
||||
base::ListValue args;
|
||||
args.AppendString(file_path);
|
||||
*prevent_default = Emit("open-file", &args);
|
||||
}
|
||||
|
||||
void App::OnOpenURL(const std::string& url) {
|
||||
base::ListValue args;
|
||||
args.AppendString(url);
|
||||
Emit("open-url", &args);
|
||||
}
|
||||
|
||||
void App::OnWillFinishLaunching() {
|
||||
Emit("will-finish-launching");
|
||||
}
|
||||
|
||||
void App::OnFinishLaunching() {
|
||||
Emit("finish-launching");
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::New(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args.IsConstructCall())
|
||||
return node::ThrowError("Require constructor call");
|
||||
|
||||
new App(args.This());
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::Quit(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
Browser::Get()->Quit();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::Exit(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
exit(args[0]->IntegerValue());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::Terminate(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
Browser::Get()->Terminate();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::Focus(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
Browser::Get()->Focus();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::GetVersion(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
std::string version(Browser::Get()->GetVersion());
|
||||
|
||||
return v8::String::New(version.data(), version.size());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::AppendSwitch(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsString())
|
||||
return node::ThrowError("Bad argument");
|
||||
|
||||
std::string switch_string(*v8::String::Utf8Value(args[0]));
|
||||
if (args.Length() == 1) {
|
||||
CommandLine::ForCurrentProcess()->AppendSwitch(switch_string);
|
||||
} else {
|
||||
std::string value(*v8::String::Utf8Value(args[1]));
|
||||
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
|
||||
switch_string, value);
|
||||
}
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::AppendArgument(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsString())
|
||||
return node::ThrowError("Bad argument");
|
||||
|
||||
std::string value(*v8::String::Utf8Value(args[0]));
|
||||
CommandLine::ForCurrentProcess()->AppendArg(value);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::DockBounce(const v8::Arguments& args) {
|
||||
std::string type(*v8::String::Utf8Value(args[0]));
|
||||
int request_id = -1;
|
||||
|
||||
if (type == "critical")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_CRITICAL);
|
||||
else if (type == "informational")
|
||||
request_id = Browser::Get()->DockBounce(Browser::BOUNCE_INFORMATIONAL);
|
||||
else
|
||||
return node::ThrowTypeError("Invalid bounce type");
|
||||
|
||||
return v8::Integer::New(request_id);
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::DockCancelBounce(const v8::Arguments& args) {
|
||||
Browser::Get()->DockCancelBounce(args[0]->IntegerValue());
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::DockSetBadgeText(const v8::Arguments& args) {
|
||||
std::string label(*v8::String::Utf8Value(args[0]));
|
||||
Browser::Get()->DockSetBadgeText(label);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> App::DockGetBadgeText(const v8::Arguments& args) {
|
||||
std::string text(Browser::Get()->DockGetBadgeText());
|
||||
return v8::String::New(text.data(), text.size());
|
||||
}
|
||||
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
// static
|
||||
void App::Initialize(v8::Handle<v8::Object> target) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(App::New);
|
||||
t->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
t->SetClassName(v8::String::NewSymbol("Application"));
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "quit", Quit);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "exit", Exit);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "terminate", Terminate);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "focus", Focus);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getVersion", GetVersion);
|
||||
|
||||
target->Set(v8::String::NewSymbol("Application"), t->GetFunction());
|
||||
|
||||
NODE_SET_METHOD(target, "appendSwitch", AppendSwitch);
|
||||
NODE_SET_METHOD(target, "appendArgument", AppendArgument);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
NODE_SET_METHOD(target, "dockBounce", DockBounce);
|
||||
NODE_SET_METHOD(target, "dockCancelBounce", DockCancelBounce);
|
||||
NODE_SET_METHOD(target, "dockSetBadgeText", DockSetBadgeText);
|
||||
NODE_SET_METHOD(target, "dockGetBadgeText", DockGetBadgeText);
|
||||
#endif // defined(OS_MACOSX)
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
NODE_MODULE(atom_browser_app, atom::api::App::Initialize)
|
||||
60
browser/api/atom_api_app.h
Normal file
60
browser/api/atom_api_app.h
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "browser/api/atom_api_event_emitter.h"
|
||||
#include "browser/browser_observer.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class App : public EventEmitter,
|
||||
public BrowserObserver {
|
||||
public:
|
||||
virtual ~App();
|
||||
|
||||
static void Initialize(v8::Handle<v8::Object> target);
|
||||
|
||||
protected:
|
||||
explicit App(v8::Handle<v8::Object> wrapper);
|
||||
|
||||
// BrowserObserver implementations:
|
||||
virtual void OnWillQuit(bool* prevent_default) OVERRIDE;
|
||||
virtual void OnWindowAllClosed() OVERRIDE;
|
||||
virtual void OnOpenFile(bool* prevent_default,
|
||||
const std::string& file_path) OVERRIDE;
|
||||
virtual void OnOpenURL(const std::string& url) OVERRIDE;
|
||||
virtual void OnWillFinishLaunching() OVERRIDE;
|
||||
virtual void OnFinishLaunching() OVERRIDE;
|
||||
|
||||
private:
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments &args);
|
||||
|
||||
static v8::Handle<v8::Value> Quit(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Exit(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Terminate(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Focus(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetVersion(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> AppendSwitch(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> AppendArgument(const v8::Arguments &args);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
static v8::Handle<v8::Value> DockBounce(const v8::Arguments& args);
|
||||
static v8::Handle<v8::Value> DockCancelBounce(const v8::Arguments& args);
|
||||
static v8::Handle<v8::Value> DockSetBadgeText(const v8::Arguments& args);
|
||||
static v8::Handle<v8::Value> DockGetBadgeText(const v8::Arguments& args);
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(App);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
137
browser/api/atom_api_auto_updater.cc
Normal file
137
browser/api/atom_api_auto_updater.cc
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_auto_updater.h"
|
||||
|
||||
#include "base/values.h"
|
||||
#include "browser/auto_updater.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
AutoUpdater::AutoUpdater(v8::Handle<v8::Object> wrapper)
|
||||
: EventEmitter(wrapper) {
|
||||
auto_updater::AutoUpdater::SetDelegate(this);
|
||||
auto_updater::AutoUpdater::Init();
|
||||
}
|
||||
|
||||
AutoUpdater::~AutoUpdater() {
|
||||
auto_updater::AutoUpdater::SetDelegate(NULL);
|
||||
}
|
||||
|
||||
void AutoUpdater::WillInstallUpdate(const std::string& version,
|
||||
const base::Closure& install) {
|
||||
continue_update_ = install;
|
||||
|
||||
base::ListValue args;
|
||||
args.AppendString(version);
|
||||
bool prevent_default = Emit("will-install-update-raw", &args);
|
||||
|
||||
if (!prevent_default)
|
||||
install.Run();
|
||||
}
|
||||
|
||||
void AutoUpdater::ReadyForUpdateOnQuit(const std::string& version,
|
||||
const base::Closure& quit_and_install) {
|
||||
quit_and_install_ = quit_and_install;
|
||||
|
||||
base::ListValue args;
|
||||
args.AppendString(version);
|
||||
Emit("ready-for-update-on-quit-raw", &args);
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> AutoUpdater::New(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args.IsConstructCall())
|
||||
return node::ThrowError("Require constructor call");
|
||||
|
||||
new AutoUpdater(args.This());
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> AutoUpdater::SetFeedURL(const v8::Arguments &args) {
|
||||
auto_updater::AutoUpdater::SetFeedURL(*v8::String::Utf8Value(args[0]));
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> AutoUpdater::SetAutomaticallyChecksForUpdates(
|
||||
const v8::Arguments &args) {
|
||||
auto_updater::AutoUpdater::SetAutomaticallyChecksForUpdates(
|
||||
args[0]->BooleanValue());
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> AutoUpdater::SetAutomaticallyDownloadsUpdates(
|
||||
const v8::Arguments &args) {
|
||||
auto_updater::AutoUpdater::SetAutomaticallyDownloadsUpdates(
|
||||
args[0]->BooleanValue());
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> AutoUpdater::CheckForUpdates(const v8::Arguments &args) {
|
||||
auto_updater::AutoUpdater::CheckForUpdates();
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> AutoUpdater::CheckForUpdatesInBackground(
|
||||
const v8::Arguments &args) {
|
||||
auto_updater::AutoUpdater::CheckForUpdatesInBackground();
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> AutoUpdater::ContinueUpdate(const v8::Arguments &args) {
|
||||
AutoUpdater* self = AutoUpdater::Unwrap<AutoUpdater>(args.This());
|
||||
self->continue_update_.Run();
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> AutoUpdater::QuitAndInstall(const v8::Arguments &args) {
|
||||
AutoUpdater* self = AutoUpdater::Unwrap<AutoUpdater>(args.This());
|
||||
self->quit_and_install_.Run();
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
void AutoUpdater::Initialize(v8::Handle<v8::Object> target) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Local<v8::FunctionTemplate> t(
|
||||
v8::FunctionTemplate::New(AutoUpdater::New));
|
||||
t->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
t->SetClassName(v8::String::NewSymbol("AutoUpdater"));
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setFeedUrl", SetFeedURL);
|
||||
NODE_SET_PROTOTYPE_METHOD(t,
|
||||
"setAutomaticallyChecksForUpdates",
|
||||
SetAutomaticallyChecksForUpdates);
|
||||
NODE_SET_PROTOTYPE_METHOD(t,
|
||||
"setAutomaticallyDownloadsUpdates",
|
||||
SetAutomaticallyDownloadsUpdates);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "checkForUpdates", CheckForUpdates);
|
||||
NODE_SET_PROTOTYPE_METHOD(t,
|
||||
"checkForUpdatesInBackground",
|
||||
CheckForUpdatesInBackground);
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "continueUpdate", ContinueUpdate);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "quitAndInstall", QuitAndInstall);
|
||||
|
||||
target->Set(v8::String::NewSymbol("AutoUpdater"), t->GetFunction());
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
NODE_MODULE(atom_browser_auto_updater, atom::api::AutoUpdater::Initialize)
|
||||
58
browser/api/atom_api_auto_updater.h
Normal file
58
browser/api/atom_api_auto_updater.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "browser/api/atom_api_event_emitter.h"
|
||||
#include "browser/auto_updater_delegate.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class AutoUpdater : public EventEmitter,
|
||||
public auto_updater::AutoUpdaterDelegate {
|
||||
public:
|
||||
virtual ~AutoUpdater();
|
||||
|
||||
static void Initialize(v8::Handle<v8::Object> target);
|
||||
|
||||
protected:
|
||||
explicit AutoUpdater(v8::Handle<v8::Object> wrapper);
|
||||
|
||||
virtual void WillInstallUpdate(const std::string& version,
|
||||
const base::Closure& install) OVERRIDE;
|
||||
virtual void ReadyForUpdateOnQuit(
|
||||
const std::string& version,
|
||||
const base::Closure& quit_and_install) OVERRIDE;
|
||||
|
||||
private:
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments &args);
|
||||
|
||||
static v8::Handle<v8::Value> SetFeedURL(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetAutomaticallyChecksForUpdates(
|
||||
const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetAutomaticallyDownloadsUpdates(
|
||||
const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> CheckForUpdates(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> CheckForUpdatesInBackground(
|
||||
const v8::Arguments &args);
|
||||
|
||||
static v8::Handle<v8::Value> ContinueUpdate(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> QuitAndInstall(const v8::Arguments &args);
|
||||
|
||||
base::Closure continue_update_;
|
||||
base::Closure quit_and_install_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AutoUpdater);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_AUTO_UPDATER_H_
|
||||
66
browser/api/atom_api_browser_ipc.cc
Normal file
66
browser/api/atom_api_browser_ipc.cc
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_browser_ipc.h"
|
||||
|
||||
#include "base/values.h"
|
||||
#include "common/api/api_messages.h"
|
||||
#include "common/v8_value_converter_impl.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
#include "vendor/node/src/node_internals.h"
|
||||
|
||||
using content::RenderViewHost;
|
||||
using content::V8ValueConverter;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> BrowserIPC::Send(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsString() || !args[1]->IsNumber() || !args[2]->IsNumber())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
std::string channel(*v8::String::Utf8Value(args[0]));
|
||||
int process_id = args[1]->IntegerValue();
|
||||
int routing_id = args[2]->IntegerValue();
|
||||
|
||||
RenderViewHost* render_view_host(RenderViewHost::FromID(
|
||||
process_id, routing_id));
|
||||
if (!render_view_host)
|
||||
return node::ThrowError("Invalid render view host");
|
||||
|
||||
// Convert Arguments to Array, so we can use V8ValueConverter to convert it
|
||||
// to ListValue.
|
||||
v8::Local<v8::Array> v8_args = v8::Array::New(args.Length() - 3);
|
||||
for (int i = 0; i < args.Length() - 3; ++i)
|
||||
v8_args->Set(i, args[i + 3]);
|
||||
|
||||
scoped_ptr<V8ValueConverter> converter(new V8ValueConverterImpl());
|
||||
scoped_ptr<base::Value> arguments(
|
||||
converter->FromV8Value(v8_args, v8::Context::GetCurrent()));
|
||||
|
||||
DCHECK(arguments && arguments->IsType(base::Value::TYPE_LIST));
|
||||
|
||||
render_view_host->Send(new AtomViewMsg_Message(
|
||||
routing_id,
|
||||
channel,
|
||||
*static_cast<base::ListValue*>(arguments.get())));
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
void BrowserIPC::Initialize(v8::Handle<v8::Object> target) {
|
||||
node::SetMethod(target, "send", Send);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
NODE_MODULE(atom_browser_ipc, atom::api::BrowserIPC::Initialize)
|
||||
29
browser/api/atom_api_browser_ipc.h
Normal file
29
browser/api/atom_api_browser_ipc.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_BROWSER_IPC_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_BROWSER_IPC_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class BrowserIPC {
|
||||
public:
|
||||
static void Initialize(v8::Handle<v8::Object> target);
|
||||
|
||||
private:
|
||||
static v8::Handle<v8::Value> Send(const v8::Arguments &args);
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(BrowserIPC);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_BROWSER_IPC_H_
|
||||
47
browser/api/atom_api_crash_reporter.cc
Normal file
47
browser/api/atom_api_crash_reporter.cc
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_crash_reporter.h"
|
||||
|
||||
#include "browser/crash_reporter.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
#include "vendor/node/src/node_internals.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> CrashReporter::SetCompanyName(const v8::Arguments &args) {
|
||||
std::string name(*v8::String::Utf8Value(args[0]));
|
||||
crash_reporter::CrashReporter::SetCompanyName(name);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> CrashReporter::SetSubmissionURL(
|
||||
const v8::Arguments &args) {
|
||||
std::string url(*v8::String::Utf8Value(args[0]));
|
||||
crash_reporter::CrashReporter::SetSubmissionURL(url);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> CrashReporter::SetAutoSubmit(const v8::Arguments &args) {
|
||||
crash_reporter::CrashReporter::SetAutoSubmit(args[0]->BooleanValue());
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
void CrashReporter::Initialize(v8::Handle<v8::Object> target) {
|
||||
node::SetMethod(target, "setCompanyName", SetCompanyName);
|
||||
node::SetMethod(target, "setSubmissionUrl", SetSubmissionURL);
|
||||
node::SetMethod(target, "setAutoSubmit", SetAutoSubmit);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
NODE_MODULE(atom_browser_crash_reporter, atom::api::CrashReporter::Initialize)
|
||||
31
browser/api/atom_api_crash_reporter.h
Normal file
31
browser/api/atom_api_crash_reporter.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_CRASH_REPORTER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_CRASH_REPORTER_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class CrashReporter {
|
||||
public:
|
||||
static void Initialize(v8::Handle<v8::Object> target);
|
||||
|
||||
private:
|
||||
static v8::Handle<v8::Value> SetCompanyName(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetSubmissionURL(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetAutoSubmit(const v8::Arguments &args);
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(CrashReporter);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_CRASH_REPORTER_H_
|
||||
129
browser/api/atom_api_dialog.cc
Normal file
129
browser/api/atom_api_dialog.cc
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_dialog.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/utf_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
#include "browser/api/atom_api_window.h"
|
||||
#include "browser/native_window.h"
|
||||
#include "browser/ui/file_dialog.h"
|
||||
#include "browser/ui/message_box.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
base::FilePath V8ValueToFilePath(v8::Handle<v8::Value> path) {
|
||||
std::string path_string(*v8::String::Utf8Value(path));
|
||||
return base::FilePath::FromUTF8Unsafe(path_string);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> FilePathToV8Value(const base::FilePath path) {
|
||||
std::string path_string(path.AsUTF8Unsafe());
|
||||
return v8::String::New(path_string.data(), path_string.size());
|
||||
}
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> target) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
NODE_SET_METHOD(target, "showMessageBox", ShowMessageBox);
|
||||
NODE_SET_METHOD(target, "showOpenDialog", ShowOpenDialog);
|
||||
NODE_SET_METHOD(target, "showSaveDialog", ShowSaveDialog);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
v8::Handle<v8::Value> ShowMessageBox(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsNumber() || // type
|
||||
!args[1]->IsArray() || // buttons
|
||||
!args[2]->IsString() || // title
|
||||
!args[3]->IsString() || // message
|
||||
!args[4]->IsString()) // detail
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
NativeWindow* native_window = NULL;
|
||||
if (args[5]->IsObject()) {
|
||||
Window* window = Window::Unwrap<Window>(args[5]->ToObject());
|
||||
if (!window || !window->window())
|
||||
return node::ThrowError("Invalid window");
|
||||
|
||||
native_window = window->window();
|
||||
}
|
||||
|
||||
MessageBoxType type = (MessageBoxType)(args[0]->IntegerValue());
|
||||
|
||||
std::vector<std::string> buttons;
|
||||
v8::Handle<v8::Array> v8_buttons = v8::Handle<v8::Array>::Cast(args[1]);
|
||||
for (uint32_t i = 0; i < v8_buttons->Length(); ++i)
|
||||
buttons.push_back(*v8::String::Utf8Value(v8_buttons->Get(i)));
|
||||
|
||||
std::string title(*v8::String::Utf8Value(args[2]));
|
||||
std::string message(*v8::String::Utf8Value(args[3]));
|
||||
std::string detail(*v8::String::Utf8Value(args[4]));
|
||||
|
||||
int chosen = atom::ShowMessageBox(
|
||||
native_window, type, buttons, title, message, detail);
|
||||
return scope.Close(v8::Integer::New(chosen));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> ShowOpenDialog(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsString() || // title
|
||||
!args[1]->IsString() || // default_path
|
||||
!args[2]->IsNumber()) // properties
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
std::string title(*v8::String::Utf8Value(args[0]));
|
||||
base::FilePath default_path(V8ValueToFilePath(args[1]));
|
||||
int properties = args[2]->IntegerValue();
|
||||
|
||||
std::vector<base::FilePath> paths;
|
||||
if (!file_dialog::ShowOpenDialog(title, default_path, properties, &paths))
|
||||
return v8::Undefined();
|
||||
|
||||
v8::Handle<v8::Array> result = v8::Array::New(paths.size());
|
||||
for (size_t i = 0; i < paths.size(); ++i)
|
||||
result->Set(i, FilePathToV8Value(paths[i]));
|
||||
|
||||
return scope.Close(result);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> ShowSaveDialog(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsObject() || // window
|
||||
!args[1]->IsString() || // title
|
||||
!args[2]->IsString()) // default_path
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
Window* window = Window::Unwrap<Window>(args[0]->ToObject());
|
||||
if (!window || !window->window())
|
||||
return node::ThrowError("Invalid window");
|
||||
|
||||
std::string title(*v8::String::Utf8Value(args[1]));
|
||||
base::FilePath default_path(V8ValueToFilePath(args[2]));
|
||||
|
||||
base::FilePath path;
|
||||
if (!file_dialog::ShowSaveDialog(window->window(),
|
||||
title,
|
||||
default_path,
|
||||
&path))
|
||||
return v8::Undefined();
|
||||
|
||||
return scope.Close(FilePathToV8Value(path));
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
NODE_MODULE(atom_browser_dialog, atom::api::Initialize)
|
||||
22
browser/api/atom_api_dialog.h
Normal file
22
browser/api/atom_api_dialog.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_DIALOG_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_DIALOG_H_
|
||||
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
v8::Handle<v8::Value> ShowMessageBox(const v8::Arguments &args);
|
||||
v8::Handle<v8::Value> ShowOpenDialog(const v8::Arguments &args);
|
||||
v8::Handle<v8::Value> ShowSaveDialog(const v8::Arguments &args);
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_DIALOG_H_
|
||||
61
browser/api/atom_api_event.cc
Normal file
61
browser/api/atom_api_event.cc
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_event.h"
|
||||
|
||||
using node::node_isolate;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
v8::Persistent<v8::FunctionTemplate> Event::constructor_template_;
|
||||
|
||||
Event::Event()
|
||||
: prevent_default_(false) {
|
||||
}
|
||||
|
||||
Event::~Event() {
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Object> Event::CreateV8Object() {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (constructor_template_.IsEmpty()) {
|
||||
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New);
|
||||
constructor_template_ = v8::Persistent<v8::FunctionTemplate>::New(
|
||||
node_isolate, t);
|
||||
constructor_template_->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
constructor_template_->SetClassName(v8::String::NewSymbol("Event"));
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "preventDefault", PreventDefault);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Object> v8_event =
|
||||
constructor_template_->GetFunction()->NewInstance(0, NULL);
|
||||
|
||||
return scope.Close(v8_event);
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Event::New(const v8::Arguments &args) {
|
||||
Event* event = new Event;
|
||||
event->Wrap(args.This());
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Event::PreventDefault(const v8::Arguments &args) {
|
||||
Event* event = Unwrap<Event>(args.This());
|
||||
if (event == NULL)
|
||||
return node::ThrowError("Event is already destroyed");
|
||||
|
||||
event->prevent_default_ = true;
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
46
browser/api/atom_api_event.h
Normal file
46
browser/api/atom_api_event.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_API_EVENT_H_
|
||||
#define ATOM_BROWSER_ATOM_API_EVENT_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "vendor/node/src/node_object_wrap.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class Event : public node::ObjectWrap {
|
||||
public:
|
||||
virtual ~Event();
|
||||
|
||||
// Create a V8 Event object.
|
||||
static v8::Handle<v8::Object> CreateV8Object();
|
||||
|
||||
// Accessor to return handle_, this follows Google C++ Style.
|
||||
v8::Persistent<v8::Object>& handle() { return handle_; }
|
||||
|
||||
// Whether event.preventDefault() is called.
|
||||
bool prevent_default() const { return prevent_default_; }
|
||||
|
||||
protected:
|
||||
Event();
|
||||
|
||||
private:
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> PreventDefault(const v8::Arguments &args);
|
||||
|
||||
static v8::Persistent<v8::FunctionTemplate> constructor_template_;
|
||||
|
||||
bool prevent_default_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Event);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_API_EVENT_H_
|
||||
76
browser/api/atom_api_event_emitter.cc
Normal file
76
browser/api/atom_api_event_emitter.cc
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_event_emitter.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/values.h"
|
||||
#include "browser/api/atom_api_event.h"
|
||||
#include "common/v8_value_converter_impl.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
#include "vendor/node/src/node_internals.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
EventEmitter::EventEmitter(v8::Handle<v8::Object> wrapper) {
|
||||
Wrap(wrapper);
|
||||
|
||||
// process.emit('ATOM_BROWSER_INTERNAL_NEW', this).
|
||||
v8::Handle<v8::Value> args[] = {
|
||||
v8::String::New("ATOM_BROWSER_INTERNAL_NEW"),
|
||||
wrapper,
|
||||
};
|
||||
node::MakeCallback(node::process, "emit", 2, args);
|
||||
}
|
||||
|
||||
EventEmitter::~EventEmitter() {
|
||||
}
|
||||
|
||||
bool EventEmitter::Emit(const std::string& name) {
|
||||
base::ListValue args;
|
||||
return Emit(name, &args);
|
||||
}
|
||||
|
||||
bool EventEmitter::Emit(const std::string& name, base::ListValue* args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
|
||||
scoped_ptr<content::V8ValueConverter> converter(new V8ValueConverterImpl);
|
||||
|
||||
v8::Handle<v8::Object> v8_event = Event::CreateV8Object();
|
||||
Event* event = Event::Unwrap<Event>(v8_event);
|
||||
|
||||
// Generate arguments for calling handle.emit.
|
||||
std::vector<v8::Handle<v8::Value>> v8_args;
|
||||
v8_args.reserve(args->GetSize() + 2);
|
||||
v8_args.push_back(v8::String::New(name.c_str(), name.size()));
|
||||
v8_args.push_back(v8_event);
|
||||
for (size_t i = 0; i < args->GetSize(); i++) {
|
||||
base::Value* value = NULL;
|
||||
if (args->Get(i, &value)) {
|
||||
DCHECK(value);
|
||||
v8_args.push_back(converter->ToV8Value(value, context));
|
||||
} else {
|
||||
NOTREACHED() << "Wrong offset " << i << " for " << *args;
|
||||
}
|
||||
}
|
||||
|
||||
node::MakeCallback(handle(), "emit", v8_args.size(), &v8_args[0]);
|
||||
|
||||
bool prevent_default = event->prevent_default();
|
||||
|
||||
// Don't wait for V8 GC, delete it immediately.
|
||||
delete event;
|
||||
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
46
browser/api/atom_api_event_emitter.h
Normal file
46
browser/api/atom_api_event_emitter.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_EVENT_EMITTER_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_EVENT_EMITTER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "vendor/node/src/node_object_wrap.h"
|
||||
|
||||
namespace base {
|
||||
class ListValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
// Class interiting EventEmitter should assume it's a javascript object which
|
||||
// interits require('events').EventEmitter, this class provides many helper
|
||||
// methods to do event processing in C++.
|
||||
class EventEmitter : public node::ObjectWrap {
|
||||
public:
|
||||
virtual ~EventEmitter();
|
||||
|
||||
// Emit an event and returns whether the handler has called preventDefault().
|
||||
bool Emit(const std::string& name);
|
||||
bool Emit(const std::string& name, base::ListValue* args);
|
||||
|
||||
// Small accessor to return handle_, this follows Google C++ Style.
|
||||
v8::Persistent<v8::Object> handle() const { return handle_; }
|
||||
|
||||
protected:
|
||||
explicit EventEmitter(v8::Handle<v8::Object> wrapper);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(EventEmitter);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_EVENT_EMITTER_H_
|
||||
388
browser/api/atom_api_menu.cc
Normal file
388
browser/api/atom_api_menu.cc
Normal file
@@ -0,0 +1,388 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_menu.h"
|
||||
|
||||
#include "browser/api/atom_api_window.h"
|
||||
#include "browser/ui/accelerator_util.h"
|
||||
|
||||
#define UNWRAP_MEMNU_AND_CHECK \
|
||||
Menu* self = ObjectWrap::Unwrap<Menu>(args.This()); \
|
||||
if (self == NULL) \
|
||||
return node::ThrowError("Menu is already destroyed")
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Converts a V8 value to a string16.
|
||||
string16 V8ValueToUTF16(v8::Handle<v8::Value> value) {
|
||||
v8::String::Value s(value);
|
||||
return string16(reinterpret_cast<const char16*>(*s), s.length());
|
||||
}
|
||||
|
||||
// Converts string16 to V8 String.
|
||||
v8::Handle<v8::Value> UTF16ToV8Value(const string16& s) {
|
||||
return v8::String::New(reinterpret_cast<const uint16_t*>(s.data()), s.size());
|
||||
}
|
||||
|
||||
// Call method of delegate object.
|
||||
v8::Handle<v8::Value> CallDelegate(v8::Handle<v8::Value> default_value,
|
||||
v8::Handle<v8::Object> menu,
|
||||
const char* method,
|
||||
int command_id) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::Value> delegate = menu->Get(v8::String::New("delegate"));
|
||||
if (!delegate->IsObject())
|
||||
return default_value;
|
||||
|
||||
v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(
|
||||
delegate->ToObject()->Get(v8::String::New(method)));
|
||||
if (!function->IsFunction())
|
||||
return default_value;
|
||||
|
||||
v8::Handle<v8::Value> argv = v8::Integer::New(command_id);
|
||||
|
||||
return scope.Close(
|
||||
function->Call(v8::Context::GetCurrent()->Global(), 1, &argv));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Menu::Menu(v8::Handle<v8::Object> wrapper)
|
||||
: EventEmitter(wrapper),
|
||||
model_(new ui::SimpleMenuModel(this)) {
|
||||
}
|
||||
|
||||
Menu::~Menu() {
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdChecked(int command_id) const {
|
||||
v8::HandleScope scope;
|
||||
return CallDelegate(v8::False(),
|
||||
handle(),
|
||||
"isCommandIdChecked",
|
||||
command_id)->BooleanValue();
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdEnabled(int command_id) const {
|
||||
v8::HandleScope scope;
|
||||
return CallDelegate(v8::True(),
|
||||
handle(),
|
||||
"isCommandIdEnabled",
|
||||
command_id)->BooleanValue();
|
||||
}
|
||||
|
||||
bool Menu::IsCommandIdVisible(int command_id) const {
|
||||
v8::HandleScope scope;
|
||||
return CallDelegate(v8::True(),
|
||||
handle(),
|
||||
"isCommandIdVisible",
|
||||
command_id)->BooleanValue();
|
||||
}
|
||||
|
||||
bool Menu::GetAcceleratorForCommandId(int command_id,
|
||||
ui::Accelerator* accelerator) {
|
||||
v8::HandleScope scope;
|
||||
v8::Handle<v8::Value> shortcut = CallDelegate(v8::Undefined(),
|
||||
handle(),
|
||||
"getAcceleratorForCommandId",
|
||||
command_id);
|
||||
if (shortcut->IsString()) {
|
||||
std::string shortcut_str(*v8::String::Utf8Value(shortcut));
|
||||
return accelerator_util::StringToAccelerator(shortcut_str, accelerator);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Menu::IsItemForCommandIdDynamic(int command_id) const {
|
||||
v8::HandleScope scope;
|
||||
return CallDelegate(v8::False(),
|
||||
handle(),
|
||||
"isItemForCommandIdDynamic",
|
||||
command_id)->BooleanValue();
|
||||
}
|
||||
|
||||
string16 Menu::GetLabelForCommandId(int command_id) const {
|
||||
v8::HandleScope scope;
|
||||
return V8ValueToUTF16(CallDelegate(v8::False(),
|
||||
handle(),
|
||||
"getLabelForCommandId",
|
||||
command_id));
|
||||
}
|
||||
|
||||
string16 Menu::GetSublabelForCommandId(int command_id) const {
|
||||
v8::HandleScope scope;
|
||||
return V8ValueToUTF16(CallDelegate(v8::False(),
|
||||
handle(),
|
||||
"getSubLabelForCommandId",
|
||||
command_id));
|
||||
}
|
||||
|
||||
void Menu::ExecuteCommand(int command_id, int event_flags) {
|
||||
v8::HandleScope scope;
|
||||
CallDelegate(v8::False(), handle(), "executeCommand", command_id);
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::New(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args.IsConstructCall())
|
||||
return node::ThrowError("Require constructor call");
|
||||
|
||||
Menu::Create(args.This());
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::InsertItem(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsString())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
int index = args[0]->IntegerValue();
|
||||
|
||||
if (index < 0)
|
||||
self->model_->AddItem(args[1]->IntegerValue(), V8ValueToUTF16(args[2]));
|
||||
else
|
||||
self->model_->InsertItemAt(
|
||||
index, args[1]->IntegerValue(), V8ValueToUTF16(args[2]));
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::InsertCheckItem(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() || !args[1]->IsNumber() || !args[2]->IsString())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
int index = args[0]->IntegerValue();
|
||||
int command_id = args[1]->IntegerValue();
|
||||
|
||||
if (index < 0)
|
||||
self->model_->AddCheckItem(command_id, V8ValueToUTF16(args[2]));
|
||||
else
|
||||
self->model_->InsertCheckItemAt(index, command_id, V8ValueToUTF16(args[2]));
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::InsertRadioItem(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() ||
|
||||
!args[1]->IsNumber() ||
|
||||
!args[2]->IsString() ||
|
||||
!args[3]->IsNumber())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
int index = args[0]->IntegerValue();
|
||||
int command_id = args[1]->IntegerValue();
|
||||
int group_id = args[3]->IntegerValue();
|
||||
|
||||
if (index < 0)
|
||||
self->model_->AddRadioItem(command_id, V8ValueToUTF16(args[2]), group_id);
|
||||
else
|
||||
self->model_->InsertRadioItemAt(
|
||||
index, command_id, V8ValueToUTF16(args[2]), group_id);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::InsertSeparator(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
int index = args[0]->IntegerValue();
|
||||
|
||||
if (index < 0)
|
||||
self->model_->AddSeparator(ui::NORMAL_SEPARATOR);
|
||||
else
|
||||
self->model_->InsertSeparatorAt(index, ui::NORMAL_SEPARATOR);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::InsertSubMenu(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() ||
|
||||
!args[1]->IsNumber() ||
|
||||
!args[2]->IsString() ||
|
||||
!args[3]->IsObject())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
Menu* submenu = ObjectWrap::Unwrap<Menu>(args[3]->ToObject());
|
||||
if (!submenu)
|
||||
return node::ThrowTypeError("The submenu is already destroyed");
|
||||
|
||||
int index = args[0]->IntegerValue();
|
||||
int command_id = args[1]->IntegerValue();
|
||||
|
||||
if (index < 0)
|
||||
self->model_->AddSubMenu(
|
||||
command_id, V8ValueToUTF16(args[2]), submenu->model_.get());
|
||||
else
|
||||
self->model_->InsertSubMenuAt(
|
||||
index, command_id, V8ValueToUTF16(args[2]), submenu->model_.get());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::SetIcon(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() || !args[1]->IsString())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
// FIXME use webkit_glue's image decoder here.
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::SetSublabel(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
if (!args[0]->IsNumber() || !args[1]->IsString())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
self->model_->SetSublabel(args[0]->IntegerValue(), V8ValueToUTF16(args[1]));
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::Clear(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
self->model_->Clear();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::GetIndexOfCommandId(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
int index = args[0]->IntegerValue();
|
||||
return v8::Integer::New(self->model_->GetIndexOfCommandId(index));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::GetItemCount(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
return v8::Integer::New(self->model_->GetItemCount());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::GetCommandIdAt(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
int index = args[0]->IntegerValue();
|
||||
return v8::Integer::New(self->model_->GetCommandIdAt(index));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::GetLabelAt(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
int index = args[0]->IntegerValue();
|
||||
return UTF16ToV8Value(self->model_->GetLabelAt(index));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::GetSublabelAt(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
int index = args[0]->IntegerValue();
|
||||
return UTF16ToV8Value(self->model_->GetSublabelAt(index));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::IsItemCheckedAt(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
int index = args[0]->IntegerValue();
|
||||
return v8::Boolean::New(self->model_->IsItemCheckedAt(index));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::IsEnabledAt(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
return v8::Boolean::New(self->model_->IsEnabledAt(args[0]->IntegerValue()));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::IsVisibleAt(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
return v8::Boolean::New(self->model_->IsVisibleAt(args[0]->IntegerValue()));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::Popup(const v8::Arguments &args) {
|
||||
UNWRAP_MEMNU_AND_CHECK;
|
||||
|
||||
Window* window = Window::Unwrap<Window>(args[0]->ToObject());
|
||||
if (!window)
|
||||
return node::ThrowTypeError("Invalid window");
|
||||
|
||||
self->Popup(window->window());
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
void Menu::Initialize(v8::Handle<v8::Object> target) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Local<v8::FunctionTemplate> t(v8::FunctionTemplate::New(Menu::New));
|
||||
t->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
t->SetClassName(v8::String::NewSymbol("Menu"));
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "insertItem", InsertItem);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "insertCheckItem", InsertCheckItem);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "insertRadioItem", InsertRadioItem);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "insertSeparator", InsertSeparator);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "insertSubMenu", InsertSubMenu);
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setIcon", SetIcon);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setSublabel", SetSublabel);
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "clear", Clear);
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getIndexOfCommandId", GetIndexOfCommandId);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getItemCount", GetItemCount);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getCommandIdAt", GetCommandIdAt);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getLabelAt", GetLabelAt);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getSublabelAt", GetSublabelAt);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isItemCheckedAt", IsItemCheckedAt);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isEnabledAt", IsEnabledAt);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isVisibleAt", IsVisibleAt);
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "popup", Popup);
|
||||
|
||||
target->Set(v8::String::NewSymbol("Menu"), t->GetFunction());
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
NODE_SET_METHOD(target, "setApplicationMenu", SetApplicationMenu);
|
||||
NODE_SET_METHOD(
|
||||
target, "sendActionToFirstResponder", SendActionToFirstResponder);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
NODE_MODULE(atom_browser_menu, atom::api::Menu::Initialize)
|
||||
84
browser/api/atom_api_menu.h
Normal file
84
browser/api/atom_api_menu.h
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "browser/api/atom_api_event_emitter.h"
|
||||
#include "ui/base/models/simple_menu_model.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NativeWindow;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Menu : public EventEmitter,
|
||||
public ui::SimpleMenuModel::Delegate {
|
||||
public:
|
||||
virtual ~Menu();
|
||||
|
||||
static Menu* Create(v8::Handle<v8::Object> wrapper);
|
||||
|
||||
static void Initialize(v8::Handle<v8::Object> target);
|
||||
|
||||
protected:
|
||||
explicit Menu(v8::Handle<v8::Object> wrapper);
|
||||
|
||||
// ui::SimpleMenuModel::Delegate implementations:
|
||||
virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
|
||||
virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
|
||||
virtual bool IsCommandIdVisible(int command_id) const OVERRIDE;
|
||||
virtual bool GetAcceleratorForCommandId(
|
||||
int command_id,
|
||||
ui::Accelerator* accelerator) OVERRIDE;
|
||||
virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE;
|
||||
virtual string16 GetLabelForCommandId(int command_id) const OVERRIDE;
|
||||
virtual string16 GetSublabelForCommandId(int command_id) const OVERRIDE;
|
||||
virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
|
||||
|
||||
virtual void Popup(NativeWindow* window) = 0;
|
||||
|
||||
scoped_ptr<ui::SimpleMenuModel> model_;
|
||||
|
||||
private:
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments &args);
|
||||
|
||||
static v8::Handle<v8::Value> InsertItem(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> InsertCheckItem(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> InsertRadioItem(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> InsertSeparator(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> InsertSubMenu(const v8::Arguments &args);
|
||||
|
||||
static v8::Handle<v8::Value> SetIcon(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetSublabel(const v8::Arguments &args);
|
||||
|
||||
static v8::Handle<v8::Value> Clear(const v8::Arguments &args);
|
||||
|
||||
static v8::Handle<v8::Value> GetIndexOfCommandId(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetItemCount(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetCommandIdAt(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetLabelAt(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetSublabelAt(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsItemCheckedAt(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsEnabledAt(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsVisibleAt(const v8::Arguments &args);
|
||||
|
||||
static v8::Handle<v8::Value> Popup(const v8::Arguments &args);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
static v8::Handle<v8::Value> SetApplicationMenu(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SendActionToFirstResponder(
|
||||
const v8::Arguments &args);
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Menu);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_H_
|
||||
39
browser/api/atom_api_menu_mac.h
Normal file
39
browser/api/atom_api_menu_mac.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
|
||||
#include "browser/api/atom_api_menu.h"
|
||||
|
||||
#import "browser/ui/atom_menu_controller_mac.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuMac : public Menu {
|
||||
public:
|
||||
explicit MenuMac(v8::Handle<v8::Object> wrapper);
|
||||
virtual ~MenuMac();
|
||||
|
||||
protected:
|
||||
virtual void Popup(NativeWindow* window) OVERRIDE;
|
||||
|
||||
scoped_nsobject<AtomMenuController> menu_controller_;
|
||||
|
||||
private:
|
||||
friend class Menu;
|
||||
|
||||
// Fake sending an action from the application menu.
|
||||
static void SendActionToFirstResponder(const std::string& action);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuMac);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_MAC_H_
|
||||
114
browser/api/atom_api_menu_mac.mm
Normal file
114
browser/api/atom_api_menu_mac.mm
Normal file
@@ -0,0 +1,114 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "browser/api/atom_api_menu_mac.h"
|
||||
|
||||
#include "base/message_loop.h"
|
||||
#include "base/mac/scoped_sending_event.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "browser/native_window.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/web_contents_view.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuMac::MenuMac(v8::Handle<v8::Object> wrapper)
|
||||
: Menu(wrapper) {
|
||||
}
|
||||
|
||||
MenuMac::~MenuMac() {
|
||||
}
|
||||
|
||||
void MenuMac::Popup(NativeWindow* native_window) {
|
||||
scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:model_.get()]);
|
||||
|
||||
NSWindow* window = native_window->GetNativeWindow();
|
||||
content::WebContents* web_contents = native_window->GetWebContents();
|
||||
|
||||
// Fake out a context menu event.
|
||||
NSEvent* currentEvent = [NSApp currentEvent];
|
||||
NSPoint position = [window mouseLocationOutsideOfEventStream];
|
||||
NSTimeInterval eventTime = [currentEvent timestamp];
|
||||
NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown
|
||||
location:position
|
||||
modifierFlags:NSRightMouseDownMask
|
||||
timestamp:eventTime
|
||||
windowNumber:[window windowNumber]
|
||||
context:nil
|
||||
eventNumber:0
|
||||
clickCount:1
|
||||
pressure:1.0];
|
||||
|
||||
{
|
||||
// Make sure events can be pumped while the menu is up.
|
||||
MessageLoop::ScopedNestableTaskAllower allow(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;
|
||||
|
||||
// Show the menu.
|
||||
[NSMenu popUpContextMenu:[menu_controller menu]
|
||||
withEvent:clickEvent
|
||||
forView:web_contents->GetView()->GetContentNativeView()];
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void MenuMac::SendActionToFirstResponder(const std::string& action) {
|
||||
SEL selector = NSSelectorFromString(base::SysUTF8ToNSString(action));
|
||||
[[NSApplication sharedApplication] sendAction:selector
|
||||
to:nil
|
||||
from:[NSApp mainMenu]];
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::SetApplicationMenu(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsObject())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
MenuMac* menu = ObjectWrap::Unwrap<MenuMac>(args[0]->ToObject());
|
||||
if (!menu)
|
||||
return node::ThrowError("Menu is destroyed");
|
||||
|
||||
scoped_nsobject<AtomMenuController> menu_controller(
|
||||
[[AtomMenuController alloc] initWithModel:menu->model_.get()]);
|
||||
[NSApp setMainMenu:[menu_controller menu]];
|
||||
|
||||
// Ensure the menu_controller_ is destroyed after main menu is set.
|
||||
menu_controller.swap(menu->menu_controller_);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Menu::SendActionToFirstResponder(
|
||||
const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args[0]->IsString())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
std::string action(*v8::String::Utf8Value(args[0]));
|
||||
MenuMac::SendActionToFirstResponder(action);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
Menu* Menu::Create(v8::Handle<v8::Object> wrapper) {
|
||||
return new MenuMac(wrapper);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
33
browser/api/atom_api_menu_win.cc
Normal file
33
browser/api/atom_api_menu_win.cc
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_menu_win.h"
|
||||
|
||||
#include "browser/ui/win/menu_2.h"
|
||||
#include "ui/gfx/point.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
MenuWin::MenuWin(v8::Handle<v8::Object> wrapper)
|
||||
: Menu(wrapper) {
|
||||
}
|
||||
|
||||
MenuWin::~MenuWin() {
|
||||
}
|
||||
|
||||
void MenuWin::Popup(NativeWindow* native_window) {
|
||||
menu_.reset(new atom::Menu2(model_.get()));
|
||||
menu_->RunContextMenuAt(gfx::Point(0, 0));
|
||||
}
|
||||
|
||||
// static
|
||||
Menu* Menu::Create(v8::Handle<v8::Object> wrapper) {
|
||||
return new MenuWin(wrapper);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
34
browser/api/atom_api_menu_win.h
Normal file
34
browser/api/atom_api_menu_win.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_MENU_WIN_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_MENU_WIN_H_
|
||||
|
||||
#include "browser/api/atom_api_menu.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class Menu2;
|
||||
|
||||
namespace api {
|
||||
|
||||
class MenuWin : public Menu {
|
||||
public:
|
||||
explicit MenuWin(v8::Handle<v8::Object> wrapper);
|
||||
virtual ~MenuWin();
|
||||
|
||||
protected:
|
||||
virtual void Popup(NativeWindow* window) OVERRIDE;
|
||||
|
||||
private:
|
||||
scoped_ptr<atom::Menu2> menu_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MenuWin);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_MENU_WIN_H_
|
||||
66
browser/api/atom_api_power_monitor.cc
Normal file
66
browser/api/atom_api_power_monitor.cc
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_power_monitor.h"
|
||||
|
||||
#include "base/power_monitor/power_monitor.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
PowerMonitor::PowerMonitor(v8::Handle<v8::Object> wrapper)
|
||||
: EventEmitter(wrapper) {
|
||||
base::PowerMonitor::Get()->AddObserver(this);
|
||||
}
|
||||
|
||||
PowerMonitor::~PowerMonitor() {
|
||||
base::PowerMonitor::Get()->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void PowerMonitor::OnPowerStateChange(bool on_battery_power) {
|
||||
if (on_battery_power)
|
||||
Emit("on-battery");
|
||||
else
|
||||
Emit("on-ac");
|
||||
}
|
||||
|
||||
void PowerMonitor::OnSuspend() {
|
||||
Emit("suspend");
|
||||
}
|
||||
|
||||
void PowerMonitor::OnResume() {
|
||||
Emit("resume");
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> PowerMonitor::New(const v8::Arguments& args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args.IsConstructCall())
|
||||
return node::ThrowError("Require constructor call");
|
||||
|
||||
new PowerMonitor(args.This());
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
// static
|
||||
void PowerMonitor::Initialize(v8::Handle<v8::Object> target) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(
|
||||
PowerMonitor::New);
|
||||
t->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
t->SetClassName(v8::String::NewSymbol("PowerMonitor"));
|
||||
|
||||
target->Set(v8::String::NewSymbol("PowerMonitor"), t->GetFunction());
|
||||
}
|
||||
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
NODE_MODULE(atom_browser_power_monitor, atom::api::PowerMonitor::Initialize)
|
||||
41
browser/api/atom_api_power_monitor.h
Normal file
41
browser/api/atom_api_power_monitor.h
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
|
||||
#include "browser/api/atom_api_event_emitter.h"
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/power_monitor/power_observer.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class PowerMonitor : public EventEmitter,
|
||||
public base::PowerObserver {
|
||||
public:
|
||||
virtual ~PowerMonitor();
|
||||
|
||||
static void Initialize(v8::Handle<v8::Object> target);
|
||||
|
||||
protected:
|
||||
explicit PowerMonitor(v8::Handle<v8::Object> wrapper);
|
||||
|
||||
virtual void OnPowerStateChange(bool on_battery_power) OVERRIDE;
|
||||
virtual void OnSuspend() OVERRIDE;
|
||||
virtual void OnResume() OVERRIDE;
|
||||
|
||||
private:
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments &args);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_POWER_MONITOR_H_
|
||||
731
browser/api/atom_api_window.cc
Normal file
731
browser/api/atom_api_window.cc
Normal file
@@ -0,0 +1,731 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_api_window.h"
|
||||
|
||||
#include "base/values.h"
|
||||
#include "browser/native_window.h"
|
||||
#include "common/v8_value_converter_impl.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "ui/gfx/point.h"
|
||||
#include "ui/gfx/rect.h"
|
||||
#include "ui/gfx/size.h"
|
||||
|
||||
using content::V8ValueConverter;
|
||||
using content::NavigationController;
|
||||
using node::ObjectWrap;
|
||||
|
||||
#define UNWRAP_WINDOW_AND_CHECK \
|
||||
Window* self = ObjectWrap::Unwrap<Window>(args.This()); \
|
||||
if (self == NULL) \
|
||||
return node::ThrowError("Window is already destroyed")
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
// Converts string16 to V8 String.
|
||||
v8::Handle<v8::String> UTF16ToV8String(const string16& s) {
|
||||
return v8::String::New(reinterpret_cast<const uint16_t*>(s.data()), s.size());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Window::Window(v8::Handle<v8::Object> wrapper, base::DictionaryValue* options)
|
||||
: EventEmitter(wrapper),
|
||||
window_(NativeWindow::Create(options)) {
|
||||
window_->InitFromOptions(options);
|
||||
window_->AddObserver(this);
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
Emit("destroyed");
|
||||
|
||||
window_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void Window::OnPageTitleUpdated(bool* prevent_default,
|
||||
const std::string& title) {
|
||||
base::ListValue args;
|
||||
args.AppendString(title);
|
||||
*prevent_default = Emit("page-title-updated", &args);
|
||||
}
|
||||
|
||||
void Window::WillCloseWindow(bool* prevent_default) {
|
||||
*prevent_default = Emit("close");
|
||||
}
|
||||
|
||||
void Window::OnWindowClosed() {
|
||||
Emit("closed");
|
||||
|
||||
// Free memory immediately when window is closed.
|
||||
delete this;
|
||||
}
|
||||
|
||||
void Window::OnWindowBlur() {
|
||||
Emit("blur");
|
||||
}
|
||||
|
||||
void Window::OnRendererUnresponsive() {
|
||||
Emit("unresponsive");
|
||||
}
|
||||
|
||||
void Window::OnRendererResponsive() {
|
||||
Emit("responsive");
|
||||
}
|
||||
|
||||
void Window::OnRendererCrashed() {
|
||||
Emit("crashed");
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::New(const v8::Arguments &args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (!args.IsConstructCall())
|
||||
return node::ThrowError("Require constructor call");
|
||||
|
||||
if (!args[0]->IsObject())
|
||||
return node::ThrowTypeError("Need options creating Window");
|
||||
|
||||
scoped_ptr<V8ValueConverter> converter(new V8ValueConverterImpl());
|
||||
scoped_ptr<base::Value> options(
|
||||
converter->FromV8Value(args[0], v8::Context::GetCurrent()));
|
||||
|
||||
if (!options || !options->IsType(base::Value::TYPE_DICTIONARY))
|
||||
return node::ThrowTypeError("Invalid options");
|
||||
|
||||
new Window(args.This(), static_cast<base::DictionaryValue*>(options.get()));
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Destroy(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
delete self;
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Close(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->Close();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Focus(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->Focus(args[0]->IsBoolean() ? args[0]->BooleanValue(): true);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsFocused(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
return v8::Boolean::New(self->window_->IsFocused());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Show(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->Show();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Hide(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->Hide();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Maximize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->Maximize();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Unmaximize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->Unmaximize();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Minimize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->Minimize();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Restore(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->Restore();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetFullscreen(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetFullscreen(args[0]->BooleanValue());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsFullscreen(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->IsFullscreen());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetSize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 2)
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetSize(
|
||||
gfx::Size(args[0]->IntegerValue(), args[1]->IntegerValue()));
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetSize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
gfx::Size size = self->window_->GetSize();
|
||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||
ret->Set(0, v8::Integer::New(size.width()));
|
||||
ret->Set(1, v8::Integer::New(size.height()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetMinimumSize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 2)
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetMinimumSize(
|
||||
gfx::Size(args[0]->IntegerValue(), args[1]->IntegerValue()));
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetMinimumSize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
gfx::Size size = self->window_->GetMinimumSize();
|
||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||
ret->Set(0, v8::Integer::New(size.width()));
|
||||
ret->Set(1, v8::Integer::New(size.height()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetMaximumSize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 2)
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetMaximumSize(
|
||||
gfx::Size(args[0]->IntegerValue(), args[1]->IntegerValue()));
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetMaximumSize(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
gfx::Size size = self->window_->GetMaximumSize();
|
||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||
ret->Set(0, v8::Integer::New(size.width()));
|
||||
ret->Set(1, v8::Integer::New(size.height()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetResizable(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetResizable(args[0]->BooleanValue());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsResizable(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->IsResizable());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetAlwaysOnTop(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetAlwaysOnTop(args[0]->BooleanValue());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsAlwaysOnTop(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->IsAlwaysOnTop());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Center(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->Center();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetPosition(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 2)
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetPosition(
|
||||
gfx::Point(args[0]->IntegerValue(), args[1]->IntegerValue()));
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetPosition(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
gfx::Point pos = self->window_->GetPosition();
|
||||
v8::Handle<v8::Array> ret = v8::Array::New(2);
|
||||
ret->Set(0, v8::Integer::New(pos.x()));
|
||||
ret->Set(1, v8::Integer::New(pos.y()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetTitle(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsString())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetTitle(*v8::String::Utf8Value(args[0]));
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetTitle(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
std::string title = self->window_->GetTitle();
|
||||
|
||||
return v8::String::New(title.c_str(), title.size());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::FlashFrame(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->FlashFrame(
|
||||
args[0]->IsBoolean() ? args[0]->BooleanValue(): true);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::SetKiosk(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsBoolean())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
self->window_->SetKiosk(args[0]->BooleanValue());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsKiosk(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->IsKiosk());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::OpenDevTools(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->OpenDevTools();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::CloseDevTools(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->CloseDevTools();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::InspectElement(const v8::Arguments& args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->InspectElement(args[0]->IntegerValue(),
|
||||
args[1]->IntegerValue());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::FocusOnWebView(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->FocusOnWebView();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::BlurWebView(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->BlurWebView();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsWebViewFocused(const v8::Arguments& args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
return v8::Boolean::New(self->window_->IsWebViewFocused());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::RestartHangMonitorTimeout(
|
||||
const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->RestartHangMonitorTimeout();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetPageTitle(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
string16 title = self->window_->GetWebContents()->GetTitle();
|
||||
|
||||
return UTF16ToV8String(title);
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsLoading(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->GetWebContents()->IsLoading());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsWaitingForResponse(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(
|
||||
self->window_->GetWebContents()->IsWaitingForResponse());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Stop(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
self->window_->GetWebContents()->Stop();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetRoutingID(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Integer::New(self->window_->GetWebContents()->GetRoutingID());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetProcessID(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Integer::New(
|
||||
self->window_->GetWebContents()->GetRenderProcessHost()->GetID());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::IsCrashed(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
return v8::Boolean::New(self->window_->GetWebContents()->IsCrashed());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::LoadURL(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsString())
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
controller.LoadURL(GURL(*v8::String::Utf8Value(args[0])),
|
||||
content::Referrer(),
|
||||
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
|
||||
std::string());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GetURL(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
std::string url;
|
||||
if (controller.GetActiveEntry())
|
||||
url = controller.GetActiveEntry()->GetVirtualURL().spec();
|
||||
|
||||
return v8::String::New(url.c_str(), url.size());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::CanGoBack(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
|
||||
return v8::Boolean::New(controller.CanGoBack());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::CanGoForward(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
|
||||
return v8::Boolean::New(controller.CanGoForward());
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::CanGoToOffset(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1)
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
int offset = args[0]->IntegerValue();
|
||||
|
||||
return v8::Boolean::New(controller.CanGoToOffset(offset));
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GoBack(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
controller.GoBack();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GoForward(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
controller.GoForward();
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GoToIndex(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1)
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
controller.GoToIndex(args[0]->IntegerValue());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::GoToOffset(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
if (args.Length() < 1)
|
||||
return node::ThrowTypeError("Bad argument");
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
controller.GoToOffset(args[0]->IntegerValue());
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::Reload(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
controller.Reload(args[0]->IsBoolean() ? args[0]->BooleanValue(): false);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Handle<v8::Value> Window::ReloadIgnoringCache(const v8::Arguments &args) {
|
||||
UNWRAP_WINDOW_AND_CHECK;
|
||||
|
||||
NavigationController& controller =
|
||||
self->window_->GetWebContents()->GetController();
|
||||
controller.ReloadIgnoringCache(
|
||||
args[0]->IsBoolean() ? args[0]->BooleanValue(): false);
|
||||
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
// static
|
||||
void Window::Initialize(v8::Handle<v8::Object> target) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(Window::New);
|
||||
t->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
t->SetClassName(v8::String::NewSymbol("BrowserWindow"));
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "destroy", Destroy);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "close", Close);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "focus", Focus);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isFocused", IsFocused);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "show", Show);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "hide", Hide);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "maximize", Maximize);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "unmaximize", Unmaximize);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "minimize", Minimize);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "restore", Restore);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setFullScreen", SetFullscreen);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isFullScreen", IsFullscreen);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setSize", SetSize);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getSize", GetSize);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setMinimumSize", SetMinimumSize);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getMinimumSize", GetMinimumSize);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setMaximumSize", SetMaximumSize);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getMaximumSize", GetMaximumSize);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setResizable", SetResizable);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isResizable", IsResizable);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setAlwaysOnTop", SetAlwaysOnTop);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isAlwaysOnTop", IsAlwaysOnTop);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "center", Center);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setPosition", SetPosition);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getPosition", GetPosition);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setTitle", SetTitle);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getTitle", GetTitle);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "flashFrame", FlashFrame);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setKiosk", SetKiosk);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isKiosk", IsKiosk);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "openDevTools", OpenDevTools);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "closeDevTools", CloseDevTools);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "inspectElement", InspectElement);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "focusOnWebView", FocusOnWebView);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "blurWebView", BlurWebView);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isWebViewFocused", IsWebViewFocused);
|
||||
NODE_SET_PROTOTYPE_METHOD(t,
|
||||
"restartHangMonitorTimeout",
|
||||
RestartHangMonitorTimeout);
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getPageTitle", GetPageTitle);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isLoading", IsLoading);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isWaitingForResponse", IsWaitingForResponse);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "stop", Stop);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getRoutingId", GetRoutingID);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getProcessId", GetProcessID);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "isCrashed", IsCrashed);
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "loadUrl", LoadURL);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getUrl", GetURL);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "canGoBack", CanGoBack);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "canGoForward", CanGoForward);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "canGoToOffset", CanGoToOffset);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "goBack", GoBack);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "goForward", GoForward);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "goToIndex", GoToIndex);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "goToOffset", GoToOffset);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "reload", Reload);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "reloadIgnoringCache", ReloadIgnoringCache);
|
||||
|
||||
target->Set(v8::String::NewSymbol("BrowserWindow"), t->GetFunction());
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
NODE_MODULE(atom_browser_window, atom::api::Window::Initialize)
|
||||
119
browser/api/atom_api_window.h
Normal file
119
browser/api/atom_api_window.h
Normal file
@@ -0,0 +1,119 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
||||
#define ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "browser/api/atom_api_event_emitter.h"
|
||||
#include "browser/native_window_observer.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class NativeWindow;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Window : public EventEmitter,
|
||||
public NativeWindowObserver {
|
||||
public:
|
||||
virtual ~Window();
|
||||
|
||||
static void Initialize(v8::Handle<v8::Object> target);
|
||||
|
||||
NativeWindow* window() { return window_.get(); }
|
||||
|
||||
protected:
|
||||
explicit Window(v8::Handle<v8::Object> wrapper,
|
||||
base::DictionaryValue* options);
|
||||
|
||||
// Implementations of NativeWindowObserver.
|
||||
virtual void OnPageTitleUpdated(bool* prevent_default,
|
||||
const std::string& title) OVERRIDE;
|
||||
virtual void WillCloseWindow(bool* prevent_default) OVERRIDE;
|
||||
virtual void OnWindowClosed() OVERRIDE;
|
||||
virtual void OnWindowBlur() OVERRIDE;
|
||||
virtual void OnRendererUnresponsive() OVERRIDE;
|
||||
virtual void OnRendererResponsive() OVERRIDE;
|
||||
virtual void OnRendererCrashed() OVERRIDE;
|
||||
|
||||
private:
|
||||
static v8::Handle<v8::Value> New(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Destroy(const v8::Arguments &args);
|
||||
|
||||
// APIs for NativeWindow.
|
||||
static v8::Handle<v8::Value> Close(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Focus(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsFocused(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Show(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Hide(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Maximize(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Unmaximize(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Minimize(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Restore(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetFullscreen(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsFullscreen(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetSize(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetSize(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetMinimumSize(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetMinimumSize(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetMaximumSize(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetMaximumSize(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetResizable(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsResizable(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetAlwaysOnTop(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsAlwaysOnTop(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Center(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetPosition(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetPosition(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetTitle(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetTitle(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> FlashFrame(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> SetKiosk(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsKiosk(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> OpenDevTools(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> CloseDevTools(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> InspectElement(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> FocusOnWebView(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> BlurWebView(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsWebViewFocused(const v8::Arguments& args);
|
||||
static v8::Handle<v8::Value> RestartHangMonitorTimeout(
|
||||
const v8::Arguments &args);
|
||||
|
||||
// APIs for WebContents.
|
||||
static v8::Handle<v8::Value> GetPageTitle(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsLoading(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsWaitingForResponse(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Stop(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetRoutingID(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetProcessID(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> IsCrashed(const v8::Arguments &args);
|
||||
|
||||
// APIs for NavigationController.
|
||||
static v8::Handle<v8::Value> LoadURL(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GetURL(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> CanGoBack(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> CanGoForward(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> CanGoToOffset(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GoBack(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GoForward(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GoToIndex(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> GoToOffset(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Reload(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> ReloadIgnoringCache(const v8::Arguments &args);
|
||||
|
||||
scoped_ptr<NativeWindow> window_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Window);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_API_WINDOW_H_
|
||||
111
browser/api/atom_browser_bindings.cc
Normal file
111
browser/api/atom_browser_bindings.cc
Normal file
@@ -0,0 +1,111 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/api/atom_browser_bindings.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/values.h"
|
||||
#include "common/v8_value_converter_impl.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
#include "vendor/node/src/node_internals.h"
|
||||
|
||||
using content::V8ValueConverter;
|
||||
using node::node_isolate;
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomBrowserBindings::AtomBrowserBindings() {
|
||||
}
|
||||
|
||||
AtomBrowserBindings::~AtomBrowserBindings() {
|
||||
}
|
||||
|
||||
void AtomBrowserBindings::AfterLoad() {
|
||||
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
||||
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::Object> global = node::g_context->Global();
|
||||
v8::Handle<v8::Object> atom =
|
||||
global->Get(v8::String::New("__atom"))->ToObject();
|
||||
DCHECK(!atom.IsEmpty());
|
||||
|
||||
browser_main_parts_ = v8::Persistent<v8::Object>::New(
|
||||
node_isolate,
|
||||
atom->Get(v8::String::New("browserMainParts"))->ToObject());
|
||||
DCHECK(!browser_main_parts_.IsEmpty());
|
||||
}
|
||||
|
||||
void AtomBrowserBindings::OnRendererMessage(int process_id,
|
||||
int routing_id,
|
||||
const std::string& channel,
|
||||
const base::ListValue& args) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
|
||||
|
||||
scoped_ptr<V8ValueConverter> converter(new V8ValueConverterImpl());
|
||||
|
||||
// process.emit(channel, 'message', process_id, routing_id);
|
||||
std::vector<v8::Handle<v8::Value>> arguments;
|
||||
arguments.reserve(3 + args.GetSize());
|
||||
arguments.push_back(v8::String::New(channel.c_str(), channel.size()));
|
||||
const base::Value* value;
|
||||
if (args.Get(0, &value))
|
||||
arguments.push_back(converter->ToV8Value(value, context));
|
||||
arguments.push_back(v8::Integer::New(process_id));
|
||||
arguments.push_back(v8::Integer::New(routing_id));
|
||||
|
||||
for (size_t i = 1; i < args.GetSize(); i++) {
|
||||
const base::Value* value;
|
||||
if (args.Get(i, &value))
|
||||
arguments.push_back(converter->ToV8Value(value, context));
|
||||
}
|
||||
|
||||
node::MakeCallback(node::process, "emit", arguments.size(), &arguments[0]);
|
||||
}
|
||||
|
||||
void AtomBrowserBindings::OnRendererMessageSync(
|
||||
int process_id,
|
||||
int routing_id,
|
||||
const std::string& channel,
|
||||
const base::ListValue& args,
|
||||
base::DictionaryValue* result) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
|
||||
|
||||
scoped_ptr<V8ValueConverter> converter(new V8ValueConverterImpl());
|
||||
|
||||
v8::Handle<v8::Object> event = v8::Object::New();
|
||||
|
||||
// process.emit(channel, 'sync-message', event, process_id, routing_id);
|
||||
std::vector<v8::Handle<v8::Value>> arguments;
|
||||
arguments.reserve(3 + args.GetSize());
|
||||
arguments.push_back(v8::String::New(channel.c_str(), channel.size()));
|
||||
const base::Value* value;
|
||||
if (args.Get(0, &value))
|
||||
arguments.push_back(converter->ToV8Value(value, context));
|
||||
arguments.push_back(event);
|
||||
arguments.push_back(v8::Integer::New(process_id));
|
||||
arguments.push_back(v8::Integer::New(routing_id));
|
||||
|
||||
for (size_t i = 1; i < args.GetSize(); i++) {
|
||||
const base::Value* value;
|
||||
if (args.Get(i, &value))
|
||||
arguments.push_back(converter->ToV8Value(value, context));
|
||||
}
|
||||
|
||||
node::MakeCallback(node::process, "emit", arguments.size(), &arguments[0]);
|
||||
|
||||
scoped_ptr<base::Value> base_event(converter->FromV8Value(event, context));
|
||||
DCHECK(base_event && base_event->IsType(base::Value::TYPE_DICTIONARY));
|
||||
|
||||
result->Swap(static_cast<base::DictionaryValue*>(base_event.get()));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
53
browser/api/atom_browser_bindings.h
Normal file
53
browser/api/atom_browser_bindings.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_
|
||||
#define ATOM_BROWSER_API_ATOM_BROWSER_BINDINGS_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common/api/atom_bindings.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
class ListValue;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserBindings : public AtomBindings {
|
||||
public:
|
||||
AtomBrowserBindings();
|
||||
virtual ~AtomBrowserBindings();
|
||||
|
||||
// Called when the node.js main script has been loaded.
|
||||
virtual void AfterLoad();
|
||||
|
||||
// Called when received a message from renderer.
|
||||
void OnRendererMessage(int process_id,
|
||||
int routing_id,
|
||||
const std::string& channel,
|
||||
const base::ListValue& args);
|
||||
|
||||
// Called when received a synchronous message from renderer.
|
||||
void OnRendererMessageSync(int process_id,
|
||||
int routing_id,
|
||||
const std::string& channel,
|
||||
const base::ListValue& args,
|
||||
base::DictionaryValue* result);
|
||||
|
||||
// The require('atom').browserMainParts object.
|
||||
v8::Handle<v8::Object> browser_main_parts() {
|
||||
return browser_main_parts_;
|
||||
}
|
||||
|
||||
private:
|
||||
v8::Persistent<v8::Object> browser_main_parts_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserBindings);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_API_ATOM_BINDINGS_
|
||||
24
browser/api/lib/app.coffee
Normal file
24
browser/api/lib/app.coffee
Normal file
@@ -0,0 +1,24 @@
|
||||
bindings = process.atomBinding 'app'
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
Application = bindings.Application
|
||||
Application::__proto__ = EventEmitter.prototype
|
||||
|
||||
app = new Application
|
||||
|
||||
app.getHomeDir = ->
|
||||
process.env[if process.platform is 'win32' then 'USERPROFILE' else 'HOME']
|
||||
|
||||
app.commandLine =
|
||||
appendSwitch: bindings.appendSwitch,
|
||||
appendArgument: bindings.appendArgument
|
||||
|
||||
if process.platform is 'darwin'
|
||||
app.dock =
|
||||
bounce: (type = 'informational') -> bindings.dockBounce type
|
||||
cancelBounce: bindings.dockCancelBounce
|
||||
setBadge: bindings.dockSetBadgeText
|
||||
getBadge: bindings.dockGetBadgeText
|
||||
|
||||
# Only one App object pemitted.
|
||||
module.exports = app
|
||||
1
browser/api/lib/atom-delegate.coffee
Normal file
1
browser/api/lib/atom-delegate.coffee
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = global.__atom
|
||||
12
browser/api/lib/auto-updater.coffee
Normal file
12
browser/api/lib/auto-updater.coffee
Normal file
@@ -0,0 +1,12 @@
|
||||
AutoUpdater = process.atomBinding('auto_updater').AutoUpdater
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
AutoUpdater::__proto__ = EventEmitter.prototype
|
||||
|
||||
autoUpdater = new AutoUpdater
|
||||
autoUpdater.on 'will-install-update-raw', (event, version) ->
|
||||
@emit 'will-install-update', event, version, => @continueUpdate()
|
||||
autoUpdater.on 'ready-for-update-on-quit-raw', (event, version) ->
|
||||
@emit 'ready-for-update-on-quit', event, version, => @quitAndInstall()
|
||||
|
||||
module.exports = autoUpdater
|
||||
29
browser/api/lib/browser-window.coffee
Normal file
29
browser/api/lib/browser-window.coffee
Normal file
@@ -0,0 +1,29 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
objectsRegistry = require '../../atom/objects-registry.js'
|
||||
|
||||
BrowserWindow = process.atomBinding('window').BrowserWindow
|
||||
BrowserWindow::__proto__ = EventEmitter.prototype
|
||||
|
||||
BrowserWindow::toggleDevTools = ->
|
||||
opened = v8Util.getHiddenValue this, 'devtoolsOpened'
|
||||
if opened
|
||||
@closeDevTools()
|
||||
v8Util.setHiddenValue this, 'devtoolsOpened', false
|
||||
else
|
||||
@openDevTools()
|
||||
v8Util.setHiddenValue this, 'devtoolsOpened', true
|
||||
|
||||
BrowserWindow::restart = ->
|
||||
@loadUrl(@getUrl())
|
||||
|
||||
BrowserWindow.getFocusedWindow = ->
|
||||
windows = objectsRegistry.getAllWindows()
|
||||
return window for window in windows when window.isFocused()
|
||||
|
||||
BrowserWindow.fromProcessIdAndRoutingId = (processId, routingId) ->
|
||||
windows = objectsRegistry.getAllWindows()
|
||||
return window for window in windows when window.getProcessId() == processId and
|
||||
window.getRoutingId() == routingId
|
||||
|
||||
module.exports = BrowserWindow
|
||||
1
browser/api/lib/crash-reporter.coffee
Normal file
1
browser/api/lib/crash-reporter.coffee
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = process.atomBinding 'crash_reporter'
|
||||
54
browser/api/lib/dialog.coffee
Normal file
54
browser/api/lib/dialog.coffee
Normal file
@@ -0,0 +1,54 @@
|
||||
binding = process.atomBinding 'dialog'
|
||||
BrowserWindow = require 'browser-window'
|
||||
|
||||
fileDialogProperties =
|
||||
openFile: 1, openDirectory: 2, multiSelections: 4, createDirectory: 8
|
||||
|
||||
messageBoxTypes = ['none', 'info', 'warning']
|
||||
|
||||
module.exports =
|
||||
showOpenDialog: (options) ->
|
||||
options = title: 'Open', properties: ['openFile'] unless options?
|
||||
options.properties = options.properties ? ['openFile']
|
||||
throw new TypeError('Properties need to be array') unless Array.isArray options.properties
|
||||
|
||||
properties = 0
|
||||
for prop, value of fileDialogProperties
|
||||
properties |= value if prop in options.properties
|
||||
|
||||
options.title = options.title ? ''
|
||||
options.defaultPath = options.defaultPath ? ''
|
||||
|
||||
binding.showOpenDialog options.title, options.defaultPath, properties
|
||||
|
||||
showSaveDialog: (window, options) ->
|
||||
throw new TypeError('Invalid window') unless window?.constructor is BrowserWindow
|
||||
options = title: 'Save' unless options?
|
||||
|
||||
options.title = options.title ? ''
|
||||
options.defaultPath = options.defaultPath ? ''
|
||||
|
||||
binding.showSaveDialog window, options.title, options.defaultPath
|
||||
|
||||
showMessageBox: (window, options) ->
|
||||
if window? and window.constructor isnt BrowserWindow
|
||||
options = window
|
||||
window = null
|
||||
|
||||
options = type: 'none' unless options?
|
||||
options.type = options.type ? 'none'
|
||||
options.type = messageBoxTypes.indexOf options.type
|
||||
throw new TypeError('Invalid message box type') unless options.type > -1
|
||||
|
||||
throw new TypeError('Buttons need to be array') unless Array.isArray options.buttons
|
||||
|
||||
options.title = options.title ? ''
|
||||
options.message = options.message ? ''
|
||||
options.detail = options.detail ? ''
|
||||
|
||||
binding.showMessageBox options.type,
|
||||
options.buttons,
|
||||
String(options.title),
|
||||
String(options.message),
|
||||
String(options.detail),
|
||||
window
|
||||
26
browser/api/lib/ipc.coffee
Normal file
26
browser/api/lib/ipc.coffee
Normal file
@@ -0,0 +1,26 @@
|
||||
EventEmitter = require('events').EventEmitter
|
||||
send = process.atomBinding('ipc').send
|
||||
|
||||
sendWrap = (channel, processId, routingId, args...) ->
|
||||
BrowserWindow = require 'browser-window'
|
||||
if processId?.constructor is BrowserWindow
|
||||
window = processId
|
||||
processId = window.getProcessId()
|
||||
routingId = window.getRoutingId()
|
||||
|
||||
send channel, processId, routingId, args...
|
||||
|
||||
class Ipc extends EventEmitter
|
||||
constructor: ->
|
||||
process.on 'ATOM_INTERNAL_MESSAGE', (args...) =>
|
||||
@emit(args...)
|
||||
process.on 'ATOM_INTERNAL_MESSAGE_SYNC', (args...) =>
|
||||
@emit(args...)
|
||||
|
||||
send: (processId, routingId, args...) ->
|
||||
@sendChannel(processId, routingId, 'message', args...)
|
||||
|
||||
sendChannel: (args...) ->
|
||||
sendWrap('ATOM_INTERNAL_MESSAGE', args...)
|
||||
|
||||
module.exports = new Ipc
|
||||
33
browser/api/lib/menu-item.coffee
Normal file
33
browser/api/lib/menu-item.coffee
Normal file
@@ -0,0 +1,33 @@
|
||||
nextCommandId = 0
|
||||
|
||||
class MenuItem
|
||||
@types = ['normal', 'separator', 'submenu', 'checkbox', 'radio']
|
||||
|
||||
constructor: (options) ->
|
||||
Menu = require 'menu'
|
||||
|
||||
{click, @selector, @type, @label, @sublabel, @accelerator, @enabled, @visible, @checked, @groupId, @submenu} = options
|
||||
|
||||
@type = 'submenu' if not @type? and @submenu?
|
||||
throw new Error('Invalid submenu') if @type is 'submenu' and @submenu?.constructor isnt Menu
|
||||
|
||||
@type = @type ? 'normal'
|
||||
@label = @label ? ''
|
||||
@sublabel = @sublabel ? ''
|
||||
@accelerator = @accelerator ? null
|
||||
@enabled = @enabled ? true
|
||||
@visible = @visible ? true
|
||||
@checked = @checked ? false
|
||||
@groupId = @groupId ? null
|
||||
@submenu = @submenu ? null
|
||||
|
||||
throw new Error('Unknown menu type') if MenuItem.types.indexOf(@type) is -1
|
||||
|
||||
@commandId = ++nextCommandId
|
||||
@click = =>
|
||||
if typeof click is 'function'
|
||||
click.apply this, arguments
|
||||
else if typeof @selector is 'string'
|
||||
Menu.sendActionToFirstResponder @selector
|
||||
|
||||
module.exports = MenuItem
|
||||
67
browser/api/lib/menu.coffee
Normal file
67
browser/api/lib/menu.coffee
Normal file
@@ -0,0 +1,67 @@
|
||||
BrowserWindow = require 'browser-window'
|
||||
EventEmitter = require('events').EventEmitter
|
||||
IDWeakMap = require 'id-weak-map'
|
||||
MenuItem = require 'menu-item'
|
||||
|
||||
bindings = process.atomBinding 'menu'
|
||||
|
||||
Menu = bindings.Menu
|
||||
Menu::__proto__ = EventEmitter.prototype
|
||||
|
||||
popup = Menu::popup
|
||||
Menu::popup = (window) ->
|
||||
throw new TypeError('Invalid window') unless window?.constructor is BrowserWindow
|
||||
|
||||
popup.call this, window
|
||||
|
||||
Menu::append = (item) ->
|
||||
@insert @getItemCount(), item
|
||||
|
||||
Menu::insert = (pos, item) ->
|
||||
throw new TypeError('Invalid item') unless item?.constructor is MenuItem
|
||||
|
||||
switch item.type
|
||||
when 'normal' then @insertItem pos, item.commandId, item.label
|
||||
when 'checkbox' then @insertCheckItem pos, item.commandId, item.label
|
||||
when 'radio' then @insertRadioItem pos, item.commandId, item.label, item.groupId
|
||||
when 'separator' then @insertSeparator pos
|
||||
when 'submenu' then @insertSubMenu pos, item.commandId, item.label, item.submenu
|
||||
|
||||
@setSublabel pos, item.sublabel if item.sublabel?
|
||||
|
||||
unless @delegate?
|
||||
@commandsMap = {}
|
||||
@items = []
|
||||
@delegate =
|
||||
isCommandIdChecked: (commandId) => @commandsMap[commandId]?.checked
|
||||
isCommandIdEnabled: (commandId) => @commandsMap[commandId]?.enabled
|
||||
isCommandIdVisible: (commandId) => @commandsMap[commandId]?.visible
|
||||
getAcceleratorForCommandId: (commandId) => @commandsMap[commandId]?.accelerator
|
||||
executeCommand: (commandId) =>
|
||||
activeItem = @commandsMap[commandId]
|
||||
activeItem.click(activeItem) if activeItem?
|
||||
@items.splice pos, 0, item
|
||||
@commandsMap[item.commandId] = item
|
||||
|
||||
Menu.setApplicationMenu = (menu) ->
|
||||
throw new TypeError('Invalid menu') unless menu?.constructor is Menu
|
||||
bindings.setApplicationMenu menu
|
||||
|
||||
Menu.sendActionToFirstResponder = bindings.sendActionToFirstResponder
|
||||
|
||||
Menu.buildFromTemplate = (template) ->
|
||||
throw new TypeError('Invalid template for Menu') unless Array.isArray template
|
||||
|
||||
menu = new Menu
|
||||
for item in template
|
||||
throw new TypeError('Invalid template for MenuItem') unless typeof item is 'object'
|
||||
|
||||
item.submenu = Menu.buildFromTemplate item.submenu if item.submenu?
|
||||
menuItem = new MenuItem(item)
|
||||
menuItem[key] = value for key, value of item when not menuItem[key]?
|
||||
|
||||
menu.append menuItem
|
||||
|
||||
menu
|
||||
|
||||
module.exports = Menu
|
||||
7
browser/api/lib/power-monitor.coffee
Normal file
7
browser/api/lib/power-monitor.coffee
Normal file
@@ -0,0 +1,7 @@
|
||||
bindings = process.atomBinding 'power_monitor'
|
||||
EventEmitter = require('events').EventEmitter
|
||||
|
||||
PowerMonitor = bindings.PowerMonitor
|
||||
PowerMonitor::__proto__ = EventEmitter.prototype
|
||||
|
||||
module.exports = new PowerMonitor
|
||||
57
browser/atom/atom.coffee
Normal file
57
browser/atom/atom.coffee
Normal file
@@ -0,0 +1,57 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
|
||||
# Redirect node's console to use our own implementations, since node can not
|
||||
# handle output when running as GUI program.
|
||||
if process.platform is 'win32'
|
||||
console.log = console.error = console.warn = process.log
|
||||
process.stdout.write = process.stderr.write = process.log
|
||||
|
||||
# Provide default Content API implementations.
|
||||
atom = {}
|
||||
|
||||
atom.browserMainParts =
|
||||
preMainMessageLoopRun: ->
|
||||
# This is the start of the whole application, usually we should initialize
|
||||
# the main window here.
|
||||
|
||||
# Store atom object in global scope, apps can just override methods of it to
|
||||
# implement various logics.
|
||||
global.__atom = atom
|
||||
|
||||
# Add browser/api/lib to require's search paths,
|
||||
# which contains javascript part of Atom's built-in libraries.
|
||||
globalPaths = require('module').globalPaths
|
||||
globalPaths.push path.join process.resourcesPath, 'browser', 'api', 'lib'
|
||||
|
||||
# And also common/api/lib
|
||||
globalPaths.push path.join process.resourcesPath, 'common', 'api', 'lib'
|
||||
|
||||
# Don't quit on fatal error.
|
||||
process.on 'uncaughtException', (error) ->
|
||||
# Show error in GUI.
|
||||
message = error.stack ? "#{error.name}: #{error.message}"
|
||||
require('dialog').showMessageBox
|
||||
type: 'warning'
|
||||
title: 'An javascript error occured in the browser'
|
||||
message: 'uncaughtException'
|
||||
detail: message
|
||||
buttons: ['OK']
|
||||
|
||||
# Load the RPC server.
|
||||
require './rpc-server.js'
|
||||
|
||||
# Now we try to load app's package.json.
|
||||
packageJson = null
|
||||
|
||||
packagePath = path.join process.resourcesPath, 'app'
|
||||
try
|
||||
# First we try to load process.resourcesPath/app
|
||||
packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json')))
|
||||
catch error
|
||||
# If not found then we load browser/default_app
|
||||
packagePath = path.join process.resourcesPath, 'browser', 'default_app'
|
||||
packageJson = JSON.parse(fs.readFileSync(path.join(packagePath, 'package.json')))
|
||||
|
||||
# Finally load app's main.js and transfer control to C++.
|
||||
require path.join(packagePath, packageJson.main)
|
||||
82
browser/atom/objects-registry.coffee
Normal file
82
browser/atom/objects-registry.coffee
Normal file
@@ -0,0 +1,82 @@
|
||||
BrowserWindow = require 'browser-window'
|
||||
IDWeakMap = require 'id-weak-map'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
|
||||
class ObjectsStore
|
||||
@stores = {}
|
||||
|
||||
constructor: ->
|
||||
@nextId = 0
|
||||
@objects = []
|
||||
|
||||
getNextId: ->
|
||||
++@nextId
|
||||
|
||||
add: (obj) ->
|
||||
id = @getNextId()
|
||||
@objects[id] = obj
|
||||
id
|
||||
|
||||
has: (id) ->
|
||||
@objects[id]?
|
||||
|
||||
remove: (id) ->
|
||||
throw new Error("Invalid key #{id} for ObjectsStore") unless @has id
|
||||
delete @objects[id]
|
||||
|
||||
get: (id) ->
|
||||
throw new Error("Invalid key #{id} for ObjectsStore") unless @has id
|
||||
@objects[id]
|
||||
|
||||
@forRenderView: (processId, routingId) ->
|
||||
key = "#{processId}_#{routingId}"
|
||||
@stores[key] = new ObjectsStore unless @stores[key]?
|
||||
@stores[key]
|
||||
|
||||
@releaseForRenderView: (processId, routingId) ->
|
||||
key = "#{processId}_#{routingId}"
|
||||
delete @stores[key]
|
||||
|
||||
# Objects in weak map will be not referenced (so we won't leak memory), and
|
||||
# every object created in browser will have a unique id in weak map.
|
||||
objectsWeakMap = new IDWeakMap
|
||||
objectsWeakMap.add = (obj) ->
|
||||
id = IDWeakMap::add.call this, obj
|
||||
v8Util.setHiddenValue obj, 'atomId', id
|
||||
id
|
||||
|
||||
windowsWeakMap = new IDWeakMap
|
||||
|
||||
process.on 'ATOM_BROWSER_INTERNAL_NEW', (obj) ->
|
||||
# Remember all windows.
|
||||
if obj.constructor is BrowserWindow
|
||||
id = windowsWeakMap.add obj
|
||||
obj.on 'destroyed', ->
|
||||
windowsWeakMap.remove id
|
||||
|
||||
exports.add = (processId, routingId, obj) ->
|
||||
# Some native objects may already been added to objectsWeakMap, be care not
|
||||
# to add it twice.
|
||||
objectsWeakMap.add obj unless v8Util.getHiddenValue obj, 'atomId'
|
||||
id = v8Util.getHiddenValue obj, 'atomId'
|
||||
|
||||
# Store and reference the object, then return the storeId which points to
|
||||
# where the object is stored. The caller can later dereference the object
|
||||
# with the storeId.
|
||||
store = ObjectsStore.forRenderView processId, routingId
|
||||
storeId = store.add obj
|
||||
|
||||
[id, storeId]
|
||||
|
||||
exports.get = (id) ->
|
||||
objectsWeakMap.get id
|
||||
|
||||
exports.getAllWindows = () ->
|
||||
keys = windowsWeakMap.keys()
|
||||
windowsWeakMap.get key for key in keys
|
||||
|
||||
exports.remove = (processId, routingId, storeId) ->
|
||||
ObjectsStore.forRenderView(processId, routingId).remove storeId
|
||||
|
||||
exports.clear = (processId, routingId) ->
|
||||
ObjectsStore.releaseForRenderView processId, routingId
|
||||
128
browser/atom/rpc-server.coffee
Normal file
128
browser/atom/rpc-server.coffee
Normal file
@@ -0,0 +1,128 @@
|
||||
ipc = require 'ipc'
|
||||
path = require 'path'
|
||||
objectsRegistry = require './objects-registry.js'
|
||||
v8Util = process.atomBinding 'v8_util'
|
||||
|
||||
# Convert a real value into meta data.
|
||||
valueToMeta = (processId, routingId, value) ->
|
||||
meta = type: typeof value
|
||||
|
||||
meta.type = 'value' if value is null
|
||||
meta.type = 'array' if Array.isArray value
|
||||
|
||||
# Treat the arguments object as array.
|
||||
meta.type = 'array' if meta.type is 'object' and value.callee? and value.length?
|
||||
|
||||
if meta.type is 'array'
|
||||
meta.members = []
|
||||
meta.members.push valueToMeta(processId, routingId, el) for el in value
|
||||
else if meta.type is 'object' or meta.type is 'function'
|
||||
meta.name = value.constructor.name
|
||||
|
||||
# Reference the original value if it's an object, because when it's
|
||||
# passed to renderer we would assume the renderer keeps a reference of
|
||||
# it.
|
||||
[meta.id, meta.storeId] = objectsRegistry.add processId, routingId, value
|
||||
|
||||
meta.members = []
|
||||
meta.members.push {name: prop, type: typeof field} for prop, field of value
|
||||
else
|
||||
meta.type = 'value'
|
||||
meta.value = value
|
||||
|
||||
meta
|
||||
|
||||
# Convert Error into meta data.
|
||||
errorToMeta = (error) ->
|
||||
type: 'error', message: error.message, stack: (error.stack || error)
|
||||
|
||||
# Convert array of meta data from renderer into array of real values.
|
||||
unwrapArgs = (processId, routingId, args) ->
|
||||
metaToValue = (meta) ->
|
||||
switch meta.type
|
||||
when 'value' then meta.value
|
||||
when 'remote-object' then objectsRegistry.get meta.id
|
||||
when 'array' then unwrapArgs processId, routingId, meta.value
|
||||
when 'object'
|
||||
ret = {}
|
||||
for member in meta.members
|
||||
ret[member.name] = metaToValue(member.value)
|
||||
ret
|
||||
when 'function'
|
||||
ret = ->
|
||||
ipc.sendChannel processId, routingId, 'ATOM_RENDERER_CALLBACK', meta.id, valueToMeta(processId, routingId, arguments)
|
||||
v8Util.setDestructor ret, ->
|
||||
ipc.sendChannel processId, routingId, 'ATOM_RENDERER_RELEASE_CALLBACK', meta.id
|
||||
ret
|
||||
else throw new TypeError("Unknown type: #{meta.type}")
|
||||
|
||||
args.map metaToValue
|
||||
|
||||
ipc.on 'ATOM_BROWSER_REQUIRE', (event, processId, routingId, module) ->
|
||||
try
|
||||
event.result = valueToMeta processId, routingId, require(module)
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_GLOBAL', (event, processId, routingId, name) ->
|
||||
try
|
||||
event.result = valueToMeta processId, routingId, global[name]
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_RELEASE_RENDER_VIEW', (event, processId, routingId) ->
|
||||
objectsRegistry.clear processId, routingId
|
||||
|
||||
ipc.on 'ATOM_BROWSER_CURRENT_WINDOW', (event, processId, routingId) ->
|
||||
try
|
||||
BrowserWindow = require 'browser-window'
|
||||
window = BrowserWindow.fromProcessIdAndRoutingId processId, routingId
|
||||
event.result = valueToMeta processId, routingId, window
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_CONSTRUCTOR', (event, processId, routingId, id, args) ->
|
||||
try
|
||||
args = unwrapArgs processId, routingId, args
|
||||
constructor = objectsRegistry.get id
|
||||
# Call new with array of arguments.
|
||||
# http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
|
||||
obj = new (Function::bind.apply(constructor, [null].concat(args)))
|
||||
event.result = valueToMeta processId, routingId, obj
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_FUNCTION_CALL', (event, processId, routingId, id, args) ->
|
||||
try
|
||||
args = unwrapArgs processId, routingId, args
|
||||
func = objectsRegistry.get id
|
||||
ret = func.apply global, args
|
||||
event.result = valueToMeta processId, routingId, ret
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_CALL', (event, processId, routingId, id, method, args) ->
|
||||
try
|
||||
args = unwrapArgs processId, routingId, args
|
||||
obj = objectsRegistry.get id
|
||||
ret = obj[method].apply(obj, args)
|
||||
event.result = valueToMeta processId, routingId, ret
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_SET', (event, processId, routingId, id, name, value) ->
|
||||
try
|
||||
obj = objectsRegistry.get id
|
||||
obj[name] = value
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_MEMBER_GET', (event, processId, routingId, id, name) ->
|
||||
try
|
||||
obj = objectsRegistry.get id
|
||||
event.result = valueToMeta processId, routingId, obj[name]
|
||||
catch e
|
||||
event.result = errorToMeta e
|
||||
|
||||
ipc.on 'ATOM_BROWSER_DEREFERENCE', (processId, routingId, storeId) ->
|
||||
objectsRegistry.remove processId, routingId, storeId
|
||||
10
browser/atom_application_delegate_mac.h
Normal file
10
browser/atom_application_delegate_mac.h
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface AtomApplicationDelegate : NSObject<NSApplicationDelegate> {
|
||||
}
|
||||
|
||||
@end
|
||||
38
browser/atom_application_delegate_mac.mm
Normal file
38
browser/atom_application_delegate_mac.mm
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "browser/atom_application_delegate_mac.h"
|
||||
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#import "browser/atom_application_mac.h"
|
||||
#include "browser/browser.h"
|
||||
|
||||
@implementation AtomApplicationDelegate
|
||||
|
||||
- (void)applicationWillFinishLaunching:(NSNotification*)notify {
|
||||
atom::Browser::Get()->WillFinishLaunching();
|
||||
}
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification*)notify {
|
||||
atom::Browser::Get()->DidFinishLaunching();
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication*)sender
|
||||
openFile:(NSString*)filename {
|
||||
std::string filename_str(base::SysNSStringToUTF8(filename));
|
||||
return atom::Browser::Get()->OpenFile(filename_str) ? YES : NO;
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender {
|
||||
atom::Browser* browser = atom::Browser::Get();
|
||||
if (browser->is_quiting()) {
|
||||
return NSTerminateNow;
|
||||
} else {
|
||||
// System started termination.
|
||||
atom::Browser::Get()->Quit();
|
||||
return NSTerminateLater;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
23
browser/atom_application_mac.h
Normal file
23
browser/atom_application_mac.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "base/mac/scoped_sending_event.h"
|
||||
|
||||
@interface AtomApplication : NSApplication<CrAppProtocol,
|
||||
CrAppControlProtocol> {
|
||||
@private
|
||||
BOOL handlingSendEvent_;
|
||||
}
|
||||
|
||||
+ (AtomApplication*)sharedApplication;
|
||||
|
||||
// CrAppProtocol:
|
||||
- (BOOL)isHandlingSendEvent;
|
||||
|
||||
// CrAppControlProtocol:
|
||||
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent;
|
||||
|
||||
- (IBAction)closeAllWindows:(id)sender;
|
||||
|
||||
@end
|
||||
49
browser/atom_application_mac.mm
Normal file
49
browser/atom_application_mac.mm
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "browser/atom_application_mac.h"
|
||||
|
||||
#include "base/auto_reset.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "browser/browser.h"
|
||||
|
||||
@implementation AtomApplication
|
||||
|
||||
+ (AtomApplication*)sharedApplication {
|
||||
return (AtomApplication*)[super sharedApplication];
|
||||
}
|
||||
|
||||
- (BOOL)isHandlingSendEvent {
|
||||
return handlingSendEvent_;
|
||||
}
|
||||
|
||||
- (void)sendEvent:(NSEvent*)event {
|
||||
base::AutoReset<BOOL> scoper(&handlingSendEvent_, YES);
|
||||
[super sendEvent:event];
|
||||
}
|
||||
|
||||
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent {
|
||||
handlingSendEvent_ = handlingSendEvent;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
setEventHandler:self
|
||||
andSelector:@selector(handleURLEvent:withReplyEvent:)
|
||||
forEventClass:kInternetEventClass
|
||||
andEventID:kAEGetURL];
|
||||
}
|
||||
|
||||
- (IBAction)closeAllWindows:(id)sender {
|
||||
atom::Browser::Get()->Quit();
|
||||
}
|
||||
|
||||
- (void)handleURLEvent:(NSAppleEventDescriptor*)event
|
||||
withReplyEvent:(NSAppleEventDescriptor*)replyEvent {
|
||||
NSString* url = [
|
||||
[event paramDescriptorForKeyword:keyDirectObject] stringValue];
|
||||
atom::Browser::Get()->OpenURL(base::SysNSStringToUTF8(url));
|
||||
}
|
||||
|
||||
@end
|
||||
53
browser/atom_browser_client.cc
Normal file
53
browser/atom_browser_client.cc
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/atom_browser_client.h"
|
||||
|
||||
#include "browser/atom_browser_main_parts.h"
|
||||
#include "webkit/glue/webpreferences.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomBrowserClient::AtomBrowserClient() {
|
||||
}
|
||||
|
||||
AtomBrowserClient::~AtomBrowserClient() {
|
||||
}
|
||||
|
||||
void AtomBrowserClient::OverrideWebkitPrefs(
|
||||
content::RenderViewHost* render_view_host,
|
||||
const GURL& url,
|
||||
WebPreferences* prefs) {
|
||||
prefs->javascript_enabled = true;
|
||||
prefs->web_security_enabled = false;
|
||||
prefs->javascript_can_open_windows_automatically = true;
|
||||
prefs->plugins_enabled = false;
|
||||
prefs->dom_paste_enabled = true;
|
||||
prefs->java_enabled = false;
|
||||
prefs->allow_scripts_to_close_windows = true;
|
||||
prefs->javascript_can_access_clipboard = true;
|
||||
prefs->local_storage_enabled = true;
|
||||
prefs->databases_enabled = true;
|
||||
prefs->application_cache_enabled = true;
|
||||
prefs->allow_universal_access_from_file_urls = true;
|
||||
prefs->allow_file_access_from_file_urls = true;
|
||||
prefs->experimental_webgl_enabled = false;
|
||||
prefs->allow_displaying_insecure_content = true;
|
||||
prefs->allow_running_insecure_content = true;
|
||||
}
|
||||
|
||||
bool AtomBrowserClient::ShouldSwapProcessesForNavigation(
|
||||
content::SiteInstance* site_instance,
|
||||
const GURL& current_url,
|
||||
const GURL& new_url) {
|
||||
// Restart renderer process if navigating to the same url.
|
||||
return current_url == new_url;
|
||||
}
|
||||
|
||||
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) {
|
||||
return new AtomBrowserMainParts;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
35
browser/atom_browser_client.h
Normal file
35
browser/atom_browser_client.h
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_BROWSER_CLIENT_
|
||||
#define ATOM_BROWSER_ATOM_BROWSER_CLIENT_
|
||||
|
||||
#include "brightray/browser/browser_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserClient : public brightray::BrowserClient {
|
||||
public:
|
||||
AtomBrowserClient();
|
||||
virtual ~AtomBrowserClient();
|
||||
|
||||
protected:
|
||||
virtual void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
|
||||
const GURL& url,
|
||||
WebPreferences* prefs) OVERRIDE;
|
||||
virtual bool ShouldSwapProcessesForNavigation(
|
||||
content::SiteInstance* site_instance,
|
||||
const GURL& current_url,
|
||||
const GURL& new_url) OVERRIDE;
|
||||
|
||||
private:
|
||||
virtual brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
|
||||
const content::MainFunctionParams&) OVERRIDE;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_BROWSER_CLIENT_
|
||||
23
browser/atom_browser_context.cc
Normal file
23
browser/atom_browser_context.cc
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/atom_browser_context.h"
|
||||
|
||||
#include "browser/atom_browser_main_parts.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomBrowserContext::AtomBrowserContext() {
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
}
|
||||
|
||||
// static
|
||||
AtomBrowserContext* AtomBrowserContext::Get() {
|
||||
return static_cast<AtomBrowserContext*>(
|
||||
AtomBrowserMainParts::Get()->browser_context());
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
26
browser/atom_browser_context.h
Normal file
26
browser/atom_browser_context.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
|
||||
#define ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "brightray/browser/browser_context.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext : public brightray::BrowserContext {
|
||||
public:
|
||||
AtomBrowserContext();
|
||||
virtual ~AtomBrowserContext();
|
||||
|
||||
static AtomBrowserContext* Get();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
|
||||
85
browser/atom_browser_main_parts.cc
Normal file
85
browser/atom_browser_main_parts.cc
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/atom_browser_main_parts.h"
|
||||
|
||||
#include "base/power_monitor/power_monitor.h"
|
||||
#include "browser/api/atom_browser_bindings.h"
|
||||
#include "browser/atom_browser_client.h"
|
||||
#include "browser/atom_browser_context.h"
|
||||
#include "browser/browser.h"
|
||||
#include "common/node_bindings.h"
|
||||
#include "vendor/node/src/node.h"
|
||||
#include "vendor/node/src/node_internals.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
// static
|
||||
AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
|
||||
|
||||
AtomBrowserMainParts::AtomBrowserMainParts()
|
||||
: atom_bindings_(new AtomBrowserBindings),
|
||||
browser_(new Browser),
|
||||
node_bindings_(NodeBindings::Create(true)) {
|
||||
DCHECK(!self_) << "Cannot have two AtomBrowserMainParts";
|
||||
self_ = this;
|
||||
}
|
||||
|
||||
AtomBrowserMainParts::~AtomBrowserMainParts() {
|
||||
}
|
||||
|
||||
// static
|
||||
AtomBrowserMainParts* AtomBrowserMainParts::Get() {
|
||||
DCHECK(self_);
|
||||
return self_;
|
||||
}
|
||||
|
||||
brightray::BrowserContext* AtomBrowserMainParts::CreateBrowserContext() {
|
||||
return new AtomBrowserContext();
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||
brightray::BrowserMainParts::PostEarlyInitialization();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
base::PowerMonitor::AllocateSystemIOPorts();
|
||||
#endif
|
||||
|
||||
node_bindings_->Initialize();
|
||||
|
||||
// Wrap whole process in one global context.
|
||||
node::g_context->Enter();
|
||||
|
||||
atom_bindings_->BindTo(node::process);
|
||||
|
||||
node_bindings_->Load();
|
||||
|
||||
atom_bindings_->AfterLoad();
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
node_bindings_->PrepareMessageLoop();
|
||||
|
||||
brightray::BrowserMainParts::PreMainMessageLoopRun();
|
||||
|
||||
{
|
||||
v8::HandleScope scope;
|
||||
v8::Context::Scope context_scope(node::g_context);
|
||||
|
||||
v8::Handle<v8::Value> args;
|
||||
node::MakeCallback(atom_bindings_->browser_main_parts(),
|
||||
"preMainMessageLoopRun",
|
||||
0, &args);
|
||||
}
|
||||
|
||||
node_bindings_->RunMessageLoop();
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
// The corresponding call in OS X is in AtomApplicationDelegate.
|
||||
Browser::Get()->WillFinishLaunching();
|
||||
Browser::Get()->DidFinishLaunching();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
50
browser/atom_browser_main_parts.h
Normal file
50
browser/atom_browser_main_parts.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_
|
||||
#define ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_
|
||||
|
||||
#include "brightray/browser/browser_main_parts.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserBindings;
|
||||
class Browser;
|
||||
class NodeBindings;
|
||||
|
||||
class AtomBrowserMainParts : public brightray::BrowserMainParts {
|
||||
public:
|
||||
AtomBrowserMainParts();
|
||||
virtual ~AtomBrowserMainParts();
|
||||
|
||||
static AtomBrowserMainParts* Get();
|
||||
|
||||
AtomBrowserBindings* atom_bindings() { return atom_bindings_.get(); }
|
||||
Browser* browser() { return browser_.get(); }
|
||||
|
||||
protected:
|
||||
// Implementations of brightray::BrowserMainParts.
|
||||
virtual brightray::BrowserContext* CreateBrowserContext() OVERRIDE;
|
||||
|
||||
// Implementations of content::BrowserMainParts.
|
||||
virtual void PostEarlyInitialization() OVERRIDE;
|
||||
virtual void PreMainMessageLoopRun() OVERRIDE;
|
||||
#if defined(OS_MACOSX)
|
||||
virtual void PreMainMessageLoopStart() OVERRIDE;
|
||||
virtual void PostDestroyThreads() OVERRIDE;
|
||||
#endif
|
||||
|
||||
private:
|
||||
scoped_ptr<AtomBrowserBindings> atom_bindings_;
|
||||
scoped_ptr<Browser> browser_;
|
||||
scoped_ptr<NodeBindings> node_bindings_;
|
||||
|
||||
static AtomBrowserMainParts* self_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_
|
||||
37
browser/atom_browser_main_parts_mac.mm
Normal file
37
browser/atom_browser_main_parts_mac.mm
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/atom_browser_main_parts.h"
|
||||
|
||||
#import "base/mac/bundle_locations.h"
|
||||
#import "browser/atom_application_mac.h"
|
||||
#import "browser/atom_application_delegate_mac.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopStart() {
|
||||
// Force the NSApplication subclass to be used.
|
||||
NSApplication* application = [AtomApplication sharedApplication];
|
||||
|
||||
AtomApplicationDelegate* delegate = [AtomApplicationDelegate alloc];
|
||||
[NSApp setDelegate:delegate];
|
||||
|
||||
auto infoDictionary = base::mac::OuterBundle().infoDictionary;
|
||||
|
||||
NSString *mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"];
|
||||
auto mainNib = [[NSNib alloc] initWithNibNamed:mainNibName bundle:base::mac::FrameworkBundle()];
|
||||
[mainNib instantiateWithOwner:application topLevelObjects:nil];
|
||||
[mainNib release];
|
||||
|
||||
// Prevent Cocoa from turning command-line arguments into
|
||||
// |-application:openFiles:|, since we already handle them directly.
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
|
||||
}
|
||||
|
||||
void AtomBrowserMainParts::PostDestroyThreads() {
|
||||
[[AtomApplication sharedApplication] setDelegate:nil];
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
33
browser/atom_event_processing_window.h
Normal file
33
browser/atom_event_processing_window.h
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_EVENT_PROCESSING_WINDOW_H_
|
||||
#define ATOM_BROWSER_ATOM_EVENT_PROCESSING_WINDOW_H_
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/memory/scoped_nsobject.h"
|
||||
#import "ui/base/cocoa/underlay_opengl_hosting_window.h"
|
||||
|
||||
// Override NSWindow to access unhandled keyboard events (for command
|
||||
// processing); subclassing NSWindow is the only method to do
|
||||
// this.
|
||||
@interface AtomEventProcessingWindow : UnderlayOpenGLHostingWindow {
|
||||
@private
|
||||
BOOL redispatchingEvent_;
|
||||
BOOL eventHandled_;
|
||||
}
|
||||
|
||||
// Sends a key event to |NSApp sendEvent:|, but also makes sure that it's not
|
||||
// short-circuited to the RWHV. This is used to send keyboard events to the menu
|
||||
// and the cmd-` handler if a keyboard event comes back unhandled from the
|
||||
// renderer. The event must be of type |NSKeyDown|, |NSKeyUp|, or
|
||||
// |NSFlagsChanged|.
|
||||
// Returns |YES| if |event| has been handled.
|
||||
- (BOOL)redispatchKeyEvent:(NSEvent*)event;
|
||||
|
||||
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
|
||||
@end
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_EVENT_PROCESSING_WINDOW_H_
|
||||
106
browser/atom_event_processing_window.mm
Normal file
106
browser/atom_event_processing_window.mm
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import "browser/atom_event_processing_window.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#import "content/public/browser/render_widget_host_view_mac_base.h"
|
||||
|
||||
@interface AtomEventProcessingWindow ()
|
||||
// Duplicate the given key event, but changing the associated window.
|
||||
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event;
|
||||
@end
|
||||
|
||||
@implementation AtomEventProcessingWindow
|
||||
|
||||
- (BOOL)redispatchKeyEvent:(NSEvent*)event {
|
||||
DCHECK(event);
|
||||
NSEventType eventType = [event type];
|
||||
if (eventType != NSKeyDown &&
|
||||
eventType != NSKeyUp &&
|
||||
eventType != NSFlagsChanged) {
|
||||
NOTREACHED();
|
||||
return YES; // Pretend it's been handled in an effort to limit damage.
|
||||
}
|
||||
|
||||
// Ordinarily, the event's window should be this window. However, when
|
||||
// switching between normal and fullscreen mode, we switch out the window, and
|
||||
// the event's window might be the previous window (or even an earlier one if
|
||||
// the renderer is running slowly and several mode switches occur). In this
|
||||
// rare case, we synthesize a new key event so that its associate window
|
||||
// (number) is our own.
|
||||
if ([event window] != self)
|
||||
event = [self keyEventForWindow:self fromKeyEvent:event];
|
||||
|
||||
// Redispatch the event.
|
||||
eventHandled_ = YES;
|
||||
redispatchingEvent_ = YES;
|
||||
[NSApp sendEvent:event];
|
||||
redispatchingEvent_ = NO;
|
||||
|
||||
// If the event was not handled by [NSApp sendEvent:], the sendEvent:
|
||||
// method below will be called, and because |redispatchingEvent_| is YES,
|
||||
// |eventHandled_| will be set to NO.
|
||||
return eventHandled_;
|
||||
}
|
||||
|
||||
- (void)sendEvent:(NSEvent*)event {
|
||||
if (!redispatchingEvent_)
|
||||
[super sendEvent:event];
|
||||
else
|
||||
eventHandled_ = NO;
|
||||
}
|
||||
|
||||
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event {
|
||||
NSEventType eventType = [event type];
|
||||
|
||||
// Convert the event's location from the original window's coordinates into
|
||||
// our own.
|
||||
NSPoint eventLoc = [event locationInWindow];
|
||||
eventLoc = [[event window] convertBaseToScreen:eventLoc];
|
||||
eventLoc = [self convertScreenToBase:eventLoc];
|
||||
|
||||
// Various things *only* apply to key down/up.
|
||||
BOOL eventIsARepeat = NO;
|
||||
NSString* eventCharacters = nil;
|
||||
NSString* eventUnmodCharacters = nil;
|
||||
if (eventType == NSKeyDown || eventType == NSKeyUp) {
|
||||
eventIsARepeat = [event isARepeat];
|
||||
eventCharacters = [event characters];
|
||||
eventUnmodCharacters = [event charactersIgnoringModifiers];
|
||||
}
|
||||
|
||||
// This synthesis may be slightly imperfect: we provide nil for the context,
|
||||
// since I (viettrungluu) am sceptical that putting in the original context
|
||||
// (if one is given) is valid.
|
||||
return [NSEvent keyEventWithType:eventType
|
||||
location:eventLoc
|
||||
modifierFlags:[event modifierFlags]
|
||||
timestamp:[event timestamp]
|
||||
windowNumber:[window windowNumber]
|
||||
context:nil
|
||||
characters:eventCharacters
|
||||
charactersIgnoringModifiers:eventUnmodCharacters
|
||||
isARepeat:eventIsARepeat
|
||||
keyCode:[event keyCode]];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)performKeyEquivalent:(NSEvent*)event {
|
||||
if (redispatchingEvent_)
|
||||
return NO;
|
||||
|
||||
// Give the web site a chance to handle the event. If it doesn't want to
|
||||
// handle it, it will call us back with one of the |handle*| methods above.
|
||||
NSResponder* r = [self firstResponder];
|
||||
if ([r conformsToProtocol:@protocol(RenderWidgetHostViewMacBase)])
|
||||
return [r performKeyEquivalent:event];
|
||||
|
||||
if ([super performKeyEquivalent:event])
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end // AtomEventProcessingWindow
|
||||
22
browser/atom_javascript_dialog_manager.cc
Normal file
22
browser/atom_javascript_dialog_manager.cc
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "browser/atom_javascript_dialog_manager.h"
|
||||
|
||||
#include "base/utf_string_conversions.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
void AtomJavaScriptDialogManager::RunBeforeUnloadDialog(
|
||||
content::WebContents* web_contents,
|
||||
const string16& message_text,
|
||||
bool is_reload,
|
||||
const DialogClosedCallback& callback) {
|
||||
|
||||
bool prevent_reload = message_text.empty() ||
|
||||
message_text == ASCIIToUTF16("false");
|
||||
callback.Run(!prevent_reload, message_text);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
35
browser/atom_javascript_dialog_manager.h
Normal file
35
browser/atom_javascript_dialog_manager.h
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROSER_ATOM_JAVASCRIPT_DIALOG_MANAGER_H_
|
||||
#define ATOM_BROSER_ATOM_JAVASCRIPT_DIALOG_MANAGER_H_
|
||||
|
||||
#include "content/public/browser/javascript_dialog_manager.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomJavaScriptDialogManager : public content::JavaScriptDialogManager {
|
||||
public:
|
||||
// content::JavaScriptDialogManager implementations.
|
||||
virtual void RunJavaScriptDialog(
|
||||
content::WebContents* web_contents,
|
||||
const GURL& origin_url,
|
||||
const std::string& accept_lang,
|
||||
content::JavaScriptMessageType javascript_message_type,
|
||||
const string16& message_text,
|
||||
const string16& default_prompt_text,
|
||||
const DialogClosedCallback& callback,
|
||||
bool* did_suppress_message) OVERRIDE {}
|
||||
virtual void RunBeforeUnloadDialog(
|
||||
content::WebContents* web_contents,
|
||||
const string16& message_text,
|
||||
bool is_reload,
|
||||
const DialogClosedCallback& callback) OVERRIDE;
|
||||
virtual void ResetJavaScriptState(
|
||||
content::WebContents* web_contents) OVERRIDE {}
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROSER_ATOM_JAVASCRIPT_DIALOG_MANAGER_H_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user