mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
129 Commits
v12.0.10
...
v13.0.0-ni
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1078590bbd | ||
|
|
8383c14aba | ||
|
|
729c45637d | ||
|
|
3a970825b2 | ||
|
|
bf24759354 | ||
|
|
8f1bc338e5 | ||
|
|
cdc94e4cef | ||
|
|
f99ea7c0ba | ||
|
|
a55e028b12 | ||
|
|
da3d21e5e3 | ||
|
|
8cbcb04e84 | ||
|
|
6a3679dc55 | ||
|
|
8f9058ea72 | ||
|
|
75247d18d0 | ||
|
|
9377b04e0b | ||
|
|
e250a2d804 | ||
|
|
420eaaa294 | ||
|
|
998f17ee59 | ||
|
|
9eab298779 | ||
|
|
e01b1831d9 | ||
|
|
1e2a2004e9 | ||
|
|
6932e17088 | ||
|
|
6ccebdf712 | ||
|
|
b266b5208a | ||
|
|
21024011d7 | ||
|
|
833baa4c54 | ||
|
|
ef49fea5eb | ||
|
|
9b02d94e97 | ||
|
|
b73b343e29 | ||
|
|
4588a41161 | ||
|
|
c8eb4ecc0c | ||
|
|
2f9281519c | ||
|
|
44ca6e0818 | ||
|
|
28ae68d66c | ||
|
|
b4c1e54ed3 | ||
|
|
cc09da6233 | ||
|
|
a8e9140c26 | ||
|
|
b9c9e7fc06 | ||
|
|
51db2a6b34 | ||
|
|
e641a747fb | ||
|
|
f876154fd3 | ||
|
|
cec6378881 | ||
|
|
9908cc363a | ||
|
|
bc6fed5eda | ||
|
|
07a1c2a3e5 | ||
|
|
76f721474e | ||
|
|
1a79bedb27 | ||
|
|
edfbeb92bf | ||
|
|
6d0a0319e1 | ||
|
|
19ff18ac40 | ||
|
|
c41b8d536b | ||
|
|
7677576da8 | ||
|
|
1abd36f6c8 | ||
|
|
788e51127f | ||
|
|
ee0550efca | ||
|
|
b788ceb7bd | ||
|
|
e87061398b | ||
|
|
c9b813a1f9 | ||
|
|
3bc220db29 | ||
|
|
6001f03e46 | ||
|
|
771e34a53a | ||
|
|
3db4e612f4 | ||
|
|
03b43e4d8c | ||
|
|
e89b3ca1d1 | ||
|
|
d3b1566181 | ||
|
|
5a5d964720 | ||
|
|
228a184b48 | ||
|
|
7672aa9525 | ||
|
|
b111bba387 | ||
|
|
b133b6fd45 | ||
|
|
45eee46864 | ||
|
|
5521f8acca | ||
|
|
b37982987a | ||
|
|
8eee9d1290 | ||
|
|
6fc5ff77c1 | ||
|
|
cffb51e141 | ||
|
|
e96fa95b94 | ||
|
|
efca7007b6 | ||
|
|
c2909a3b8d | ||
|
|
430189fa84 | ||
|
|
94381cda49 | ||
|
|
528b0f0e74 | ||
|
|
cdcee04bbe | ||
|
|
6c5f7a6e86 | ||
|
|
32d4c9ad85 | ||
|
|
acfbbe9869 | ||
|
|
4e3e3d414d | ||
|
|
61f339d3aa | ||
|
|
cf970f31a3 | ||
|
|
9c26be7b43 | ||
|
|
19954126e0 | ||
|
|
7d49ce898a | ||
|
|
09d7b2bc91 | ||
|
|
59b4d5c156 | ||
|
|
36af8022ca | ||
|
|
14c8e000cb | ||
|
|
c8c41fb727 | ||
|
|
fadd513739 | ||
|
|
770e245de5 | ||
|
|
7cc571801c | ||
|
|
8311ea1a36 | ||
|
|
022bafc485 | ||
|
|
d0cf16263e | ||
|
|
ba629e3127 | ||
|
|
662077f153 | ||
|
|
d56861eaa5 | ||
|
|
38ab829ea6 | ||
|
|
87e20f2b97 | ||
|
|
6761814f14 | ||
|
|
c8d77cae4a | ||
|
|
0be6c92aa9 | ||
|
|
956892dd5b | ||
|
|
a5c612cd96 | ||
|
|
9d54fdfd12 | ||
|
|
b894151745 | ||
|
|
e455a79218 | ||
|
|
b1b25607ee | ||
|
|
6932e02eb8 | ||
|
|
854d2b1574 | ||
|
|
329494cfeb | ||
|
|
abb1504ecc | ||
|
|
b57ae67da6 | ||
|
|
2e239ea563 | ||
|
|
7c099210b4 | ||
|
|
46972abf8b | ||
|
|
b4196ca486 | ||
|
|
06158b3e94 | ||
|
|
18f004eab1 | ||
|
|
03a70896c7 |
@@ -295,10 +295,10 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
run:
|
||||
name: Setup Goma
|
||||
command: |
|
||||
if [ "`uname`" == "Linux" ]; then
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
||||
else
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=25' >> $BASH_ENV
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
echo 'ulimit -n 10000' >> $BASH_ENV
|
||||
echo 'sudo launchctl limit maxfiles 65536 200000' >> $BASH_ENV
|
||||
fi
|
||||
if [ ! -z "$RAW_GOMA_AUTH" ]; then
|
||||
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
|
||||
@@ -307,7 +307,7 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
cd build-tools
|
||||
npm install
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
node -e "require('./src/utils/goma.js').ensure()"
|
||||
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
|
||||
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
|
||||
@@ -445,9 +445,6 @@ step-fix-sync-on-mac: &step-fix-sync-on-mac
|
||||
# Fix Clang Install (wrong binary)
|
||||
rm -rf src/third_party/llvm-build
|
||||
python src/tools/clang/scripts/update.py
|
||||
# Fix Framework Header Installs (symlinks not retained)
|
||||
rm -rf src/electron/external_binaries
|
||||
python src/electron/script/update-external-binaries.py
|
||||
fi
|
||||
|
||||
step-install-signing-cert-on-mac: &step-install-signing-cert-on-mac
|
||||
@@ -483,7 +480,6 @@ step-gn-check: &step-gn-check
|
||||
cd src
|
||||
gn check out/Default //electron:electron_lib
|
||||
gn check out/Default //electron:electron_app
|
||||
gn check out/Default //electron:manifests
|
||||
gn check out/Default //electron/shell/common/api:mojo
|
||||
# Check the hunspell filenames
|
||||
node electron/script/gen-hunspell-filenames.js --check
|
||||
@@ -893,6 +889,8 @@ step-ninja-summary: &step-ninja-summary
|
||||
run:
|
||||
name: Print ninja summary
|
||||
command: |
|
||||
set +e
|
||||
set +o pipefail
|
||||
python depot_tools/post_build_ninja_summary.py -C src/out/Default
|
||||
|
||||
step-ninja-report: &step-ninja-report
|
||||
@@ -1421,9 +1419,6 @@ commands:
|
||||
restore-src-cache:
|
||||
type: boolean
|
||||
default: true
|
||||
preserve-vendor-dirs:
|
||||
type: boolean
|
||||
default: false
|
||||
steps:
|
||||
- when:
|
||||
condition: << parameters.attach >>
|
||||
@@ -1461,26 +1456,11 @@ commands:
|
||||
- store_artifacts:
|
||||
path: patches
|
||||
# These next few steps reset Electron to the correct commit regardless of which cache was restored
|
||||
- when:
|
||||
condition: << parameters.preserve-vendor-dirs >>
|
||||
steps:
|
||||
- run:
|
||||
name: Preserve vendor dirs for release
|
||||
command: |
|
||||
mv src/electron/vendor/requests .
|
||||
- run:
|
||||
name: Wipe Electron
|
||||
command: rm -rf src/electron
|
||||
- *step-checkout-electron
|
||||
- *step-run-electron-only-hooks
|
||||
- when:
|
||||
condition: << parameters.preserve-vendor-dirs >>
|
||||
steps:
|
||||
- run:
|
||||
name: Preserve vendor dirs for release
|
||||
command: |
|
||||
rm -rf src/electron/vendor/requests
|
||||
mv requests src/electron/vendor/requests
|
||||
- *step-generate-deps-hash-cleanly
|
||||
- *step-mark-sync-done
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
@@ -1676,7 +1656,7 @@ jobs:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True --custom-var=checkout_requests=True'
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: false
|
||||
@@ -1684,7 +1664,6 @@ jobs:
|
||||
checkout: true
|
||||
persist-checkout: true
|
||||
restore-src-cache: false
|
||||
preserve-vendor-dirs: true
|
||||
|
||||
linux-checkout-fast:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1735,7 +1714,7 @@ jobs:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-testing-build
|
||||
<<: *env-macos-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac --custom-var=checkout_requests=True'
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: false
|
||||
@@ -1743,7 +1722,6 @@ jobs:
|
||||
checkout: true
|
||||
persist-checkout: true
|
||||
restore-src-cache: false
|
||||
preserve-vendor-dirs: true
|
||||
|
||||
mac-checkout-fast:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -1820,7 +1798,6 @@ jobs:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
|
||||
<<: *env-release-build
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
@@ -1873,7 +1850,6 @@ jobs:
|
||||
<<: *machine-linux-2xlarge
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
|
||||
<<: *env-ia32
|
||||
<<: *env-release-build
|
||||
<<: *env-32bit-release
|
||||
@@ -1934,7 +1910,7 @@ jobs:
|
||||
<<: *env-arm
|
||||
<<: *env-release-build
|
||||
<<: *env-32bit-release
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_requests=True'
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
@@ -1999,7 +1975,7 @@ jobs:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm64
|
||||
<<: *env-release-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_requests=True'
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
@@ -2061,7 +2037,6 @@ jobs:
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-release-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
@@ -2075,7 +2050,6 @@ jobs:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-release-build
|
||||
<<: *env-apple-silicon
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
@@ -2169,7 +2143,6 @@ jobs:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-mas
|
||||
<<: *env-release-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
@@ -2183,7 +2156,6 @@ jobs:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-mas-apple-silicon
|
||||
<<: *env-release-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
<<: *env-ninja-status
|
||||
steps:
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
*
|
||||
!tools/xvfb-init.sh
|
||||
!build/install-build-deps.sh
|
||||
|
||||
1
.github/config.yml
vendored
1
.github/config.yml
vendored
@@ -36,5 +36,6 @@ authorizedUsers:
|
||||
- loc
|
||||
- MarshallOfSound
|
||||
- miniak
|
||||
- mlaurencin
|
||||
- nornagon
|
||||
- zcbenz
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -55,7 +55,7 @@ electron.d.ts
|
||||
spec/.hash
|
||||
|
||||
# Eslint Cache
|
||||
.eslintcache
|
||||
.eslintcache*
|
||||
|
||||
# Generated native addon files
|
||||
/spec-main/fixtures/native-addon/echo/build/
|
||||
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,6 +0,0 @@
|
||||
[submodule "vendor/requests"]
|
||||
path = vendor/requests
|
||||
url = https://github.com/kennethreitz/requests
|
||||
[submodule "vendor/boto"]
|
||||
path = vendor/boto
|
||||
url = https://github.com/boto/boto.git
|
||||
18
BUILD.gn
18
BUILD.gn
@@ -265,21 +265,6 @@ if (is_linux) {
|
||||
}
|
||||
}
|
||||
|
||||
source_set("manifests") {
|
||||
sources = [
|
||||
"//electron/shell/app/manifests.cc",
|
||||
"//electron/shell/app/manifests.h",
|
||||
]
|
||||
|
||||
include_dirs = [ "//electron" ]
|
||||
|
||||
deps = [
|
||||
"//electron/shell/common/api:mojo",
|
||||
"//printing/buildflags",
|
||||
"//services/service_manager/public/cpp",
|
||||
]
|
||||
}
|
||||
|
||||
npm_action("electron_version_args") {
|
||||
script = "generate-version-json"
|
||||
|
||||
@@ -328,7 +313,6 @@ source_set("electron_lib") {
|
||||
":electron_fuses",
|
||||
":electron_js2c",
|
||||
":electron_version_header",
|
||||
":manifests",
|
||||
":resources",
|
||||
"buildflags",
|
||||
"chromium_src:chrome",
|
||||
@@ -353,7 +337,6 @@ source_set("electron_lib") {
|
||||
"//components/viz/service",
|
||||
"//content/public/browser",
|
||||
"//content/public/child",
|
||||
"//content/public/common:service_names",
|
||||
"//content/public/gpu",
|
||||
"//content/public/renderer",
|
||||
"//content/public/utility",
|
||||
@@ -508,6 +491,7 @@ source_set("electron_lib") {
|
||||
}
|
||||
}
|
||||
if (is_linux) {
|
||||
libs = [ "xshmfence" ]
|
||||
deps += [
|
||||
":libnotify_loader",
|
||||
"//build/config/linux/gtk",
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
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.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
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ _If an issue has been closed and you still feel it's relevant, feel free to ping
|
||||
### 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.
|
||||
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.
|
||||
@@ -66,5 +66,5 @@ See [Coding Style](https://electronjs.org/docs/development/coding-style) for inf
|
||||
|
||||
## Further Reading
|
||||
|
||||
For more in-depth guides on developing Electron, see
|
||||
For more in-depth guides on developing Electron, see
|
||||
[/docs/development](/docs/development/README.md)
|
||||
|
||||
40
DEPS
40
DEPS
@@ -14,21 +14,19 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'3a75ada69d1ac06d6903a2c981ab90a8162f1ba0',
|
||||
'b13e791d7244a08d9d61dbfa2bb2b6cdf1ff6294',
|
||||
'node_version':
|
||||
'v14.15.1',
|
||||
'v14.15.2',
|
||||
'nan_version':
|
||||
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
|
||||
'squirrel.mac_version':
|
||||
'a3a5b3f03b824441c014893b18f99a103b2603e9',
|
||||
'cdc0729c8bf8576bfef18629186e1e9ecf1b0d9f',
|
||||
|
||||
'pyyaml_version': '3.12',
|
||||
'requests_version': 'e4d59bedfd3c7f4f254f4f5d036587bcd8152458',
|
||||
|
||||
'chromium_git': 'https://chromium.googlesource.com',
|
||||
'electron_git': 'https://github.com/electron',
|
||||
'nodejs_git': 'https://github.com/nodejs',
|
||||
'requests_git': 'https://github.com/kennethreitz',
|
||||
'yaml_git': 'https://github.com/yaml',
|
||||
'squirrel_git': 'https://github.com/Squirrel',
|
||||
|
||||
@@ -50,18 +48,11 @@ vars = {
|
||||
# It's only needed to parse the native tests configurations.
|
||||
'checkout_pyyaml': False,
|
||||
|
||||
# Python "requests" module is used for releases only.
|
||||
'checkout_requests': False,
|
||||
|
||||
'mac_xcode_version': 'default',
|
||||
|
||||
# To allow running hooks without parsing the DEPS tree
|
||||
'process_deps': True,
|
||||
|
||||
# It is always needed for normal Electron builds,
|
||||
# but might be impossible for custom in-house builds.
|
||||
'download_external_binaries': True,
|
||||
|
||||
'checkout_nacl':
|
||||
False,
|
||||
'checkout_libaom':
|
||||
@@ -99,10 +90,6 @@ deps = {
|
||||
'url': (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
|
||||
'condition': 'checkout_pyyaml and process_deps',
|
||||
},
|
||||
'src/electron/vendor/requests': {
|
||||
'url': Var('requests_git') + '/requests.git' + '@' + Var('requests_version'),
|
||||
'condition': 'checkout_requests and process_deps',
|
||||
},
|
||||
'src/third_party/squirrel.mac': {
|
||||
'url': Var("squirrel_git") + '/Squirrel.Mac.git@' + Var("squirrel.mac_version"),
|
||||
'condition': 'process_deps',
|
||||
@@ -157,32 +144,13 @@ hooks = [
|
||||
'src/electron/patches/mtime-cache.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'electron_external_binaries',
|
||||
'pattern': 'src/electron/script/update-external-binaries.py',
|
||||
'condition': 'download_external_binaries',
|
||||
'action': [
|
||||
'python3',
|
||||
'src/electron/script/update-external-binaries.py',
|
||||
],
|
||||
},
|
||||
{
|
||||
'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(["python", "script/lib/npx.py", "yarn@' + (Var("yarn_version")) + '", "install", "--frozen-lockfile"]);',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'setup_requests',
|
||||
'pattern': 'src/electron',
|
||||
'condition': 'checkout_requests and process_deps',
|
||||
'action': [
|
||||
'python3',
|
||||
'-c',
|
||||
'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "requests")); subprocess.check_call(["python", "setup.py", "build"]);',
|
||||
'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"]);',
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1 +1 @@
|
||||
12.0.0-nightly.20201118
|
||||
13.0.0-nightly.20201223
|
||||
@@ -1,6 +1,5 @@
|
||||
[](https://electronjs.org)
|
||||
|
||||
|
||||
[](https://circleci.com/gh/electron/electron/tree/master)
|
||||
[](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/master)
|
||||
[](https://david-dm.org/electron/electron?type=dev)
|
||||
|
||||
@@ -13,4 +13,5 @@ Report security bugs in third-party modules to the person or team maintaining th
|
||||
For context on Electron's security notification process, please see the [Notifications](https://github.com/electron/governance/blob/master/wg-security/membership-and-notifications.md#notifications) section of the Security WG's [Membership and Notifications](https://github.com/electron/governance/blob/master/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).
|
||||
|
||||
10
appveyor.yml
10
appveyor.yml
@@ -67,9 +67,7 @@ build_script:
|
||||
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
$env:GCLIENT_EXTRA_ARGS="$env:GCLIENT_EXTRA_ARGS --custom-var=checkout_requests=True"
|
||||
} else {
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
|
||||
}
|
||||
- >-
|
||||
@@ -98,8 +96,6 @@ build_script:
|
||||
$env:SAVE_GCLIENT_SRC="true"
|
||||
}
|
||||
} else {
|
||||
# update external binaries
|
||||
python src/electron/script/update-external-binaries.py
|
||||
# update angle
|
||||
cd src\third_party\angle
|
||||
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
|
||||
@@ -141,7 +137,8 @@ build_script:
|
||||
- cd build-tools
|
||||
- npm install
|
||||
- mkdir third_party
|
||||
- node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
||||
- 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 ..
|
||||
@@ -151,7 +148,6 @@ build_script:
|
||||
- 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:manifests
|
||||
- gn check out/Default //electron/shell/common/api:mojo
|
||||
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
|
||||
@@ -2,7 +2,7 @@ is_electron_build = true
|
||||
root_extra_deps = [ "//electron" ]
|
||||
|
||||
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
|
||||
node_module_version = 87
|
||||
node_module_version = 89
|
||||
|
||||
v8_promise_internal_field_count = 1
|
||||
v8_typed_array_max_size_in_heap = 0
|
||||
|
||||
@@ -1,653 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
# Script to install everything needed to build chromium (well, ideally, anyway)
|
||||
# See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_build_instructions.md
|
||||
usage() {
|
||||
echo "Usage: $0 [--options]"
|
||||
echo "Options:"
|
||||
echo "--[no-]syms: enable or disable installation of debugging symbols"
|
||||
echo "--lib32: enable installation of 32-bit libraries, e.g. for V8 snapshot"
|
||||
echo "--[no-]arm: enable or disable installation of arm cross toolchain"
|
||||
echo "--[no-]chromeos-fonts: enable or disable installation of Chrome OS"\
|
||||
"fonts"
|
||||
echo "--[no-]nacl: enable or disable installation of prerequisites for"\
|
||||
"building standalone NaCl and all its toolchains"
|
||||
echo "--[no-]backwards-compatible: enable or disable installation of packages
|
||||
that are no longer currently needed and have been removed from this
|
||||
script. Useful for bisection."
|
||||
echo "--no-prompt: silently select standard options/defaults"
|
||||
echo "--quick-check: quickly try to determine if dependencies are installed"
|
||||
echo " (this avoids interactive prompts and sudo commands,"
|
||||
echo " so might not be 100% accurate)"
|
||||
echo "--unsupported: attempt installation even on unsupported systems"
|
||||
echo "Script will prompt interactively if options not given."
|
||||
exit 1
|
||||
}
|
||||
# Checks whether a particular package is available in the repos.
|
||||
# USAGE: $ package_exists <package name>
|
||||
package_exists() {
|
||||
# 'apt-cache search' takes a regex string, so eg. the +'s in packages like
|
||||
# "libstdc++" need to be escaped.
|
||||
local escaped="$(echo $1 | sed 's/[\~\+\.\:-]/\\&/g')"
|
||||
[ ! -z "$(apt-cache search --names-only "${escaped}" | \
|
||||
awk '$1 == "'$1'" { print $1; }')" ]
|
||||
}
|
||||
# These default to on because (some) bots need them and it keeps things
|
||||
# simple for the bot setup if all bots just run the script in its default
|
||||
# mode. Developers who don't want stuff they don't need installed on their
|
||||
# own workstations can pass --no-arm --no-nacl when running the script.
|
||||
do_inst_arm=1
|
||||
do_inst_nacl=1
|
||||
while [ "$1" != "" ]
|
||||
do
|
||||
case "$1" in
|
||||
--syms) do_inst_syms=1;;
|
||||
--no-syms) do_inst_syms=0;;
|
||||
--lib32) do_inst_lib32=1;;
|
||||
--arm) do_inst_arm=1;;
|
||||
--no-arm) do_inst_arm=0;;
|
||||
--chromeos-fonts) do_inst_chromeos_fonts=1;;
|
||||
--no-chromeos-fonts) do_inst_chromeos_fonts=0;;
|
||||
--nacl) do_inst_nacl=1;;
|
||||
--no-nacl) do_inst_nacl=0;;
|
||||
--backwards-compatible) do_inst_backwards_compatible=1;;
|
||||
--no-backwards-compatible) do_inst_backwards_compatible=0;;
|
||||
--add-cross-tool-repo) add_cross_tool_repo=1;;
|
||||
--no-prompt) do_default=1
|
||||
do_quietly="-qq --assume-yes"
|
||||
;;
|
||||
--quick-check) do_quick_check=1;;
|
||||
--unsupported) do_unsupported=1;;
|
||||
*) usage;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
if [ "$do_inst_arm" = "1" ]; then
|
||||
do_inst_lib32=1
|
||||
fi
|
||||
# Check for lsb_release command in $PATH
|
||||
if ! which lsb_release > /dev/null; then
|
||||
echo "ERROR: lsb_release not found in \$PATH" >&2
|
||||
exit 1;
|
||||
fi
|
||||
distro_codename=$(lsb_release --codename --short)
|
||||
distro_id=$(lsb_release --id --short)
|
||||
supported_codenames="(trusty|xenial|artful|bionic)"
|
||||
supported_ids="(Debian)"
|
||||
if [ 0 -eq "${do_unsupported-0}" ] && [ 0 -eq "${do_quick_check-0}" ] ; then
|
||||
if [[ ! $distro_codename =~ $supported_codenames &&
|
||||
! $distro_id =~ $supported_ids ]]; then
|
||||
echo -e "ERROR: The only supported distros are\n" \
|
||||
"\tUbuntu 14.04 LTS (trusty)\n" \
|
||||
"\tUbuntu 16.04 LTS (xenial)\n" \
|
||||
"\tUbuntu 17.10 (artful)\n" \
|
||||
"\tUbuntu 18.04 LTS (bionic)\n" \
|
||||
"\tDebian 8 (jessie) or later" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! uname -m | egrep -q "i686|x86_64"; then
|
||||
echo "Only x86 architectures are currently supported" >&2
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
if [ "x$(id -u)" != x0 ] && [ 0 -eq "${do_quick_check-0}" ]; then
|
||||
echo "Running as non-root user."
|
||||
echo "You might have to enter your password one or more times for 'sudo'."
|
||||
echo
|
||||
fi
|
||||
# Packages needed for chromeos only
|
||||
chromeos_dev_list="libbluetooth-dev libxkbcommon-dev"
|
||||
if package_exists realpath; then
|
||||
chromeos_dev_list="${chromeos_dev_list} realpath"
|
||||
fi
|
||||
# Packages needed for development
|
||||
dev_list="\
|
||||
binutils
|
||||
bison
|
||||
bzip2
|
||||
cdbs
|
||||
curl
|
||||
dbus-x11
|
||||
dpkg-dev
|
||||
elfutils
|
||||
devscripts
|
||||
fakeroot
|
||||
flex
|
||||
g++
|
||||
git-core
|
||||
git-svn
|
||||
gperf
|
||||
libappindicator3-dev
|
||||
libasound2-dev
|
||||
libatspi2.0-dev
|
||||
libbrlapi-dev
|
||||
libbz2-dev
|
||||
libcairo2-dev
|
||||
libcap-dev
|
||||
libcups2-dev
|
||||
libcurl4-gnutls-dev
|
||||
libdrm-dev
|
||||
libelf-dev
|
||||
libffi-dev
|
||||
libgbm-dev
|
||||
libglib2.0-dev
|
||||
libglu1-mesa-dev
|
||||
libgnome-keyring-dev
|
||||
libgtk-3-dev
|
||||
libkrb5-dev
|
||||
libnspr4-dev
|
||||
libnss3-dev
|
||||
libpam0g-dev
|
||||
libpci-dev
|
||||
libpulse-dev
|
||||
libsctp-dev
|
||||
libspeechd-dev
|
||||
libsqlite3-dev
|
||||
libssl-dev
|
||||
libudev-dev
|
||||
libwww-perl
|
||||
libxslt1-dev
|
||||
libxss-dev
|
||||
libxt-dev
|
||||
libxtst-dev
|
||||
locales
|
||||
openbox
|
||||
p7zip
|
||||
patch
|
||||
perl
|
||||
pkg-config
|
||||
python
|
||||
python-cherrypy3
|
||||
python-crypto
|
||||
python-dev
|
||||
python-numpy
|
||||
python-opencv
|
||||
python-openssl
|
||||
python-psutil
|
||||
python-yaml
|
||||
rpm
|
||||
ruby
|
||||
subversion
|
||||
uuid-dev
|
||||
wdiff
|
||||
x11-utils
|
||||
xcompmgr
|
||||
xz-utils
|
||||
zip
|
||||
$chromeos_dev_list
|
||||
"
|
||||
# 64-bit systems need a minimum set of 32-bit compat packages for the pre-built
|
||||
# NaCl binaries.
|
||||
if file -L /sbin/init | grep -q 'ELF 64-bit'; then
|
||||
dev_list="${dev_list} libc6-i386 lib32gcc1 lib32stdc++6"
|
||||
fi
|
||||
# Run-time libraries required by chromeos only
|
||||
chromeos_lib_list="libpulse0 libbz2-1.0"
|
||||
# List of required run-time libraries
|
||||
common_lib_list="\
|
||||
libappindicator3-1
|
||||
libasound2
|
||||
libatk1.0-0
|
||||
libatspi2.0-0
|
||||
libc6
|
||||
libcairo2
|
||||
libcap2
|
||||
libcups2
|
||||
libexpat1
|
||||
libffi6
|
||||
libfontconfig1
|
||||
libfreetype6
|
||||
libglib2.0-0
|
||||
libgnome-keyring0
|
||||
libgtk-3-0
|
||||
libpam0g
|
||||
libpango1.0-0
|
||||
libpci3
|
||||
libpcre3
|
||||
libpixman-1-0
|
||||
libspeechd2
|
||||
libstdc++6
|
||||
libsqlite3-0
|
||||
libuuid1
|
||||
libwayland-egl1-mesa
|
||||
libx11-6
|
||||
libx11-xcb1
|
||||
libxau6
|
||||
libxcb1
|
||||
libxcomposite1
|
||||
libxcursor1
|
||||
libxdamage1
|
||||
libxdmcp6
|
||||
libxext6
|
||||
libxfixes3
|
||||
libxi6
|
||||
libxinerama1
|
||||
libxrandr2
|
||||
libxrender1
|
||||
libxtst6
|
||||
zlib1g
|
||||
"
|
||||
# Full list of required run-time libraries
|
||||
lib_list="\
|
||||
$common_lib_list
|
||||
$chromeos_lib_list
|
||||
"
|
||||
# 32-bit libraries needed e.g. to compile V8 snapshot for Android or armhf
|
||||
lib32_list="linux-libc-dev:i386 libpci3:i386"
|
||||
# 32-bit libraries needed for a 32-bit build
|
||||
lib32_list="$lib32_list libx11-xcb1:i386"
|
||||
# Packages that have been removed from this script. Regardless of configuration
|
||||
# or options passed to this script, whenever a package is removed, it should be
|
||||
# added here.
|
||||
backwards_compatible_list="\
|
||||
7za
|
||||
fonts-indic
|
||||
fonts-ipafont
|
||||
fonts-stix
|
||||
fonts-thai-tlwg
|
||||
fonts-tlwg-garuda
|
||||
language-pack-da
|
||||
language-pack-fr
|
||||
language-pack-he
|
||||
language-pack-zh-hant
|
||||
libappindicator-dev
|
||||
libappindicator1
|
||||
libappindicator3-1:i386
|
||||
libexif-dev
|
||||
libexif12
|
||||
libexif12:i386
|
||||
libgbm-dev
|
||||
libgl1-mesa-dev
|
||||
libgl1-mesa-glx:i386
|
||||
libgles2-mesa-dev
|
||||
libgtk2.0-0
|
||||
libgtk2.0-0:i386
|
||||
libgtk2.0-dev
|
||||
mesa-common-dev
|
||||
msttcorefonts
|
||||
ttf-dejavu-core
|
||||
ttf-indic-fonts
|
||||
ttf-kochi-gothic
|
||||
ttf-kochi-mincho
|
||||
ttf-mscorefonts-installer
|
||||
xfonts-mathml
|
||||
"
|
||||
case $distro_codename in
|
||||
trusty)
|
||||
backwards_compatible_list+=" \
|
||||
libgbm-dev-lts-trusty
|
||||
libgl1-mesa-dev-lts-trusty
|
||||
libgl1-mesa-glx-lts-trusty:i386
|
||||
libgles2-mesa-dev-lts-trusty
|
||||
mesa-common-dev-lts-trusty"
|
||||
;;
|
||||
xenial)
|
||||
backwards_compatible_list+=" \
|
||||
libgbm-dev-lts-xenial
|
||||
libgl1-mesa-dev-lts-xenial
|
||||
libgl1-mesa-glx-lts-xenial:i386
|
||||
libgles2-mesa-dev-lts-xenial
|
||||
mesa-common-dev-lts-xenial"
|
||||
;;
|
||||
esac
|
||||
# arm cross toolchain packages needed to build chrome on armhf
|
||||
EM_REPO="deb http://emdebian.org/tools/debian/ jessie main"
|
||||
EM_SOURCE=$(cat <<EOF
|
||||
# Repo added by Chromium $0
|
||||
${EM_REPO}
|
||||
# deb-src http://emdebian.org/tools/debian/ jessie main
|
||||
EOF
|
||||
)
|
||||
EM_ARCHIVE_KEY_FINGER="084C6C6F39159EDB67969AA87DE089671804772E"
|
||||
GPP_ARM_PACKAGE="g++-arm-linux-gnueabihf"
|
||||
case $distro_codename in
|
||||
jessie)
|
||||
eval $(apt-config shell APT_SOURCESDIR 'Dir::Etc::sourceparts/d')
|
||||
CROSSTOOLS_LIST="${APT_SOURCESDIR}/crosstools.list"
|
||||
arm_list="libc6-dev:armhf
|
||||
linux-libc-dev:armhf"
|
||||
if [ "$do_inst_arm" = "1" ]; then
|
||||
if $(dpkg-query -W ${GPP_ARM_PACKAGE} &>/dev/null); then
|
||||
arm_list+=" ${GPP_ARM_PACKAGE}"
|
||||
else
|
||||
if [ "${add_cross_tool_repo}" = "1" ]; then
|
||||
gpg --keyserver pgp.mit.edu --recv-keys ${EM_ARCHIVE_KEY_FINGER}
|
||||
gpg -a --export ${EM_ARCHIVE_KEY_FINGER} | sudo apt-key add -
|
||||
if ! grep "^${EM_REPO}" "${CROSSTOOLS_LIST}" &>/dev/null; then
|
||||
echo "${EM_SOURCE}" | sudo tee -a "${CROSSTOOLS_LIST}" >/dev/null
|
||||
fi
|
||||
arm_list+=" ${GPP_ARM_PACKAGE}"
|
||||
else
|
||||
echo "The Debian Cross-toolchains repository is necessary to"
|
||||
echo "cross-compile Chromium for arm."
|
||||
echo "Rerun with --add-deb-cross-tool-repo to have it added for you."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
# All necessary ARM packages are available on the default repos on
|
||||
# Debian 9 and later.
|
||||
*)
|
||||
arm_list="libc6-dev-armhf-cross
|
||||
linux-libc-dev-armhf-cross
|
||||
${GPP_ARM_PACKAGE}"
|
||||
;;
|
||||
esac
|
||||
# Work around for dependency issue Ubuntu/Trusty: http://crbug.com/435056
|
||||
case $distro_codename in
|
||||
trusty)
|
||||
arm_list+=" g++-4.8-multilib-arm-linux-gnueabihf
|
||||
gcc-4.8-multilib-arm-linux-gnueabihf"
|
||||
;;
|
||||
xenial|artful|bionic)
|
||||
arm_list+=" g++-5-multilib-arm-linux-gnueabihf
|
||||
gcc-5-multilib-arm-linux-gnueabihf
|
||||
gcc-arm-linux-gnueabihf"
|
||||
;;
|
||||
esac
|
||||
# Packages to build NaCl, its toolchains, and its ports.
|
||||
naclports_list="ant autoconf bison cmake gawk intltool xutils-dev xsltproc"
|
||||
nacl_list="\
|
||||
g++-mingw-w64-i686
|
||||
lib32z1-dev
|
||||
libasound2:i386
|
||||
libcap2:i386
|
||||
libelf-dev:i386
|
||||
libfontconfig1:i386
|
||||
libglib2.0-0:i386
|
||||
libgpm2:i386
|
||||
libgtk-3-0:i386
|
||||
libncurses5:i386
|
||||
lib32ncurses5-dev
|
||||
libnss3:i386
|
||||
libpango1.0-0:i386
|
||||
libssl-dev:i386
|
||||
libtinfo-dev
|
||||
libtinfo-dev:i386
|
||||
libtool
|
||||
libuuid1:i386
|
||||
libxcomposite1:i386
|
||||
libxcursor1:i386
|
||||
libxdamage1:i386
|
||||
libxi6:i386
|
||||
libxrandr2:i386
|
||||
libxss1:i386
|
||||
libxtst6:i386
|
||||
texinfo
|
||||
xvfb
|
||||
${naclports_list}
|
||||
"
|
||||
if package_exists libssl1.1; then
|
||||
nacl_list="${nacl_list} libssl1.1:i386"
|
||||
elif package_exists libssl1.0.2; then
|
||||
nacl_list="${nacl_list} libssl1.0.2:i386"
|
||||
else
|
||||
nacl_list="${nacl_list} libssl1.0.0:i386"
|
||||
fi
|
||||
# Some package names have changed over time
|
||||
if package_exists libpng16-16; then
|
||||
lib_list="${lib_list} libpng16-16"
|
||||
else
|
||||
lib_list="${lib_list} libpng12-0"
|
||||
fi
|
||||
if package_exists libnspr4; then
|
||||
lib_list="${lib_list} libnspr4 libnss3"
|
||||
else
|
||||
lib_list="${lib_list} libnspr4-0d libnss3-1d"
|
||||
fi
|
||||
if package_exists libjpeg-dev; then
|
||||
dev_list="${dev_list} libjpeg-dev"
|
||||
else
|
||||
dev_list="${dev_list} libjpeg62-dev"
|
||||
fi
|
||||
if package_exists libudev1; then
|
||||
dev_list="${dev_list} libudev1"
|
||||
nacl_list="${nacl_list} libudev1:i386"
|
||||
else
|
||||
dev_list="${dev_list} libudev0"
|
||||
nacl_list="${nacl_list} libudev0:i386"
|
||||
fi
|
||||
if package_exists libbrlapi0.6; then
|
||||
dev_list="${dev_list} libbrlapi0.6"
|
||||
else
|
||||
dev_list="${dev_list} libbrlapi0.5"
|
||||
fi
|
||||
if package_exists apache2.2-bin; then
|
||||
dev_list="${dev_list} apache2.2-bin"
|
||||
else
|
||||
dev_list="${dev_list} apache2-bin"
|
||||
fi
|
||||
if package_exists libav-tools; then
|
||||
dev_list="${dev_list} libav-tools"
|
||||
fi
|
||||
if package_exists php7.2-cgi; then
|
||||
dev_list="${dev_list} php7.2-cgi libapache2-mod-php7.2"
|
||||
elif package_exists php7.1-cgi; then
|
||||
dev_list="${dev_list} php7.1-cgi libapache2-mod-php7.1"
|
||||
elif package_exists php7.0-cgi; then
|
||||
dev_list="${dev_list} php7.0-cgi libapache2-mod-php7.0"
|
||||
else
|
||||
dev_list="${dev_list} php5-cgi libapache2-mod-php5"
|
||||
fi
|
||||
# Some packages are only needed if the distribution actually supports
|
||||
# installing them.
|
||||
if package_exists appmenu-gtk; then
|
||||
lib_list="$lib_list appmenu-gtk"
|
||||
fi
|
||||
# Cross-toolchain strip is needed for building the sysroots.
|
||||
if package_exists binutils-arm-linux-gnueabihf; then
|
||||
dev_list="${dev_list} binutils-arm-linux-gnueabihf"
|
||||
fi
|
||||
if package_exists binutils-aarch64-linux-gnu; then
|
||||
dev_list="${dev_list} binutils-aarch64-linux-gnu"
|
||||
fi
|
||||
if package_exists binutils-mipsel-linux-gnu; then
|
||||
dev_list="${dev_list} binutils-mipsel-linux-gnu"
|
||||
fi
|
||||
if package_exists binutils-mips64el-linux-gnuabi64; then
|
||||
dev_list="${dev_list} binutils-mips64el-linux-gnuabi64"
|
||||
fi
|
||||
# When cross building for arm/Android on 64-bit systems the host binaries
|
||||
# that are part of v8 need to be compiled with -m32 which means
|
||||
# that basic multilib support is needed.
|
||||
if file -L /sbin/init | grep -q 'ELF 64-bit'; then
|
||||
# gcc-multilib conflicts with the arm cross compiler (at least in trusty) but
|
||||
# g++-X.Y-multilib gives us the 32-bit support that we need. Find out the
|
||||
# appropriate value of X and Y by seeing what version the current
|
||||
# distribution's g++-multilib package depends on.
|
||||
multilib_package=$(apt-cache depends g++-multilib --important | \
|
||||
grep -E --color=never --only-matching '\bg\+\+-[0-9.]+-multilib\b')
|
||||
lib32_list="$lib32_list $multilib_package"
|
||||
fi
|
||||
if [ "$do_inst_syms" = "1" ]; then
|
||||
echo "Including debugging symbols."
|
||||
# Debian is in the process of transitioning to automatic debug packages, which
|
||||
# have the -dbgsym suffix (https://wiki.debian.org/AutomaticDebugPackages).
|
||||
# Untransitioned packages have the -dbg suffix. And on some systems, neither
|
||||
# will be available, so exclude the ones that are missing.
|
||||
dbg_package_name() {
|
||||
if package_exists "$1-dbgsym"; then
|
||||
echo "$1-dbgsym"
|
||||
elif package_exists "$1-dbg"; then
|
||||
echo "$1-dbg"
|
||||
fi
|
||||
}
|
||||
for package in "${common_lib_list}"; do
|
||||
dbg_list="$dbg_list $(dbg_package_name ${package})"
|
||||
done
|
||||
# Debugging symbols packages not following common naming scheme
|
||||
if [ "$(dbg_package_name libstdc++6)" == "" ]; then
|
||||
if package_exists libstdc++6-8-dbg; then
|
||||
dbg_list="${dbg_list} libstdc++6-8-dbg"
|
||||
elif package_exists libstdc++6-7-dbg; then
|
||||
dbg_list="${dbg_list} libstdc++6-7-dbg"
|
||||
elif package_exists libstdc++6-6-dbg; then
|
||||
dbg_list="${dbg_list} libstdc++6-6-dbg"
|
||||
elif package_exists libstdc++6-5-dbg; then
|
||||
dbg_list="${dbg_list} libstdc++6-5-dbg"
|
||||
elif package_exists libstdc++6-4.9-dbg; then
|
||||
dbg_list="${dbg_list} libstdc++6-4.9-dbg"
|
||||
elif package_exists libstdc++6-4.8-dbg; then
|
||||
dbg_list="${dbg_list} libstdc++6-4.8-dbg"
|
||||
elif package_exists libstdc++6-4.7-dbg; then
|
||||
dbg_list="${dbg_list} libstdc++6-4.7-dbg"
|
||||
elif package_exists libstdc++6-4.6-dbg; then
|
||||
dbg_list="${dbg_list} libstdc++6-4.6-dbg"
|
||||
fi
|
||||
fi
|
||||
if [ "$(dbg_package_name libatk1.0-0)" == "" ]; then
|
||||
dbg_list="$dbg_list $(dbg_package_name libatk1.0)"
|
||||
fi
|
||||
if [ "$(dbg_package_name libpango1.0-0)" == "" ]; then
|
||||
dbg_list="$dbg_list $(dbg_package_name libpango1.0-dev)"
|
||||
fi
|
||||
else
|
||||
echo "Skipping debugging symbols."
|
||||
dbg_list=
|
||||
fi
|
||||
if [ "$do_inst_lib32" = "1" ]; then
|
||||
echo "Including 32-bit libraries."
|
||||
else
|
||||
echo "Skipping 32-bit libraries."
|
||||
lib32_list=
|
||||
fi
|
||||
if [ "$do_inst_arm" = "1" ]; then
|
||||
echo "Including ARM cross toolchain."
|
||||
else
|
||||
echo "Skipping ARM cross toolchain."
|
||||
arm_list=
|
||||
fi
|
||||
if [ "$do_inst_nacl" = "1" ]; then
|
||||
echo "Including NaCl, NaCl toolchain, NaCl ports dependencies."
|
||||
else
|
||||
echo "Skipping NaCl, NaCl toolchain, NaCl ports dependencies."
|
||||
nacl_list=
|
||||
fi
|
||||
filtered_backwards_compatible_list=
|
||||
if [ "$do_inst_backwards_compatible" = "1" ]; then
|
||||
echo "Including backwards compatible packages."
|
||||
for package in ${backwards_compatible_list}; do
|
||||
if package_exists ${package}; then
|
||||
filtered_backwards_compatible_list+=" ${package}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
# The `sort -r -s -t: -k2` sorts all the :i386 packages to the front, to avoid
|
||||
# confusing dpkg-query (crbug.com/446172).
|
||||
packages="$(
|
||||
echo "${dev_list} ${lib_list} ${dbg_list} ${lib32_list} ${arm_list}" \
|
||||
"${nacl_list}" ${filtered_backwards_compatible_list} | tr " " "\n" | \
|
||||
sort -u | sort -r -s -t: -k2 | tr "\n" " "
|
||||
)"
|
||||
if [ 1 -eq "${do_quick_check-0}" ] ; then
|
||||
if ! missing_packages="$(dpkg-query -W -f ' ' ${packages} 2>&1)"; then
|
||||
# Distinguish between packages that actually aren't available to the
|
||||
# system (i.e. not in any repo) and packages that just aren't known to
|
||||
# dpkg (i.e. managed by apt).
|
||||
missing_packages="$(echo "${missing_packages}" | awk '{print $NF}')"
|
||||
not_installed=""
|
||||
unknown=""
|
||||
for p in ${missing_packages}; do
|
||||
if apt-cache show ${p} > /dev/null 2>&1; then
|
||||
not_installed="${p}\n${not_installed}"
|
||||
else
|
||||
unknown="${p}\n${unknown}"
|
||||
fi
|
||||
done
|
||||
if [ -n "${not_installed}" ]; then
|
||||
echo "WARNING: The following packages are not installed:"
|
||||
echo -e "${not_installed}" | sed -e "s/^/ /"
|
||||
fi
|
||||
if [ -n "${unknown}" ]; then
|
||||
echo "WARNING: The following packages are unknown to your system"
|
||||
echo "(maybe missing a repo or need to 'sudo apt-get update'):"
|
||||
echo -e "${unknown}" | sed -e "s/^/ /"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
if [ "$do_inst_lib32" = "1" ] || [ "$do_inst_nacl" = "1" ]; then
|
||||
sudo dpkg --add-architecture i386
|
||||
fi
|
||||
sudo apt-get update
|
||||
# We initially run "apt-get" with the --reinstall option and parse its output.
|
||||
# This way, we can find all the packages that need to be newly installed
|
||||
# without accidentally promoting any packages from "auto" to "manual".
|
||||
# We then re-run "apt-get" with just the list of missing packages.
|
||||
echo "Finding missing packages..."
|
||||
# Intentionally leaving $packages unquoted so it's more readable.
|
||||
echo "Packages required: " $packages
|
||||
echo
|
||||
new_list_cmd="sudo apt-get install --reinstall $(echo $packages)"
|
||||
if new_list="$(yes n | LANGUAGE=en LANG=C $new_list_cmd)"; then
|
||||
# We probably never hit this following line.
|
||||
echo "No missing packages, and the packages are up to date."
|
||||
elif [ $? -eq 1 ]; then
|
||||
# We expect apt-get to have exit status of 1.
|
||||
# This indicates that we cancelled the install with "yes n|".
|
||||
new_list=$(echo "$new_list" |
|
||||
sed -e '1,/The following NEW packages will be installed:/d;s/^ //;t;d')
|
||||
new_list=$(echo "$new_list" | sed 's/ *$//')
|
||||
if [ -z "$new_list" ] ; then
|
||||
echo "No missing packages, and the packages are up to date."
|
||||
else
|
||||
echo "Installing missing packages: $new_list."
|
||||
sudo apt-get install ${do_quietly-} ${new_list}
|
||||
fi
|
||||
echo
|
||||
else
|
||||
# An apt-get exit status of 100 indicates that a real error has occurred.
|
||||
# I am intentionally leaving out the '"'s around new_list_cmd,
|
||||
# as this makes it easier to cut and paste the output
|
||||
echo "The following command failed: " ${new_list_cmd}
|
||||
echo
|
||||
echo "It produces the following output:"
|
||||
yes n | $new_list_cmd || true
|
||||
echo
|
||||
echo "You will have to install the above packages yourself."
|
||||
echo
|
||||
exit 100
|
||||
fi
|
||||
# Install the Chrome OS default fonts. This must go after running
|
||||
# apt-get, since install-chromeos-fonts depends on curl.
|
||||
if [ "$do_inst_chromeos_fonts" != "0" ]; then
|
||||
echo
|
||||
echo "Installing Chrome OS fonts."
|
||||
dir=`echo $0 | sed -r -e 's/\/[^/]+$//'`
|
||||
if ! sudo $dir/linux/install-chromeos-fonts.py; then
|
||||
echo "ERROR: The installation of the Chrome OS default fonts failed."
|
||||
if [ `stat -f -c %T $dir` == "nfs" ]; then
|
||||
echo "The reason is that your repo is installed on a remote file system."
|
||||
else
|
||||
echo "This is expected if your repo is installed on a remote file system."
|
||||
fi
|
||||
echo "It is recommended to install your repo on a local file system."
|
||||
echo "You can skip the installation of the Chrome OS default founts with"
|
||||
echo "the command line option: --no-chromeos-fonts."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Skipping installation of Chrome OS fonts."
|
||||
fi
|
||||
echo "Installing locales."
|
||||
CHROMIUM_LOCALES="da_DK.UTF-8 fr_FR.UTF-8 he_IL.UTF-8 zh_TW.UTF-8"
|
||||
LOCALE_GEN=/etc/locale.gen
|
||||
if [ -e ${LOCALE_GEN} ]; then
|
||||
OLD_LOCALE_GEN="$(cat /etc/locale.gen)"
|
||||
for CHROMIUM_LOCALE in ${CHROMIUM_LOCALES}; do
|
||||
sudo sed -i "s/^# ${CHROMIUM_LOCALE}/${CHROMIUM_LOCALE}/" ${LOCALE_GEN}
|
||||
done
|
||||
# Regenerating locales can take a while, so only do it if we need to.
|
||||
if (echo "${OLD_LOCALE_GEN}" | cmp -s ${LOCALE_GEN}); then
|
||||
echo "Locales already up-to-date."
|
||||
else
|
||||
sudo locale-gen
|
||||
fi
|
||||
else
|
||||
for CHROMIUM_LOCALE in ${CHROMIUM_LOCALES}; do
|
||||
sudo locale-gen ${CHROMIUM_LOCALE}
|
||||
done
|
||||
fi
|
||||
@@ -91,11 +91,6 @@ These individual tutorials expand on topics discussed in the guide above.
|
||||
* Electron Releases & Developer Feedback
|
||||
* [Versioning Policy](tutorial/electron-versioning.md)
|
||||
* [Release Timelines](tutorial/electron-timelines.md)
|
||||
* [Packaging App Source Code with asar](tutorial/application-packaging.md)
|
||||
* [Generating asar Archives](tutorial/application-packaging.md#generating-asar-archives)
|
||||
* [Using asar Archives](tutorial/application-packaging.md#using-asar-archives)
|
||||
* [Limitations](tutorial/application-packaging.md#limitations-of-the-node-api)
|
||||
* [Adding Unpacked Files to asar Archives](tutorial/application-packaging.md#adding-unpacked-files-to-asar-archives)
|
||||
* [Testing Widevine CDM](tutorial/testing-widevine-cdm.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -227,7 +227,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
unless hovered over in the top left of the window. These custom buttons prevent
|
||||
issues with mouse events that occur with the standard window toolbar buttons.
|
||||
**Note:** This option is currently experimental.
|
||||
* `trafficLightPosition` [Point](structures/point.md) (optional) - Set a custom position for the traffic light buttons. Can only be used with `titleBarStyle` set to `hidden`
|
||||
* `trafficLightPosition` [Point](structures/point.md) (optional) - Set a
|
||||
custom position for the traffic light buttons. Can only be used with
|
||||
`titleBarStyle` set to `hidden` or `customButtonsOnHover`.
|
||||
* `fullscreenWindowTitle` Boolean (optional) - Shows the title in the
|
||||
title bar in full screen mode on macOS for all `titleBarStyle` options.
|
||||
Default is `false`.
|
||||
@@ -723,94 +725,6 @@ Returns `BrowserWindow | null` - The window that owns the given `browserView`. I
|
||||
|
||||
Returns `BrowserWindow | null` - The window with the given `id`.
|
||||
|
||||
#### `BrowserWindow.addExtension(path)` _Deprecated_
|
||||
|
||||
* `path` String
|
||||
|
||||
Adds Chrome extension located at `path`, and returns extension's name.
|
||||
|
||||
The method will also not return if the extension's manifest is missing or incomplete.
|
||||
|
||||
**Note:** This API cannot be called before the `ready` event of the `app` module
|
||||
is emitted.
|
||||
|
||||
**Note:** This method is deprecated. Instead, use
|
||||
[`ses.loadExtension(path)`](session.md#sesloadextensionpath).
|
||||
|
||||
#### `BrowserWindow.removeExtension(name)` _Deprecated_
|
||||
|
||||
* `name` String
|
||||
|
||||
Remove a Chrome extension by name.
|
||||
|
||||
**Note:** This API cannot be called before the `ready` event of the `app` module
|
||||
is emitted.
|
||||
|
||||
**Note:** This method is deprecated. Instead, use
|
||||
[`ses.removeExtension(extension_id)`](session.md#sesremoveextensionextensionid).
|
||||
|
||||
#### `BrowserWindow.getExtensions()` _Deprecated_
|
||||
|
||||
Returns `Record<String, ExtensionInfo>` - The keys are the extension names and each value is
|
||||
an Object containing `name` and `version` properties.
|
||||
|
||||
**Note:** This API cannot be called before the `ready` event of the `app` module
|
||||
is emitted.
|
||||
|
||||
**Note:** This method is deprecated. Instead, use
|
||||
[`ses.getAllExtensions()`](session.md#sesgetallextensions).
|
||||
|
||||
#### `BrowserWindow.addDevToolsExtension(path)` _Deprecated_
|
||||
|
||||
* `path` String
|
||||
|
||||
Adds DevTools extension located at `path`, and returns extension's name.
|
||||
|
||||
The extension will be remembered so you only need to call this API once, this
|
||||
API is not for programming use. If you try to add an extension that has already
|
||||
been loaded, this method will not return and instead log a warning to the
|
||||
console.
|
||||
|
||||
The method will also not return if the extension's manifest is missing or incomplete.
|
||||
|
||||
**Note:** This API cannot be called before the `ready` event of the `app` module
|
||||
is emitted.
|
||||
|
||||
**Note:** This method is deprecated. Instead, use
|
||||
[`ses.loadExtension(path)`](session.md#sesloadextensionpath).
|
||||
|
||||
#### `BrowserWindow.removeDevToolsExtension(name)` _Deprecated_
|
||||
|
||||
* `name` String
|
||||
|
||||
Remove a DevTools extension by name.
|
||||
|
||||
**Note:** This API cannot be called before the `ready` event of the `app` module
|
||||
is emitted.
|
||||
|
||||
**Note:** This method is deprecated. Instead, use
|
||||
[`ses.removeExtension(extension_id)`](session.md#sesremoveextensionextensionid).
|
||||
|
||||
#### `BrowserWindow.getDevToolsExtensions()` _Deprecated_
|
||||
|
||||
Returns `Record<string, ExtensionInfo>` - The keys are the extension names and each value is
|
||||
an Object containing `name` and `version` properties.
|
||||
|
||||
To check if a DevTools extension is installed you can run the following:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const installed = 'devtron' in BrowserWindow.getDevToolsExtensions()
|
||||
console.log(installed)
|
||||
```
|
||||
|
||||
**Note:** This API cannot be called before the `ready` event of the `app` module
|
||||
is emitted.
|
||||
|
||||
**Note:** This method is deprecated. Instead, use
|
||||
[`ses.getAllExtensions()`](session.md#sesgetallextensions).
|
||||
|
||||
### Instance Properties
|
||||
|
||||
Objects created with `new BrowserWindow` have the following properties:
|
||||
@@ -1825,12 +1739,13 @@ deprecated and will be removed in an upcoming version of macOS.
|
||||
|
||||
* `position` [Point](structures/point.md)
|
||||
|
||||
Set a custom position for the traffic light buttons. Can only be used with `titleBarStyle` set to `hidden`.
|
||||
Set a custom position for the traffic light buttons. Can only be used with
|
||||
`titleBarStyle` set to `hidden` or `customButtonsOnHover`.
|
||||
|
||||
#### `win.getTrafficLightPosition()` _macOS_
|
||||
|
||||
Returns `Point` - The current position for the traffic light buttons. Can only be used with `titleBarStyle`
|
||||
set to `hidden`.
|
||||
Returns `Point` - The current position for the traffic light buttons. Can only
|
||||
be used with `titleBarStyle` set to `hidden` or `customButtonsOnHover`.
|
||||
|
||||
#### `win.setTouchBar(touchBar)` _macOS_
|
||||
|
||||
|
||||
@@ -65,12 +65,12 @@ Forces the maximum disk space to be used by the disk cache, in bytes.
|
||||
|
||||
Enables caller stack logging for the following APIs (filtering events):
|
||||
|
||||
- `desktopCapturer.getSources()` / `desktop-capturer-get-sources`
|
||||
- `remote.require()` / `remote-require`
|
||||
- `remote.getGlobal()` / `remote-get-builtin`
|
||||
- `remote.getBuiltin()` / `remote-get-global`
|
||||
- `remote.getCurrentWindow()` / `remote-get-current-window`
|
||||
- `remote.getCurrentWebContents()` / `remote-get-current-web-contents`
|
||||
* `desktopCapturer.getSources()` / `desktop-capturer-get-sources`
|
||||
* `remote.require()` / `remote-require`
|
||||
* `remote.getGlobal()` / `remote-get-builtin`
|
||||
* `remote.getBuiltin()` / `remote-get-global`
|
||||
* `remote.getCurrentWindow()` / `remote-get-current-window`
|
||||
* `remote.getCurrentWebContents()` / `remote-get-current-web-contents`
|
||||
|
||||
### --enable-logging
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ const { app, contentTracing } = require('electron')
|
||||
app.whenReady().then(() => {
|
||||
(async () => {
|
||||
await contentTracing.startRecording({
|
||||
include_categories: ['*']
|
||||
included_categories: ['*']
|
||||
})
|
||||
console.log('Tracing started')
|
||||
await new Promise(resolve => setTimeout(resolve, 5000))
|
||||
|
||||
@@ -44,19 +44,19 @@ The `contextBridge` module has the following methods:
|
||||
### `contextBridge.exposeInMainWorld(apiKey, api)` _Experimental_
|
||||
|
||||
* `apiKey` String - The key to inject the API onto `window` with. The API will be accessible on `window[apiKey]`.
|
||||
* `api` Record<String, any> - Your API object, more information on what this API can be and how it works is available below.
|
||||
* `api` any - Your API, more information on what this API can be and how it works is available below.
|
||||
|
||||
## Usage
|
||||
|
||||
### API Objects
|
||||
### API
|
||||
|
||||
The `api` object provided to [`exposeInMainWorld`](#contextbridgeexposeinmainworldapikey-api-experimental) must be an object
|
||||
The `api` provided to [`exposeInMainWorld`](#contextbridgeexposeinmainworldapikey-api-experimental) must be a `Function`, `String`, `Number`, `Array`, `Boolean`, or an object
|
||||
whose keys are strings and values are a `Function`, `String`, `Number`, `Array`, `Boolean`, or another nested object that meets the same conditions.
|
||||
|
||||
`Function` values are proxied to the other context and all other values are **copied** and **frozen**. Any data / primitives sent in
|
||||
the API object become immutable and updates on either side of the bridge do not result in an update on the other side.
|
||||
the API become immutable and updates on either side of the bridge do not result in an update on the other side.
|
||||
|
||||
An example of a complex API object is shown below:
|
||||
An example of a complex API is shown below:
|
||||
|
||||
```javascript
|
||||
const { contextBridge } = require('electron')
|
||||
@@ -106,6 +106,7 @@ has been included below for completeness:
|
||||
| `Promise` | Complex | ✅ | ✅ | Promises are only proxied if they are the return value or exact parameter. Promises nested in arrays or objects will be dropped. |
|
||||
| `Function` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending classes or constructors will not work. |
|
||||
| [Cloneable Types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) | Simple | ✅ | ✅ | See the linked document on cloneable types |
|
||||
| `Element` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending custom elements will not work. |
|
||||
| `Symbol` | N/A | ❌ | ❌ | Symbols cannot be copied across contexts so they are dropped |
|
||||
|
||||
If the type you care about is not in the above table, it is probably not supported.
|
||||
|
||||
@@ -128,7 +128,7 @@ must be at most 39 bytes long, and values must be no longer than 127 bytes.
|
||||
Keys with names longer than the maximum will be silently ignored. Key values
|
||||
longer than the maximum length will be truncated.
|
||||
|
||||
**Note:** Calling this method from the renderer process is deprecated.
|
||||
**Note:** This method is only available in the main process.
|
||||
|
||||
### `crashReporter.getLastCrashReport()`
|
||||
|
||||
@@ -137,7 +137,7 @@ last crash report. Only crash reports that have been uploaded will be returned;
|
||||
even if a crash report is present on disk it will not be returned until it is
|
||||
uploaded. In the case that there are no uploaded reports, `null` is returned.
|
||||
|
||||
**Note:** Calling this method from the renderer process is deprecated.
|
||||
**Note:** This method is only available in the main process.
|
||||
|
||||
### `crashReporter.getUploadedReports()`
|
||||
|
||||
@@ -146,14 +146,14 @@ Returns [`CrashReport[]`](structures/crash-report.md):
|
||||
Returns all uploaded crash reports. Each report contains the date and uploaded
|
||||
ID.
|
||||
|
||||
**Note:** Calling this method from the renderer process is deprecated.
|
||||
**Note:** This method is only available in the main process.
|
||||
|
||||
### `crashReporter.getUploadToServer()`
|
||||
|
||||
Returns `Boolean` - Whether reports should be submitted to the server. Set through
|
||||
the `start` method or `setUploadToServer`.
|
||||
|
||||
**Note:** Calling this method from the renderer process is deprecated.
|
||||
**Note:** This method is only available in the main process.
|
||||
|
||||
### `crashReporter.setUploadToServer(uploadToServer)`
|
||||
|
||||
@@ -162,13 +162,7 @@ the `start` method or `setUploadToServer`.
|
||||
This would normally be controlled by user preferences. This has no effect if
|
||||
called before `start` is called.
|
||||
|
||||
**Note:** Calling this method from the renderer process is deprecated.
|
||||
|
||||
### `crashReporter.getCrashesDirectory()` _Deprecated_
|
||||
|
||||
Returns `String` - The directory where crashes are temporarily stored before being uploaded.
|
||||
|
||||
**Note:** This method is deprecated, use `app.getPath('crashDumps')` instead.
|
||||
**Note:** This method is only available in the main process.
|
||||
|
||||
### `crashReporter.addExtraParameter(key, value)`
|
||||
|
||||
|
||||
@@ -120,6 +120,24 @@ debugging purposes.
|
||||
|
||||
Prints Chrome's internal logging to the console.
|
||||
|
||||
### `ELECTRON_DEBUG_DRAG_REGIONS`
|
||||
|
||||
Adds coloration to draggable regions on [`BrowserView`](./browser-view.md)s on macOS - draggable regions will be colored
|
||||
green and non-draggable regions will be colored red to aid debugging.
|
||||
|
||||
### `ELECTRON_DEBUG_NOTIFICATIONS`
|
||||
|
||||
Adds extra logs to [`Notification`](./notification.md) lifecycles on macOS to aid in debugging. Extra logging will be displayed when new Notifications are created or activated. They will also be displayed when common actions are taken: a notification is shown, dismissed, its button is clicked, or it is replied to.
|
||||
|
||||
Sample output:
|
||||
|
||||
```sh
|
||||
Notification created (com.github.Electron:notification:EAF7B87C-A113-43D7-8E76-F88EC9D73D44)
|
||||
Notification displayed (com.github.Electron:notification:EAF7B87C-A113-43D7-8E76-F88EC9D73D44)
|
||||
Notification activated (com.github.Electron:notification:EAF7B87C-A113-43D7-8E76-F88EC9D73D44)
|
||||
Notification replied to (com.github.Electron:notification:EAF7B87C-A113-43D7-8E76-F88EC9D73D44)
|
||||
```
|
||||
|
||||
### `ELECTRON_LOG_ASAR_READS`
|
||||
|
||||
When Electron reads from an ASAR file, log the read offset and file path to
|
||||
|
||||
@@ -115,3 +115,9 @@ The following methods of `chrome.management` are supported:
|
||||
- `chrome.management.getPermissionWarningsByManifest`
|
||||
- `chrome.management.onEnabled`
|
||||
- `chrome.management.onDisabled`
|
||||
|
||||
### `chrome.webRequest`
|
||||
|
||||
All features of this API are supported.
|
||||
|
||||
> **NOTE:** Electron's [`webRequest`](web-request.md) module takes precedence over `chrome.webRequest` if there are conflicting handlers.
|
||||
|
||||
@@ -9,7 +9,7 @@ with the operating system so that you can customize the operations for various
|
||||
shortcuts.
|
||||
|
||||
**Note:** The shortcut is global; it will work even if the app does
|
||||
not have the keyboard focus. You should not use this module until the `ready`
|
||||
not have the keyboard focus. This module cannot be used before the `ready`
|
||||
event of the app module is emitted.
|
||||
|
||||
```javascript
|
||||
|
||||
@@ -12,28 +12,29 @@ It adds the following events, properties, and methods:
|
||||
|
||||
In sandboxed renderers the `process` object contains only a subset of the APIs:
|
||||
|
||||
- `crash()`
|
||||
- `hang()`
|
||||
- `getCreationTime()`
|
||||
- `getHeapStatistics()`
|
||||
- `getBlinkMemoryInfo()`
|
||||
- `getProcessMemoryInfo()`
|
||||
- `getSystemMemoryInfo()`
|
||||
- `getSystemVersion()`
|
||||
- `getCPUUsage()`
|
||||
- `getIOCounters()`
|
||||
- `argv`
|
||||
- `execPath`
|
||||
- `env`
|
||||
- `pid`
|
||||
- `arch`
|
||||
- `platform`
|
||||
- `sandboxed`
|
||||
- `type`
|
||||
- `version`
|
||||
- `versions`
|
||||
- `mas`
|
||||
- `windowsStore`
|
||||
* `crash()`
|
||||
* `hang()`
|
||||
* `getCreationTime()`
|
||||
* `getHeapStatistics()`
|
||||
* `getBlinkMemoryInfo()`
|
||||
* `getProcessMemoryInfo()`
|
||||
* `getSystemMemoryInfo()`
|
||||
* `getSystemVersion()`
|
||||
* `getCPUUsage()`
|
||||
* `getIOCounters()`
|
||||
* `uptime()`
|
||||
* `argv`
|
||||
* `execPath`
|
||||
* `env`
|
||||
* `pid`
|
||||
* `arch`
|
||||
* `platform`
|
||||
* `sandboxed`
|
||||
* `type`
|
||||
* `version`
|
||||
* `versions`
|
||||
* `mas`
|
||||
* `windowsStore`
|
||||
|
||||
## Events
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ you can use [webContents.executeJavaScript](web-contents.md#contentsexecutejavas
|
||||
|
||||
**Note:** The remote module can be disabled for security reasons in the following contexts:
|
||||
|
||||
- [`BrowserWindow`](browser-window.md) - by setting the `enableRemoteModule` option to `false`.
|
||||
- [`<webview>`](webview-tag.md) - by setting the `enableremotemodule` attribute to `false`.
|
||||
* [`BrowserWindow`](browser-window.md) - by setting the `enableRemoteModule` option to `false`.
|
||||
* [`<webview>`](webview-tag.md) - by setting the `enableremotemodule` attribute to `false`.
|
||||
|
||||
## Remote Objects
|
||||
|
||||
|
||||
@@ -101,8 +101,8 @@ Returns:
|
||||
Emitted after an extension is loaded. This occurs whenever an extension is
|
||||
added to the "enabled" set of extensions. This includes:
|
||||
|
||||
- Extensions being loaded from `Session.loadExtension`.
|
||||
- Extensions being reloaded:
|
||||
* Extensions being loaded from `Session.loadExtension`.
|
||||
* Extensions being reloaded:
|
||||
* from a crash.
|
||||
* if the extension requested it ([`chrome.runtime.reload()`](https://developer.chrome.com/extensions/runtime#method-reload)).
|
||||
|
||||
@@ -215,15 +215,15 @@ app.whenReady().then(() => {
|
||||
enableBlinkFeatures: 'Serial'
|
||||
}
|
||||
})
|
||||
win.webContents.session.on('select-serial-port', (event, portList, callback) => {
|
||||
win.webContents.session.on('select-serial-port', (event, portList, webContents, callback) => {
|
||||
event.preventDefault()
|
||||
const selectedPort = portList.find((device) => {
|
||||
return device.vendorId === 0x2341 && device.productId === 0x0043
|
||||
return device.vendorId === '9025' && device.productId === '67'
|
||||
})
|
||||
if (!selectedPort) {
|
||||
callback('')
|
||||
} else {
|
||||
callback(result1.portId)
|
||||
callback(selectedPort.portId)
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -492,6 +492,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
* `permission` String - The type of requested permission.
|
||||
* `clipboard-read` - Request access to read from the clipboard.
|
||||
* `media` - Request access to media devices such as camera, microphone and speakers.
|
||||
* `display-capture` - Request access to capture the screen.
|
||||
* `mediaKeySystem` - Request access to DRM protected content.
|
||||
* `geolocation` - Request access to user's current location.
|
||||
* `notifications` - Request notification creation and the ability to display them in the user's system tray.
|
||||
@@ -500,6 +501,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
* `pointerLock` - Request to directly interpret mouse movements as an input method. Click [here](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) to know more.
|
||||
* `fullscreen` - Request for the app to enter fullscreen mode.
|
||||
* `openExternal` - Request to open links in external applications.
|
||||
* `unknown` - An unrecognized permission request
|
||||
* `callback` Function
|
||||
* `permissionGranted` Boolean - Allow or deny the permission.
|
||||
* `details` Object - Some properties are only available on certain permission types.
|
||||
@@ -511,7 +513,9 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
|
||||
Sets the handler which can be used to respond to permission requests for the `session`.
|
||||
Calling `callback(true)` will allow the permission and `callback(false)` will reject it.
|
||||
To clear the handler, call `setPermissionRequestHandler(null)`.
|
||||
To clear the handler, call `setPermissionRequestHandler(null)`. Please note that
|
||||
you must also implement `setPermissionCheckHandler` to get complete permission handling.
|
||||
Most web APIs do a permission check and then make a permission request if the check is denied.
|
||||
|
||||
```javascript
|
||||
const { session } = require('electron')
|
||||
@@ -527,28 +531,32 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
|
||||
#### `ses.setPermissionCheckHandler(handler)`
|
||||
|
||||
* `handler` Function\<Boolean> | null
|
||||
* `webContents` [WebContents](web-contents.md) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
|
||||
* `webContents` ([WebContents](web-contents.md) | null) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin. Cross origin sub frames making permission checks will pass a `null` webContents to this handler. You should use `embeddingOrigin` and `requestingOrigin` to determine what origin the owning frame and the requesting frame are on respectively.
|
||||
* `permission` String - Type of permission check. Valid values are `midiSysex`, `notifications`, `geolocation`, `media`,`mediaKeySystem`,`midi`, `pointerLock`, `fullscreen`, `openExternal`, or `serial`.
|
||||
* `requestingOrigin` String - The origin URL of the permission check
|
||||
* `details` Object - Some properties are only available on certain permission types.
|
||||
* `securityOrigin` String - The security origin of the `media` check.
|
||||
* `mediaType` String - The type of media access being requested, can be `video`,
|
||||
* `embeddingOrigin` String (optional) - The origin of the frame embedding the frame that made the permission check. Only set for cross-origin sub frames making permission checks.
|
||||
* `securityOrigin` String (optional) - The security origin of the `media` check.
|
||||
* `mediaType` String (optional) - The type of media access being requested, can be `video`,
|
||||
`audio` or `unknown`
|
||||
* `requestingUrl` String - The last URL the requesting frame loaded
|
||||
* `requestingUrl` String (optional) - The last URL the requesting frame loaded. This is not provided for cross-origin sub frames making permission checks.
|
||||
* `isMainFrame` Boolean - Whether the frame making the request is the main frame
|
||||
|
||||
Sets the handler which can be used to respond to permission checks for the `session`.
|
||||
Returning `true` will allow the permission and `false` will reject it.
|
||||
Returning `true` will allow the permission and `false` will reject it. Please note that
|
||||
you must also implement `setPermissionRequestHandler` to get complete permission handling.
|
||||
Most web APIs do a permission check and then make a permission request if the check is denied.
|
||||
To clear the handler, call `setPermissionCheckHandler(null)`.
|
||||
|
||||
```javascript
|
||||
const { session } = require('electron')
|
||||
session.fromPartition('some-partition').setPermissionCheckHandler((webContents, permission) => {
|
||||
if (webContents.getURL() === 'some-host' && permission === 'notifications') {
|
||||
return false // denied
|
||||
const url = require('url')
|
||||
session.fromPartition('some-partition').setPermissionCheckHandler((webContents, permission, requestingOrigin) => {
|
||||
if (new URL(requestingOrigin).hostname === 'some-host' && permission === 'notifications') {
|
||||
return true // granted
|
||||
}
|
||||
|
||||
return true
|
||||
return false // denied
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -45,17 +45,6 @@ Returns `Promise<void>`
|
||||
|
||||
Open the given external protocol URL in the desktop's default manner. (For example, mailto: URLs in the user's default mail agent).
|
||||
|
||||
### `shell.moveItemToTrash(fullPath[, deleteOnFail])` _Deprecated_
|
||||
|
||||
* `fullPath` String
|
||||
* `deleteOnFail` Boolean (optional) - Whether or not to unilaterally remove the item if the Trash is disabled or unsupported on the volume. _macOS_
|
||||
|
||||
Returns `Boolean` - Whether the item was successfully moved to the trash or otherwise deleted.
|
||||
|
||||
> NOTE: This method is deprecated. Use `shell.trashItem` instead.
|
||||
|
||||
Move the given file to trash and returns a boolean status for the operation.
|
||||
|
||||
### `shell.trashItem(path)`
|
||||
|
||||
* `path` String - path to the item to be moved to the trash.
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# IpcMainEvent Object extends `Event`
|
||||
|
||||
* `processId` Integer - The internal ID of the renderer process that sent this message
|
||||
* `frameId` Integer - The ID of the renderer frame that sent this message
|
||||
* `returnValue` any - Set this to the value to be returned in a synchronous message
|
||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||
* `senderFrame` WebFrameMain _Readonly_ - The frame that sent this message
|
||||
* `ports` MessagePortMain[] - A list of MessagePorts that were transferred with this message
|
||||
* `reply` Function - A function that will send an IPC message to the renderer frame that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guarantee the reply will go to the correct process and frame.
|
||||
* `channel` String
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# IpcMainInvokeEvent Object extends `Event`
|
||||
|
||||
* `processId` Integer - The internal ID of the renderer process that sent this message
|
||||
* `frameId` Integer - The ID of the renderer frame that sent this message
|
||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||
* `senderFrame` WebFrameMain _Readonly_ - The frame that sent this message
|
||||
|
||||
@@ -433,7 +433,7 @@ It will always return `granted` for `screen` and for all media types on older ve
|
||||
|
||||
Returns `Promise<Boolean>` - A promise that resolves with `true` if consent was granted and `false` if it was denied. If an invalid `mediaType` is passed, the promise will be rejected. If an access request was denied and later is changed through the System Preferences pane, a restart of the app will be required for the new permissions to take effect. If access has already been requested and denied, it _must_ be changed through the preference pane; an alert will not pop up and the promise will resolve with the existing access status.
|
||||
|
||||
**Important:** In order to properly leverage this API, you [must set](https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_macos?language=objc) the `NSMicrophoneUsageDescription` and `NSCameraUsageDescription` strings in your app's `Info.plist` file. The values for these keys will be used to populate the permission dialogs so that the user will be properly informed as to the purpose of the permission request. See [Electron Application Distribution](https://electronjs.org/docs/tutorial/application-distribution#macos) for more information about how to set these in the context of Electron.
|
||||
**Important:** In order to properly leverage this API, you [must set](https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_macos?language=objc) the `NSMicrophoneUsageDescription` and `NSCameraUsageDescription` strings in your app's `Info.plist` file. The values for these keys will be used to populate the permission dialogs so that the user will be properly informed as to the purpose of the permission request. See [Electron Application Distribution](../tutorial/application-distribution.md#macos) for more information about how to set these in the context of Electron.
|
||||
|
||||
This user consent was not required until macOS 10.14 Mojave, so this method will always return `true` if your system is running 10.13 High Sierra or lower.
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@ returns `null`.
|
||||
|
||||
* `id` Integer
|
||||
|
||||
Returns `WebContents` - A WebContents instance with the given ID.
|
||||
Returns `WebContents` | undefined - A WebContents instance with the given ID, or
|
||||
`undefined` if there is no WebContents associated with the given ID.
|
||||
|
||||
## Class: WebContents
|
||||
|
||||
@@ -155,7 +156,7 @@ Returns:
|
||||
be set. If no post data is to be sent, the value will be `null`. Only defined
|
||||
when the window is being created by a form that set `target=_blank`.
|
||||
|
||||
Deprecated in favor of [`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandler-handler).
|
||||
Deprecated in favor of [`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandlerhandler).
|
||||
|
||||
Emitted when the page requests to open a new window for a `url`. It could be
|
||||
requested by `window.open` or an external link like `<a target='_blank'>`.
|
||||
@@ -194,33 +195,34 @@ myBrowserWindow.webContents.on('new-window', (event, url, frameName, disposition
|
||||
#### Event: 'did-create-window'
|
||||
|
||||
Returns:
|
||||
|
||||
* `window` BrowserWindow
|
||||
* `details` Object
|
||||
* `url` String - URL for the created window.
|
||||
* `frameName` String - Name given to the created window in the
|
||||
`window.open()` call.
|
||||
* `options` BrowserWindowConstructorOptions - The options used to create the
|
||||
BrowserWindow. They are merged in increasing precedence: options inherited
|
||||
from the parent, parsed options from the `features` string from
|
||||
`window.open()`, and options given by
|
||||
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandler-handler).
|
||||
Unrecognized options are not filtered out.
|
||||
* `additionalFeatures` String[] - The non-standard features (features not
|
||||
handled Chromium or Electron) _Deprecated_
|
||||
* `referrer` [Referrer](structures/referrer.md) - The referrer that will be
|
||||
passed to the new window. May or may not result in the `Referer` header
|
||||
being sent, depending on the referrer policy.
|
||||
* `postBody` [PostBody](structures/post-body.md) (optional) - The post data
|
||||
that will be sent to the new window, along with the appropriate headers
|
||||
that will be set. If no post data is to be sent, the value will be `null`.
|
||||
Only defined when the window is being created by a form that set
|
||||
`target=_blank`.
|
||||
* `disposition` String - Can be `default`, `foreground-tab`,
|
||||
`background-tab`, `new-window`, `save-to-disk` and `other`.
|
||||
* `url` String - URL for the created window.
|
||||
* `frameName` String - Name given to the created window in the
|
||||
`window.open()` call.
|
||||
* `options` BrowserWindowConstructorOptions - The options used to create the
|
||||
BrowserWindow. They are merged in increasing precedence: options inherited
|
||||
from the parent, parsed options from the `features` string from
|
||||
`window.open()`, and options given by
|
||||
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandlerhandler).
|
||||
Unrecognized options are not filtered out.
|
||||
* `additionalFeatures` String[] - The non-standard features (features not
|
||||
handled Chromium or Electron) _Deprecated_
|
||||
* `referrer` [Referrer](structures/referrer.md) - The referrer that will be
|
||||
passed to the new window. May or may not result in the `Referer` header
|
||||
being sent, depending on the referrer policy.
|
||||
* `postBody` [PostBody](structures/post-body.md) (optional) - The post data
|
||||
that will be sent to the new window, along with the appropriate headers
|
||||
that will be set. If no post data is to be sent, the value will be `null`.
|
||||
Only defined when the window is being created by a form that set
|
||||
`target=_blank`.
|
||||
* `disposition` String - Can be `default`, `foreground-tab`,
|
||||
`background-tab`, `new-window`, `save-to-disk` and `other`.
|
||||
|
||||
Emitted _after_ successful creation of a window via `window.open` in the renderer.
|
||||
Not emitted if the creation of the window is canceled from
|
||||
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandler-handler).
|
||||
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandlerhandler).
|
||||
|
||||
See [`window.open()`](window-open.md) for more details and how to use this in conjunction with `webContents.setWindowOpenHandler`.
|
||||
|
||||
@@ -638,8 +640,15 @@ Returns:
|
||||
* `isEditable` Boolean - Whether the context is editable.
|
||||
* `selectionText` String - Text of the selection that the context menu was
|
||||
invoked on.
|
||||
* `titleText` String - Title or alt text of the selection that the context
|
||||
was invoked on.
|
||||
* `titleText` String - Title text of the selection that the context menu was
|
||||
invoked on.
|
||||
* `altText` String - Alt text of the selection that the context menu was
|
||||
invoked on.
|
||||
* `suggestedFilename` String - Suggested filename to be used when saving file through 'Save
|
||||
Link As' option of context menu.
|
||||
* `selectionRect` [Rectangle](structures/rectangle.md) - Rect representing the coordinates in the document space of the selection.
|
||||
* `selectionStartOffset` Number - Start position of the selection text.
|
||||
* `referrerPolicy` [Referrer](structures/referrer.md) - The referrer policy of the frame on which the menu is invoked.
|
||||
* `misspelledWord` String - The misspelled word under the cursor, if any.
|
||||
* `dictionarySuggestions` String[] - An array of suggested words to show the
|
||||
user to replace the `misspelledWord`. Only available if there is a misspelled
|
||||
@@ -649,8 +658,9 @@ Returns:
|
||||
* `inputFieldType` String - If the context menu was invoked on an input
|
||||
field, the type of that field. Possible values are `none`, `plainText`,
|
||||
`password`, `other`.
|
||||
* `spellcheckEnabled` Boolean - If the context is editable, whether or not spellchecking is enabled.
|
||||
* `menuSourceType` String - Input source that invoked the context menu.
|
||||
Can be `none`, `mouse`, `keyboard`, `touch` or `touchMenu`.
|
||||
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
|
||||
* `mediaFlags` Object - The flags for the media element the context menu was
|
||||
invoked on.
|
||||
* `inError` Boolean - Whether the media element has crashed.
|
||||
@@ -662,16 +672,22 @@ Returns:
|
||||
visible.
|
||||
* `canToggleControls` Boolean - Whether the media element's controls are
|
||||
toggleable.
|
||||
* `canPrint` Boolean - Whether the media element can be printed.
|
||||
* `canSave` Boolean - Whether or not the media element can be downloaded.
|
||||
* `canShowPictureInPicture` Boolean - Whether the media element can show picture-in-picture.
|
||||
* `isShowingPictureInPicture` Boolean - Whether the media element is currently showing picture-in-picture.
|
||||
* `canRotate` Boolean - Whether the media element can be rotated.
|
||||
* `canLoop` Boolean - Whether the media element can be looped.
|
||||
* `editFlags` Object - These flags indicate whether the renderer believes it
|
||||
is able to perform the corresponding action.
|
||||
* `canUndo` Boolean - Whether the renderer believes it can undo.
|
||||
* `canRedo` Boolean - Whether the renderer believes it can redo.
|
||||
* `canCut` Boolean - Whether the renderer believes it can cut.
|
||||
* `canCopy` Boolean - Whether the renderer believes it can copy
|
||||
* `canCopy` Boolean - Whether the renderer believes it can copy.
|
||||
* `canPaste` Boolean - Whether the renderer believes it can paste.
|
||||
* `canDelete` Boolean - Whether the renderer believes it can delete.
|
||||
* `canSelectAll` Boolean - Whether the renderer believes it can select all.
|
||||
* `canEditRichly` Boolean - Whether the renderer believes it can edit text richly.
|
||||
|
||||
Emitted when there is a new context menu that needs to be handled.
|
||||
|
||||
@@ -1463,7 +1479,7 @@ By default, an empty `options` will be regarded as:
|
||||
}
|
||||
```
|
||||
|
||||
Use `page-break-before: always; ` CSS style to force to print to a new page.
|
||||
Use `page-break-before: always;` CSS style to force to print to a new page.
|
||||
|
||||
An example of `webContents.printToPDF`:
|
||||
|
||||
@@ -1694,7 +1710,7 @@ app.whenReady().then(() => {
|
||||
|
||||
#### `contents.sendToFrame(frameId, channel, ...args)`
|
||||
|
||||
* `frameId` Integer
|
||||
* `frameId` Integer | [number, number]
|
||||
* `channel` String
|
||||
* `...args` any[]
|
||||
|
||||
@@ -1869,7 +1885,7 @@ Returns `Boolean` - If *offscreen rendering* is enabled returns whether it is cu
|
||||
* `fps` Integer
|
||||
|
||||
If *offscreen rendering* is enabled sets the frame rate to the specified number.
|
||||
Only values between 1 and 60 are accepted.
|
||||
Only values between 1 and 240 are accepted.
|
||||
|
||||
#### `contents.getFrameRate()`
|
||||
|
||||
@@ -1967,7 +1983,7 @@ The zoom factor is the zoom percent divided by 100, so 300% = 3.0.
|
||||
#### `contents.frameRate`
|
||||
|
||||
An `Integer` property that sets the frame rate of the web contents to the specified number.
|
||||
Only values between 1 and 60 are accepted.
|
||||
Only values between 1 and 240 are accepted.
|
||||
|
||||
Only applicable if *offscreen rendering* is enabled.
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ win.webContents.on(
|
||||
)
|
||||
```
|
||||
|
||||
You can also access frames of existing pages by using the `webFrame` property
|
||||
You can also access frames of existing pages by using the `mainFrame` property
|
||||
of [`WebContents`](web-contents.md).
|
||||
|
||||
```javascript
|
||||
@@ -57,8 +57,8 @@ These methods can be accessed from the `webFrameMain` module:
|
||||
|
||||
### `webFrameMain.fromId(processId, routingId)`
|
||||
|
||||
* `processId` Integer - An `Integer` representing the id of the process which owns the frame.
|
||||
* `routingId` Integer - An `Integer` representing the unique frame id in the
|
||||
* `processId` Integer - An `Integer` representing the internal ID of the process which owns the frame.
|
||||
* `routingId` Integer - An `Integer` representing the unique frame ID in the
|
||||
current renderer process. Routing IDs can be retrieved from `WebFrameMain`
|
||||
instances (`frame.routingId`) and are also passed by frame
|
||||
specific `WebContents` navigation events (e.g. `did-frame-navigate`).
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
There are several ways to control how windows are created from trusted or
|
||||
untrusted content within a renderer. Windows can be created from the renderer in two ways:
|
||||
|
||||
- clicking on links or submitting forms adorned with `target=_blank`
|
||||
- JavaScript calling `window.open()`
|
||||
* clicking on links or submitting forms adorned with `target=_blank`
|
||||
* JavaScript calling `window.open()`
|
||||
|
||||
In non-sandboxed renderers, or when `nativeWindowOpen` is false (the default), this results in the creation of a
|
||||
[`BrowserWindowProxy`](browser-window-proxy.md), a light wrapper around
|
||||
@@ -26,7 +26,7 @@ BrowserWindow constructor options are set by, in increasing precedence
|
||||
order: options inherited from the parent, parsed options
|
||||
from the `features` string from `window.open()`, security-related webPreferences
|
||||
inherited from the parent, and options given by
|
||||
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandler-handler).
|
||||
[`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandlerhandler).
|
||||
Note that `webContents.setWindowOpenHandler` has final say and full privilege
|
||||
because it is invoked in the main process.
|
||||
|
||||
|
||||
@@ -6,14 +6,36 @@ Breaking changes will be documented here, and deprecation warnings added to JS c
|
||||
|
||||
This document uses the following convention to categorize breaking changes:
|
||||
|
||||
- **API Changed:** An API was changed in such a way that code that has not been updated is guaranteed to throw an exception.
|
||||
- **Behavior Changed:** The behavior of Electron has changed, but not in such a way that an exception will necessarily be thrown.
|
||||
- **Default Changed:** Code depending on the old default may break, not necessarily throwing an exception. The old behavior can be restored by explicitly specifying the value.
|
||||
- **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
|
||||
- **Removed:** An API or feature was removed, and is no longer supported by Electron.
|
||||
* **API Changed:** An API was changed in such a way that code that has not been updated is guaranteed to throw an exception.
|
||||
* **Behavior Changed:** The behavior of Electron has changed, but not in such a way that an exception will necessarily be thrown.
|
||||
* **Default Changed:** Code depending on the old default may break, not necessarily throwing an exception. The old behavior can be restored by explicitly specifying the value.
|
||||
* **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
|
||||
* **Removed:** An API or feature was removed, and is no longer supported by Electron.
|
||||
|
||||
## Planned Breaking API Changes (13.0)
|
||||
|
||||
### API Changed: `session.setPermissionCheckHandler(handler)`
|
||||
|
||||
The `handler` methods first parameter was previously always a `webContents`, it can now sometimes be `null`. You should use the `requestingOrigin`, `embeddingOrigin` and `securityOrigin` properties to respond to the permission check correctly. As the `webContents` can be `null` it can no longer be relied on.
|
||||
|
||||
```js
|
||||
// Old code
|
||||
session.setPermissionCheckHandler((webContents, permission) => {
|
||||
if (webContents.getURL().startsWith('https://google.com/') && permission === 'notification') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// Replace with
|
||||
session.setPermissionCheckHandler((webContents, permission, requestingOrigin) => {
|
||||
if (new URL(requestingOrigin).hostname === 'google.com' && permission === 'notification') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
```
|
||||
|
||||
### Removed: `shell.moveItemToTrash()`
|
||||
|
||||
The deprecated synchronous `shell.moveItemToTrash()` API has been removed. Use
|
||||
@@ -26,6 +48,76 @@ shell.moveItemToTrash(path)
|
||||
shell.trashItem(path).then(/* ... */)
|
||||
```
|
||||
|
||||
### Removed: `BrowserWindow` extension APIs
|
||||
|
||||
The deprecated extension APIs have been removed:
|
||||
|
||||
* `BrowserWindow.addExtension(path)`
|
||||
* `BrowserWindow.addDevToolsExtension(path)`
|
||||
* `BrowserWindow.removeExtension(name)`
|
||||
* `BrowserWindow.removeDevToolsExtension(name)`
|
||||
* `BrowserWindow.getExtensions()`
|
||||
* `BrowserWindow.getDevToolsExtensions()`
|
||||
|
||||
Use the session APIs instead:
|
||||
|
||||
* `ses.loadExtension(path)`
|
||||
* `ses.removeExtension(extension_id)`
|
||||
* `ses.getAllExtensions()`
|
||||
|
||||
```js
|
||||
// Removed in Electron 13
|
||||
BrowserWindow.addExtension(path)
|
||||
BrowserWindow.addDevToolsExtension(path)
|
||||
// Replace with
|
||||
session.defaultSession.loadExtension(path)
|
||||
```
|
||||
|
||||
```js
|
||||
// Removed in Electron 13
|
||||
BrowserWindow.removeExtension(name)
|
||||
BrowserWindow.removeDevToolsExtension(name)
|
||||
// Replace with
|
||||
session.defaultSession.removeExtension(extension_id)
|
||||
```
|
||||
|
||||
```js
|
||||
// Removed in Electron 13
|
||||
BrowserWindow.getExtensions()
|
||||
BrowserWindow.getDevToolsExtensions()
|
||||
// Replace with
|
||||
session.defaultSession.getAllExtensions()
|
||||
```
|
||||
|
||||
### Removed: methods in `systemPreferences`
|
||||
|
||||
The following `systemPreferences` methods have been deprecated:
|
||||
* `systemPreferences.isDarkMode()`
|
||||
* `systemPreferences.isInvertedColorScheme()`
|
||||
* `systemPreferences.isHighContrastColorScheme()`
|
||||
|
||||
Use the following `nativeTheme` properties instead:
|
||||
* `nativeTheme.shouldUseDarkColors`
|
||||
* `nativeTheme.shouldUseInvertedColorScheme`
|
||||
* `nativeTheme.shouldUseHighContrastColors`
|
||||
|
||||
```js
|
||||
// Removed in Electron 13
|
||||
systemPreferences.isDarkMode()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseDarkColors
|
||||
|
||||
// Removed in Electron 13
|
||||
systemPreferences.isInvertedColorScheme()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseInvertedColorScheme
|
||||
|
||||
// Removed in Electron 13
|
||||
systemPreferences.isHighContrastColorScheme()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseHighContrastColors
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (12.0)
|
||||
|
||||
### Removed: Pepper Flash support
|
||||
@@ -43,17 +135,29 @@ We [recommend having contextIsolation enabled](https://github.com/electron/elect
|
||||
|
||||
For more details see: https://github.com/electron/electron/issues/23506
|
||||
|
||||
### Removed: `crashReporter.getCrashesDirectory()`
|
||||
|
||||
The `crashReporter.getCrashesDirectory` method has been removed. Usage
|
||||
should be replaced by `app.getPath('crashDumps')`.
|
||||
|
||||
```js
|
||||
// Removed in Electron 12
|
||||
crashReporter.getCrashesDirectory()
|
||||
// Replace with
|
||||
app.getPath('crashDumps')
|
||||
```
|
||||
|
||||
### Removed: `crashReporter` methods in the renderer process
|
||||
|
||||
The following `crashReporter` methods are no longer available in the renderer
|
||||
process:
|
||||
|
||||
- `crashReporter.start`
|
||||
- `crashReporter.getLastCrashReport`
|
||||
- `crashReporter.getUploadedReports`
|
||||
- `crashReporter.getUploadToServer`
|
||||
- `crashReporter.setUploadToServer`
|
||||
- `crashReporter.getCrashesDirectory`
|
||||
* `crashReporter.start`
|
||||
* `crashReporter.getLastCrashReport`
|
||||
* `crashReporter.getUploadedReports`
|
||||
* `crashReporter.getUploadToServer`
|
||||
* `crashReporter.setUploadToServer`
|
||||
* `crashReporter.getCrashesDirectory`
|
||||
|
||||
They should be called only from the main process.
|
||||
|
||||
@@ -104,6 +208,7 @@ shell.trashItem(path).then(/* ... */)
|
||||
## Planned Breaking API Changes (11.0)
|
||||
|
||||
### Removed: `BrowserView.{destroy, fromId, fromWebContents, getAllViews}` and `id` property of `BrowserView`
|
||||
|
||||
The experimental APIs `BrowserView.{destroy, fromId, fromWebContents, getAllViews}`
|
||||
have now been removed. Additionally, the `id` property of `BrowserView`
|
||||
has also been removed.
|
||||
@@ -143,12 +248,12 @@ app.getPath('crashDumps')
|
||||
Calling the following `crashReporter` methods from the renderer process is
|
||||
deprecated:
|
||||
|
||||
- `crashReporter.start`
|
||||
- `crashReporter.getLastCrashReport`
|
||||
- `crashReporter.getUploadedReports`
|
||||
- `crashReporter.getUploadToServer`
|
||||
- `crashReporter.setUploadToServer`
|
||||
- `crashReporter.getCrashesDirectory`
|
||||
* `crashReporter.start`
|
||||
* `crashReporter.getLastCrashReport`
|
||||
* `crashReporter.getUploadedReports`
|
||||
* `crashReporter.getUploadToServer`
|
||||
* `crashReporter.setUploadToServer`
|
||||
* `crashReporter.getCrashesDirectory`
|
||||
|
||||
The only non-deprecated methods remaining in the `crashReporter` module in the
|
||||
renderer are `addExtraParameter`, `removeExtraParameter` and `getParameters`.
|
||||
@@ -190,6 +295,7 @@ We [recommend moving away from the remote
|
||||
module](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31).
|
||||
|
||||
### `protocol.unregisterProtocol`
|
||||
|
||||
### `protocol.uninterceptProtocol`
|
||||
|
||||
The APIs are now synchronous and the optional callback is no longer needed.
|
||||
@@ -202,14 +308,23 @@ protocol.unregisterProtocol(scheme)
|
||||
```
|
||||
|
||||
### `protocol.registerFileProtocol`
|
||||
|
||||
### `protocol.registerBufferProtocol`
|
||||
|
||||
### `protocol.registerStringProtocol`
|
||||
|
||||
### `protocol.registerHttpProtocol`
|
||||
|
||||
### `protocol.registerStreamProtocol`
|
||||
|
||||
### `protocol.interceptFileProtocol`
|
||||
|
||||
### `protocol.interceptStringProtocol`
|
||||
|
||||
### `protocol.interceptBufferProtocol`
|
||||
|
||||
### `protocol.interceptHttpProtocol`
|
||||
|
||||
### `protocol.interceptStreamProtocol`
|
||||
|
||||
The APIs are now synchronous and the optional callback is no longer needed.
|
||||
@@ -251,6 +366,47 @@ you should plan to update your native modules to be context aware.
|
||||
|
||||
For more detailed information see [#18397](https://github.com/electron/electron/issues/18397).
|
||||
|
||||
### Deprecated: `BrowserWindow` extension APIs
|
||||
|
||||
The following extension APIs have been deprecated:
|
||||
|
||||
* `BrowserWindow.addExtension(path)`
|
||||
* `BrowserWindow.addDevToolsExtension(path)`
|
||||
* `BrowserWindow.removeExtension(name)`
|
||||
* `BrowserWindow.removeDevToolsExtension(name)`
|
||||
* `BrowserWindow.getExtensions()`
|
||||
* `BrowserWindow.getDevToolsExtensions()`
|
||||
|
||||
Use the session APIs instead:
|
||||
|
||||
* `ses.loadExtension(path)`
|
||||
* `ses.removeExtension(extension_id)`
|
||||
* `ses.getAllExtensions()`
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 9
|
||||
BrowserWindow.addExtension(path)
|
||||
BrowserWindow.addDevToolsExtension(path)
|
||||
// Replace with
|
||||
session.defaultSession.loadExtension(path)
|
||||
```
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 9
|
||||
BrowserWindow.removeExtension(name)
|
||||
BrowserWindow.removeDevToolsExtension(name)
|
||||
// Replace with
|
||||
session.defaultSession.removeExtension(extension_id)
|
||||
```
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 9
|
||||
BrowserWindow.getExtensions()
|
||||
BrowserWindow.getDevToolsExtensions()
|
||||
// Replace with
|
||||
session.defaultSession.getAllExtensions()
|
||||
```
|
||||
|
||||
### Removed: `<webview>.getWebContents()`
|
||||
|
||||
This API, which was deprecated in Electron 8.0, is now removed.
|
||||
@@ -303,7 +459,7 @@ Clone Algorithm][SCA], the same algorithm used to serialize messages for
|
||||
`postMessage`. This brings about a 2x performance improvement for large
|
||||
messages, but also brings some breaking changes in behavior.
|
||||
|
||||
- Sending Functions, Promises, WeakMaps, WeakSets, or objects containing any
|
||||
* Sending Functions, Promises, WeakMaps, WeakSets, or objects containing any
|
||||
such values, over IPC will now throw an exception, instead of silently
|
||||
converting the functions to `undefined`.
|
||||
|
||||
@@ -317,21 +473,21 @@ ipcRenderer.send('channel', { value: 3, someFunction: () => {} })
|
||||
// => throws Error("() => {} could not be cloned.")
|
||||
```
|
||||
|
||||
- `NaN`, `Infinity` and `-Infinity` will now be correctly serialized, instead
|
||||
* `NaN`, `Infinity` and `-Infinity` will now be correctly serialized, instead
|
||||
of being converted to `null`.
|
||||
- Objects containing cyclic references will now be correctly serialized,
|
||||
* Objects containing cyclic references will now be correctly serialized,
|
||||
instead of being converted to `null`.
|
||||
- `Set`, `Map`, `Error` and `RegExp` values will be correctly serialized,
|
||||
* `Set`, `Map`, `Error` and `RegExp` values will be correctly serialized,
|
||||
instead of being converted to `{}`.
|
||||
- `BigInt` values will be correctly serialized, instead of being converted to
|
||||
* `BigInt` values will be correctly serialized, instead of being converted to
|
||||
`null`.
|
||||
- Sparse arrays will be serialized as such, instead of being converted to dense
|
||||
* Sparse arrays will be serialized as such, instead of being converted to dense
|
||||
arrays with `null`s.
|
||||
- `Date` objects will be transferred as `Date` objects, instead of being
|
||||
* `Date` objects will be transferred as `Date` objects, instead of being
|
||||
converted to their ISO string representation.
|
||||
- Typed Arrays (such as `Uint8Array`, `Uint16Array`, `Uint32Array` and so on)
|
||||
* Typed Arrays (such as `Uint8Array`, `Uint16Array`, `Uint32Array` and so on)
|
||||
will be transferred as such, instead of being converted to Node.js `Buffer`.
|
||||
- Node.js `Buffer` objects will be transferred as `Uint8Array`s. You can
|
||||
* Node.js `Buffer` objects will be transferred as `Uint8Array`s. You can
|
||||
convert a `Uint8Array` back to a Node.js `Buffer` by wrapping the underlying
|
||||
`ArrayBuffer`:
|
||||
|
||||
@@ -397,6 +553,52 @@ in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level
|
||||
limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
|
||||
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
|
||||
|
||||
### Deprecated events in `systemPreferences`
|
||||
|
||||
The following `systemPreferences` events have been deprecated:
|
||||
* `inverted-color-scheme-changed`
|
||||
* `high-contrast-color-scheme-changed`
|
||||
|
||||
Use the new `updated` event on the `nativeTheme` module instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ })
|
||||
systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
|
||||
|
||||
// Replace with
|
||||
nativeTheme.on('updated', () => { /* ... */ })
|
||||
```
|
||||
|
||||
### Deprecated: methods in `systemPreferences`
|
||||
|
||||
The following `systemPreferences` methods have been deprecated:
|
||||
* `systemPreferences.isDarkMode()`
|
||||
* `systemPreferences.isInvertedColorScheme()`
|
||||
* `systemPreferences.isHighContrastColorScheme()`
|
||||
|
||||
Use the following `nativeTheme` properties instead:
|
||||
* `nativeTheme.shouldUseDarkColors`
|
||||
* `nativeTheme.shouldUseInvertedColorScheme`
|
||||
* `nativeTheme.shouldUseHighContrastColors`
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
systemPreferences.isDarkMode()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseDarkColors
|
||||
|
||||
// Deprecated
|
||||
systemPreferences.isInvertedColorScheme()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseInvertedColorScheme
|
||||
|
||||
// Deprecated
|
||||
systemPreferences.isHighContrastColorScheme()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseHighContrastColors
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (7.0)
|
||||
|
||||
### Deprecated: Atom.io Node Headers URL
|
||||
|
||||
@@ -86,8 +86,6 @@ $ gclient sync -f
|
||||
```sh
|
||||
$ cd src
|
||||
$ export CHROMIUM_BUILDTOOLS_PATH=`pwd`/buildtools
|
||||
# this next line is needed only if building with sccache
|
||||
$ export GN_EXTRA_ARGS="${GN_EXTRA_ARGS} cc_wrapper=\"${PWD}/electron/external_binaries/sccache\""
|
||||
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") $GN_EXTRA_ARGS"
|
||||
```
|
||||
|
||||
@@ -141,12 +139,6 @@ This will build all of what was previously 'libchromiumcontent' (i.e. the
|
||||
`content/` directory of `chromium` and its dependencies, incl. WebKit and V8),
|
||||
so it will take a while.
|
||||
|
||||
To speed up subsequent builds, you can use [sccache][sccache]. Add the GN arg
|
||||
`cc_wrapper = "sccache"` by running `gn args out/Testing` to bring up an
|
||||
editor and adding a line to the end of the file.
|
||||
|
||||
[sccache]: https://github.com/mozilla/sccache
|
||||
|
||||
The built executable will be under `./out/Testing`:
|
||||
|
||||
```sh
|
||||
@@ -189,7 +181,6 @@ Not all combinations of source and target CPU/OS are supported by Chromium.
|
||||
| Windows x64 | Windows x86 | Automatically tested |
|
||||
| Linux x64 | Linux x86 | Automatically tested |
|
||||
|
||||
|
||||
If you test other combinations and find them to work, please update this document :)
|
||||
|
||||
See the GN reference for allowable values of [`target_os`][target_os values]
|
||||
|
||||
@@ -66,11 +66,11 @@ formatted correctly.
|
||||
|
||||
Electron APIs uses the same capitalization scheme as Node.js:
|
||||
|
||||
- When the module itself is a class like `BrowserWindow`, use `PascalCase`.
|
||||
- When the module is a set of APIs, like `globalShortcut`, use `camelCase`.
|
||||
- When the API is a property of object, and it is complex enough to be in a
|
||||
* When the module itself is a class like `BrowserWindow`, use `PascalCase`.
|
||||
* When the module is a set of APIs, like `globalShortcut`, use `camelCase`.
|
||||
* When the API is a property of object, and it is complex enough to be in a
|
||||
separate chapter like `win.webContents`, use `mixedCase`.
|
||||
- For other non-module APIs, use natural titles, like `<webview> Tag` or
|
||||
* For other non-module APIs, use natural titles, like `<webview> Tag` or
|
||||
`Process Object`.
|
||||
|
||||
When creating a new API, it is preferred to use getters and setters instead of
|
||||
|
||||
@@ -36,9 +36,9 @@ $ git fetch upstream
|
||||
Build steps and dependencies differ slightly depending on your operating system.
|
||||
See these detailed guides on building Electron locally:
|
||||
|
||||
* [Building on macOS](https://electronjs.org/docs/development/build-instructions-macos)
|
||||
* [Building on Linux](https://electronjs.org/docs/development/build-instructions-linux)
|
||||
* [Building on Windows](https://electronjs.org/docs/development/build-instructions-windows)
|
||||
* [Building on macOS](build-instructions-macos.md)
|
||||
* [Building on Linux](build-instructions-linux.md)
|
||||
* [Building on Windows](build-instructions-windows.md)
|
||||
|
||||
Once you've built the project locally, you're ready to start making changes!
|
||||
|
||||
@@ -63,7 +63,7 @@ or tests in the `spec/` folder.
|
||||
Please be sure to run `npm run lint` from time to time on any code changes
|
||||
to ensure that they follow the project's code style.
|
||||
|
||||
See [coding style](https://electronjs.org/docs/development/coding-style) for
|
||||
See [coding style](coding-style.md) for
|
||||
more information about best practice when modifying code in different parts of
|
||||
the project.
|
||||
|
||||
@@ -91,29 +91,29 @@ Before a pull request can be merged, it **must** have a pull request title with
|
||||
|
||||
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`
|
||||
* `fix: don't overwrite prevent_default if default wasn't prevented`
|
||||
* `feat: add app.isPackaged() method`
|
||||
* `docs: app.isDefaultProtocolClient is now available on Linux`
|
||||
|
||||
Common prefixes:
|
||||
|
||||
- fix: A bug fix
|
||||
- feat: A new feature
|
||||
- docs: Documentation changes
|
||||
- test: Adding missing tests or correcting existing tests
|
||||
- build: Changes that affect the build system
|
||||
- ci: Changes to our CI configuration files and scripts
|
||||
- perf: A code change that improves performance
|
||||
- refactor: A code change that neither fixes a bug nor adds a feature
|
||||
- style: Changes that do not affect the meaning of the code (linting)
|
||||
- vendor: Bumping a dependency like libchromiumcontent or node
|
||||
* fix: A bug fix
|
||||
* feat: A new feature
|
||||
* docs: Documentation changes
|
||||
* test: Adding missing tests or correcting existing tests
|
||||
* build: Changes that affect the build system
|
||||
* ci: Changes to our CI configuration files and scripts
|
||||
* perf: A code change that improves performance
|
||||
* refactor: A code change that neither fixes a bug nor adds a feature
|
||||
* style: Changes that do not affect the meaning of the code (linting)
|
||||
* vendor: Bumping a dependency like libchromiumcontent or node
|
||||
|
||||
Other things to keep in mind when writing a commit message:
|
||||
|
||||
1. The first line should:
|
||||
- contain a short description of the change (preferably 50 characters or less,
|
||||
* contain a short description of the change (preferably 50 characters or less,
|
||||
and no more than 72 characters)
|
||||
- be entirely in lowercase with the exception of proper nouns, acronyms, and
|
||||
* be entirely in lowercase with the exception of proper nouns, acronyms, and
|
||||
the words that refer to code, like function/variable names
|
||||
2. Keep the second line blank.
|
||||
3. Wrap all other lines at 72 columns.
|
||||
@@ -144,7 +144,7 @@ master.
|
||||
### Step 7: Test
|
||||
|
||||
Bug fixes and features should always come with tests. A
|
||||
[testing guide](https://electronjs.org/docs/development/testing) has been
|
||||
[testing guide](testing.md) has been
|
||||
provided to make the process easier. Looking at other tests to see how they
|
||||
should be structured can also help.
|
||||
|
||||
|
||||
18
docs/fiddles/features/drag-and-drop/index.html
Normal file
18
docs/fiddles/features/drag-and-drop/index.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<a href="#" id="drag">Drag me</a>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
41
docs/fiddles/features/drag-and-drop/main.js
Normal file
41
docs/fiddles/features/drag-and-drop/main.js
Normal file
@@ -0,0 +1,41 @@
|
||||
const { app, BrowserWindow, ipcMain, nativeImage, NativeImage } = require('electron')
|
||||
const fs = require('fs');
|
||||
const http = require('http');
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
const iconName = 'iconForDragAndDrop.png';
|
||||
const icon = fs.createWriteStream(`${process.cwd()}/${iconName}`);
|
||||
http.get('http://img.icons8.com/ios/452/drag-and-drop.png', (response) => {
|
||||
response.pipe(icon);
|
||||
});
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
ipcMain.on('ondragstart', (event, filePath) => {
|
||||
event.sender.startDrag({
|
||||
file: filePath,
|
||||
icon: `${process.cwd()}/${iconName}`
|
||||
})
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
9
docs/fiddles/features/drag-and-drop/renderer.js
Normal file
9
docs/fiddles/features/drag-and-drop/renderer.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
const fs = require('fs')
|
||||
|
||||
document.getElementById('drag').ondragstart = (event) => {
|
||||
const fileName = 'drag-and-drop.md'
|
||||
fs.writeFileSync(fileName, '# Test drag and drop');
|
||||
event.preventDefault()
|
||||
ipcRenderer.send('ondragstart', process.cwd() + `/${fileName}`)
|
||||
}
|
||||
16
docs/fiddles/features/keyboard-shortcuts/global/index.html
Normal file
16
docs/fiddles/features/keyboard-shortcuts/global/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
31
docs/fiddles/features/keyboard-shortcuts/global/main.js
Normal file
31
docs/fiddles/features/keyboard-shortcuts/global/main.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const { app, BrowserWindow, globalShortcut } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
globalShortcut.register('Alt+CommandOrControl+I', () => {
|
||||
console.log('Electron loves global shortcuts!')
|
||||
})
|
||||
}).then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } })
|
||||
|
||||
win.loadFile('index.html')
|
||||
win.webContents.on('before-input-event', (event, input) => {
|
||||
if (input.control && input.key.toLowerCase() === 'i') {
|
||||
console.log('Pressed Control+I')
|
||||
event.preventDefault()
|
||||
}
|
||||
})
|
||||
})
|
||||
16
docs/fiddles/features/keyboard-shortcuts/local/index.html
Normal file
16
docs/fiddles/features/keyboard-shortcuts/local/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
39
docs/fiddles/features/keyboard-shortcuts/local/main.js
Normal file
39
docs/fiddles/features/keyboard-shortcuts/local/main.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const { app, BrowserWindow, Menu, MenuItem } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({
|
||||
label: 'Electron',
|
||||
submenu: [{
|
||||
role: 'help',
|
||||
accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I',
|
||||
click: () => { console.log('Electron rocks!') }
|
||||
}]
|
||||
}))
|
||||
|
||||
Menu.setApplicationMenu(menu)
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
19
docs/fiddles/features/macos-dark-mode/index.html
Normal file
19
docs/fiddles/features/macos-dark-mode/index.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
<link rel="stylesheet" type="text/css" href="./styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>Current theme source: <strong id="theme-source">System</strong></p>
|
||||
|
||||
<button id="toggle-dark-mode">Toggle Dark Mode</button>
|
||||
<button id="reset-to-system">Reset to System Theme</button>
|
||||
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
40
docs/fiddles/features/macos-dark-mode/main.js
Normal file
40
docs/fiddles/features/macos-dark-mode/main.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
|
||||
ipcMain.handle('dark-mode:toggle', () => {
|
||||
if (nativeTheme.shouldUseDarkColors) {
|
||||
nativeTheme.themeSource = 'light'
|
||||
} else {
|
||||
nativeTheme.themeSource = 'dark'
|
||||
}
|
||||
return nativeTheme.shouldUseDarkColors
|
||||
})
|
||||
|
||||
ipcMain.handle('dark-mode:system', () => {
|
||||
nativeTheme.themeSouce = 'system'
|
||||
})
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
11
docs/fiddles/features/macos-dark-mode/renderer.js
Normal file
11
docs/fiddles/features/macos-dark-mode/renderer.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
document.getElementById('toggle-dark-mode').addEventListener('click', async () => {
|
||||
const isDarkMode = await ipcRenderer.invoke('dark-mode:toggle')
|
||||
document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'
|
||||
})
|
||||
|
||||
document.getElementById('reset-to-system').addEventListener('click', async () => {
|
||||
await ipcRenderer.invoke('dark-mode:system')
|
||||
document.getElementById('theme-source').innerHTML = 'System'
|
||||
})
|
||||
7
docs/fiddles/features/macos-dark-mode/styles.css
Normal file
7
docs/fiddles/features/macos-dark-mode/styles.css
Normal file
@@ -0,0 +1,7 @@
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body { background: #333; color: white; }
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
body { background: #ddd; color: black; }
|
||||
}
|
||||
16
docs/fiddles/features/macos-dock-menu/index.html
Normal file
16
docs/fiddles/features/macos-dock-menu/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
43
docs/fiddles/features/macos-dock-menu/main.js
Normal file
43
docs/fiddles/features/macos-dock-menu/main.js
Normal file
@@ -0,0 +1,43 @@
|
||||
const { app, BrowserWindow, Menu } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
const dockMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: 'New Window',
|
||||
click () { console.log('New Window') }
|
||||
}, {
|
||||
label: 'New Window with Settings',
|
||||
submenu: [
|
||||
{ label: 'Basic' },
|
||||
{ label: 'Pro' }
|
||||
]
|
||||
},
|
||||
{ label: 'New Command...' }
|
||||
])
|
||||
|
||||
app.whenReady().then(() => {
|
||||
app.dock.setMenu(dockMenu)
|
||||
}).then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
16
docs/fiddles/features/notifications/main/index.html
Normal file
16
docs/fiddles/features/notifications/main/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
35
docs/fiddles/features/notifications/main/main.js
Normal file
35
docs/fiddles/features/notifications/main/main.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const { app, BrowserWindow, Notification } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
function showNotification () {
|
||||
const notification = {
|
||||
title: 'Basic Notification',
|
||||
body: 'Notification from the Main process'
|
||||
}
|
||||
new Notification(notification).show()
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow).then(showNotification)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
17
docs/fiddles/features/notifications/renderer/index.html
Normal file
17
docs/fiddles/features/notifications/renderer/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
27
docs/fiddles/features/notifications/renderer/main.js
Normal file
27
docs/fiddles/features/notifications/renderer/main.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
7
docs/fiddles/features/notifications/renderer/renderer.js
Normal file
7
docs/fiddles/features/notifications/renderer/renderer.js
Normal file
@@ -0,0 +1,7 @@
|
||||
const myNotification = new Notification('Title', {
|
||||
body: 'Notification from the Renderer process'
|
||||
})
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
15
docs/fiddles/features/offscreen-rendering/index.html
Normal file
15
docs/fiddles/features/offscreen-rendering/index.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
28
docs/fiddles/features/offscreen-rendering/main.js
Normal file
28
docs/fiddles/features/offscreen-rendering/main.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const fs = require('fs')
|
||||
|
||||
app.disableHardwareAcceleration()
|
||||
|
||||
let win
|
||||
|
||||
app.whenReady().then(() => {
|
||||
win = new BrowserWindow({ webPreferences: { offscreen: true } })
|
||||
win.loadURL('https://github.com')
|
||||
win.webContents.on('paint', (event, dirty, image) => {
|
||||
fs.writeFileSync('ex.png', image.toPNG())
|
||||
})
|
||||
win.webContents.setFrameRate(60)
|
||||
console.log(`The screenshot has been successfully saved to ${process.cwd()}/ex.png`)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
17
docs/fiddles/features/online-detection/main/index.html
Normal file
17
docs/fiddles/features/online-detection/main/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
24
docs/fiddles/features/online-detection/main/main.js
Normal file
24
docs/fiddles/features/online-detection/main/main.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
let onlineStatusWindow
|
||||
|
||||
app.whenReady().then(() => {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false, webPreferences: { nodeIntegration: true } })
|
||||
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
|
||||
})
|
||||
|
||||
ipcMain.on('online-status-changed', (event, status) => {
|
||||
console.log(status)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
7
docs/fiddles/features/online-detection/main/renderer.js
Normal file
7
docs/fiddles/features/online-detection/main/renderer.js
Normal file
@@ -0,0 +1,7 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
const updateOnlineStatus = () => { ipcRenderer.send('online-status-changed', navigator.onLine ? 'online' : 'offline') }
|
||||
|
||||
window.addEventListener('online', updateOnlineStatus)
|
||||
window.addEventListener('offline', updateOnlineStatus)
|
||||
|
||||
updateOnlineStatus()
|
||||
17
docs/fiddles/features/online-detection/renderer/index.html
Normal file
17
docs/fiddles/features/online-detection/renderer/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
20
docs/fiddles/features/online-detection/renderer/main.js
Normal file
20
docs/fiddles/features/online-detection/renderer/main.js
Normal file
@@ -0,0 +1,20 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let onlineStatusWindow
|
||||
|
||||
app.whenReady().then(() => {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false })
|
||||
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,6 @@
|
||||
const alertOnlineStatus = () => { window.alert(navigator.onLine ? 'online' : 'offline') }
|
||||
|
||||
window.addEventListener('online', alertOnlineStatus)
|
||||
window.addEventListener('offline', alertOnlineStatus)
|
||||
|
||||
alertOnlineStatus()
|
||||
16
docs/fiddles/features/progress-bar/index.html
Normal file
16
docs/fiddles/features/progress-bar/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
30
docs/fiddles/features/progress-bar/main.js
Normal file
30
docs/fiddles/features/progress-bar/main.js
Normal file
@@ -0,0 +1,30 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
win.setProgressBar(0.5)
|
||||
}
|
||||
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
16
docs/fiddles/features/recent-documents/index.html
Normal file
16
docs/fiddles/features/recent-documents/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
34
docs/fiddles/features/recent-documents/main.js
Normal file
34
docs/fiddles/features/recent-documents/main.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
const fileName = 'recently-used.md'
|
||||
fs.writeFile(fileName, 'Lorem Ipsum', () => {
|
||||
app.addRecentDocument(path.join(process.cwd(), `${fileName}`))
|
||||
})
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
app.clearRecentDocuments()
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
16
docs/fiddles/features/represented-file/index.html
Normal file
16
docs/fiddles/features/represented-file/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
33
docs/fiddles/features/represented-file/main.js
Normal file
33
docs/fiddles/features/represented-file/main.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const os = require('os');
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow()
|
||||
|
||||
win.setRepresentedFilename(os.homedir())
|
||||
win.setDocumentEdited(true)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
16
docs/fiddles/quick-start/index.html
Normal file
16
docs/fiddles/quick-start/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
27
docs/fiddles/quick-start/main.js
Normal file
27
docs/fiddles/quick-start/main.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -49,6 +49,7 @@ For API references, there are exceptions to this rule.
|
||||
* No nesting lists more than 2 levels (due to the markdown renderer).
|
||||
* All `js` and `javascript` code blocks are linted with
|
||||
[standard-markdown](https://www.npmjs.com/package/standard-markdown).
|
||||
* For unordered lists, use asterisks instead of dashes
|
||||
|
||||
## Picking words
|
||||
|
||||
|
||||
@@ -43,6 +43,6 @@ If the V8 context crashes, the DevTools will display this message.
|
||||
|
||||
`DevTools was disconnected from the page. Once page is reloaded, DevTools will automatically reconnect.`
|
||||
|
||||
Chromium logs can be enabled via the `ELECTRON_ENABLE_LOGGING` environment variable. For more information, see the [environment variables documentation](https://www.electronjs.org/docs/api/environment-variables#electron_enable_logging).
|
||||
Chromium logs can be enabled via the `ELECTRON_ENABLE_LOGGING` environment variable. For more information, see the [environment variables documentation](../api/environment-variables.md#electron_enable_logging).
|
||||
|
||||
Alternatively, the command line argument `--enable-logging` can be passed. More information is available in the [command line switches documentation](https://www.electronjs.org/docs/api/command-line-switches#--enable-logging).
|
||||
Alternatively, the command line argument `--enable-logging` can be passed. More information is available in the [command line switches documentation](../api/command-line-switches.md#--enable-logging).
|
||||
|
||||
@@ -1,25 +1,38 @@
|
||||
# Application Distribution
|
||||
|
||||
To distribute your app with Electron, you need to package and rebrand it. The easiest way to do this is to use one of the following third party packaging tools:
|
||||
## Overview
|
||||
|
||||
To distribute your app with Electron, you need to package and rebrand it.
|
||||
To do this, you can either use specialized tooling or manual approaches.
|
||||
|
||||
## With tooling
|
||||
|
||||
You can use the following tools to distribute your application:
|
||||
|
||||
* [electron-forge](https://github.com/electron-userland/electron-forge)
|
||||
* [electron-builder](https://github.com/electron-userland/electron-builder)
|
||||
* [electron-packager](https://github.com/electron/electron-packager)
|
||||
|
||||
These tools will take care of all the steps you need to take to end up with a distributable Electron applications, such as packaging your application, rebranding the executable, setting the right icons and optionally creating installers.
|
||||
These tools will take care of all the steps you need to take to end up with a
|
||||
distributable Electron application, such as bundling your application,
|
||||
rebranding the executable, and setting the right icons.
|
||||
|
||||
You can check the example of how to package your app with `electron-forge` in
|
||||
our [Quick Start Guide](quick-start.md#package-and-distribute-the-application).
|
||||
|
||||
## Manual distribution
|
||||
|
||||
You can also choose to manually get your app ready for distribution. The steps needed to do this are outlined below.
|
||||
### With prebuilt binaries
|
||||
|
||||
To distribute your app with Electron, you need to download Electron's [prebuilt
|
||||
To distribute your app manually, you need to download Electron's [prebuilt
|
||||
binaries](https://github.com/electron/electron/releases). Next, the folder
|
||||
containing your app should be named `app` and placed in Electron's resources
|
||||
directory as shown in the following examples. Note that the location of
|
||||
Electron's prebuilt binaries is indicated with `electron/` in the examples
|
||||
below.
|
||||
directory as shown in the following examples.
|
||||
|
||||
On macOS:
|
||||
> *NOTE:* the location of Electron's prebuilt binaries is indicated
|
||||
with `electron/` in the examples below.
|
||||
|
||||
*On macOS:*
|
||||
|
||||
```plaintext
|
||||
electron/Electron.app/Contents/Resources/app/
|
||||
@@ -28,7 +41,7 @@ electron/Electron.app/Contents/Resources/app/
|
||||
└── index.html
|
||||
```
|
||||
|
||||
On Windows and Linux:
|
||||
*On Windows and Linux:*
|
||||
|
||||
```plaintext
|
||||
electron/resources/app
|
||||
@@ -37,47 +50,44 @@ electron/resources/app
|
||||
└── index.html
|
||||
```
|
||||
|
||||
Then execute `Electron.app` (or `electron` on Linux, `electron.exe` on Windows),
|
||||
and Electron will start as your app. The `electron` directory will then be
|
||||
your distribution to deliver to final users.
|
||||
Then execute `Electron.app` on macOS, `electron` on Linux, or `electron.exe`
|
||||
on Windows, and Electron will start as your app. The `electron` directory
|
||||
will then be your distribution to deliver to users.
|
||||
|
||||
## Packaging Your App into a File
|
||||
### With an app source code archive
|
||||
|
||||
Apart from shipping your app by copying all of its source files, you can also
|
||||
package your app into an [asar](https://github.com/electron/asar) archive to avoid
|
||||
exposing your app's source code to users.
|
||||
Instead of from shipping your app by copying all of its source files, you can
|
||||
package your app into an [asar] archive to improve the performance of reading
|
||||
files on platforms like Windows, if you are not already using a bundler such
|
||||
as Parcel or Webpack.
|
||||
|
||||
To use an `asar` archive to replace the `app` folder, you need to rename the
|
||||
archive to `app.asar`, and put it under Electron's resources directory like
|
||||
below, and Electron will then try to read the archive and start from it.
|
||||
|
||||
On macOS:
|
||||
*On macOS:*
|
||||
|
||||
```plaintext
|
||||
electron/Electron.app/Contents/Resources/
|
||||
└── app.asar
|
||||
```
|
||||
|
||||
On Windows and Linux:
|
||||
*On Windows and Linux:*
|
||||
|
||||
```plaintext
|
||||
electron/resources/
|
||||
└── app.asar
|
||||
```
|
||||
|
||||
More details can be found in [Application packaging](application-packaging.md).
|
||||
You can find more details on how to use `asar` in the
|
||||
[`electron/asar` repository][asar].
|
||||
|
||||
## Rebranding with Downloaded Binaries
|
||||
### Rebranding with downloaded binaries
|
||||
|
||||
After bundling your app into Electron, you will want to rebrand Electron
|
||||
before distributing it to users.
|
||||
|
||||
### Windows
|
||||
|
||||
You can rename `electron.exe` to any name you like, and edit its icon and other
|
||||
information with tools like [rcedit](https://github.com/electron/rcedit).
|
||||
|
||||
### macOS
|
||||
#### macOS
|
||||
|
||||
You can rename `Electron.app` to any name you want, and you also have to rename
|
||||
the `CFBundleDisplayName`, `CFBundleIdentifier` and `CFBundleName` fields in the
|
||||
@@ -104,60 +114,20 @@ MyApp.app/Contents
|
||||
└── MyApp Helper
|
||||
```
|
||||
|
||||
### Linux
|
||||
#### Windows
|
||||
|
||||
You can rename `electron.exe` to any name you like, and edit its icon and other
|
||||
information with tools like [rcedit](https://github.com/electron/rcedit).
|
||||
|
||||
#### Linux
|
||||
|
||||
You can rename the `electron` executable to any name you like.
|
||||
|
||||
## Rebranding by Rebuilding Electron from Source
|
||||
### Rebranding by rebuilding Electron from source
|
||||
|
||||
It is also possible to rebrand Electron by changing the product name and
|
||||
building it from source. To do this you need to set the build argument
|
||||
corresponding to the product name (`electron_product_name = "YourProductName"`)
|
||||
in the `args.gn` file and rebuild.
|
||||
|
||||
### Creating a Custom Electron Fork
|
||||
|
||||
Creating a custom fork of Electron is almost certainly not something you will
|
||||
need to do in order to build your app, even for "Production Level" applications.
|
||||
Using a tool such as `electron-packager` or `electron-forge` will allow you to
|
||||
"Rebrand" Electron without having to do these steps.
|
||||
|
||||
You need to fork Electron when you have custom C++ code that you have patched
|
||||
directly into Electron, that either cannot be upstreamed, or has been rejected
|
||||
from the official version. As maintainers of Electron, we very much would like
|
||||
to make your scenario work, so please try as hard as you can to get your changes
|
||||
into the official version of Electron, it will be much much easier on you, and
|
||||
we appreciate your help.
|
||||
|
||||
#### Creating a Custom Release with surf-build
|
||||
|
||||
1. Install [Surf](https://github.com/surf-build/surf), via npm:
|
||||
`npm install -g surf-build@latest`
|
||||
|
||||
2. Create a new S3 bucket and create the following empty directory structure:
|
||||
|
||||
```sh
|
||||
- electron/
|
||||
- symbols/
|
||||
- dist/
|
||||
```
|
||||
|
||||
3. Set the following Environment Variables:
|
||||
|
||||
* `ELECTRON_GITHUB_TOKEN` - a token that can create releases on GitHub
|
||||
* `ELECTRON_S3_ACCESS_KEY`, `ELECTRON_S3_BUCKET`, `ELECTRON_S3_SECRET_KEY` -
|
||||
the place where you'll upload Node.js headers as well as symbols
|
||||
* `ELECTRON_RELEASE` - Set to `true` and the upload part will run, leave unset
|
||||
and `surf-build` will do CI-type checks, appropriate to run for every
|
||||
pull request.
|
||||
* `CI` - Set to `true` or else it will fail
|
||||
* `GITHUB_TOKEN` - set it to the same as `ELECTRON_GITHUB_TOKEN`
|
||||
* `SURF_TEMP` - set to `C:\Temp` on Windows to prevent path too long issues
|
||||
* `TARGET_ARCH` - set to `ia32` or `x64`
|
||||
|
||||
4. In `script/upload.py`, you _must_ set `ELECTRON_REPO` to your fork (`MYORG/electron`),
|
||||
especially if you are a contributor to Electron proper.
|
||||
|
||||
5. `surf-build -r https://github.com/MYORG/electron -s YOUR_COMMIT -n 'surf-PLATFORM-ARCH'`
|
||||
|
||||
6. Wait a very, very long time for the build to complete.
|
||||
[asar]: https://github.com/electron/asar
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
# Application Packaging
|
||||
|
||||
To mitigate [issues](https://github.com/joyent/node/issues/6960) around long
|
||||
path names on Windows, slightly speed up `require` and conceal your source code
|
||||
from cursory inspection, you can choose to package your app into an [asar][asar]
|
||||
archive with little changes to your source code.
|
||||
|
||||
Most users will get this feature for free, since it's supported out of the box
|
||||
by [`electron-packager`][electron-packager], [`electron-forge`][electron-forge],
|
||||
and [`electron-builder`][electron-builder]. If you are not using any of these
|
||||
tools, read on.
|
||||
|
||||
## Generating `asar` Archives
|
||||
|
||||
An [asar][asar] archive is a simple tar-like format that concatenates files
|
||||
into a single file. Electron can read arbitrary files from it without unpacking
|
||||
the whole file.
|
||||
|
||||
Steps to package your app into an `asar` archive:
|
||||
|
||||
### 1. Install the asar Utility
|
||||
|
||||
```sh
|
||||
$ npm install -g asar
|
||||
```
|
||||
|
||||
### 2. Package with `asar pack`
|
||||
|
||||
```sh
|
||||
$ asar pack your-app app.asar
|
||||
```
|
||||
|
||||
## Using `asar` Archives
|
||||
|
||||
In Electron there are two sets of APIs: Node APIs provided by Node.js and Web
|
||||
APIs provided by Chromium. Both APIs support reading files from `asar` archives.
|
||||
|
||||
### Node API
|
||||
|
||||
With special patches in Electron, Node APIs like `fs.readFile` and `require`
|
||||
treat `asar` archives as virtual directories, and the files in it as normal
|
||||
files in the filesystem.
|
||||
|
||||
For example, suppose we have an `example.asar` archive under `/path/to`:
|
||||
|
||||
```sh
|
||||
$ asar list /path/to/example.asar
|
||||
/app.js
|
||||
/file.txt
|
||||
/dir/module.js
|
||||
/static/index.html
|
||||
/static/main.css
|
||||
/static/jquery.min.js
|
||||
```
|
||||
|
||||
Read a file in the `asar` archive:
|
||||
|
||||
```javascript
|
||||
const fs = require('fs')
|
||||
fs.readFileSync('/path/to/example.asar/file.txt')
|
||||
```
|
||||
|
||||
List all files under the root of the archive:
|
||||
|
||||
```javascript
|
||||
const fs = require('fs')
|
||||
fs.readdirSync('/path/to/example.asar')
|
||||
```
|
||||
|
||||
Use a module from the archive:
|
||||
|
||||
```javascript
|
||||
require('./path/to/example.asar/dir/module.js')
|
||||
```
|
||||
|
||||
You can also display a web page in an `asar` archive with `BrowserWindow`:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
win.loadURL('file:///path/to/example.asar/static/index.html')
|
||||
```
|
||||
|
||||
### Web API
|
||||
|
||||
In a web page, files in an archive can be requested with the `file:` protocol.
|
||||
Like the Node API, `asar` archives are treated as directories.
|
||||
|
||||
For example, to get a file with `$.get`:
|
||||
|
||||
```html
|
||||
<script>
|
||||
let $ = require('./jquery.min.js')
|
||||
$.get('file:///path/to/example.asar/file.txt', (data) => {
|
||||
console.log(data)
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
### Treating an `asar` Archive as a Normal File
|
||||
|
||||
For some cases like verifying the `asar` archive's checksum, we need to read the
|
||||
content of an `asar` archive as a file. For this purpose you can use the built-in
|
||||
`original-fs` module which provides original `fs` APIs without `asar` support:
|
||||
|
||||
```javascript
|
||||
const originalFs = require('original-fs')
|
||||
originalFs.readFileSync('/path/to/example.asar')
|
||||
```
|
||||
|
||||
You can also set `process.noAsar` to `true` to disable the support for `asar` in
|
||||
the `fs` module:
|
||||
|
||||
```javascript
|
||||
const fs = require('fs')
|
||||
process.noAsar = true
|
||||
fs.readFileSync('/path/to/example.asar')
|
||||
```
|
||||
|
||||
## Limitations of the Node API
|
||||
|
||||
Even though we tried hard to make `asar` archives in the Node API work like
|
||||
directories as much as possible, there are still limitations due to the
|
||||
low-level nature of the Node API.
|
||||
|
||||
### Archives Are Read-only
|
||||
|
||||
The archives can not be modified so all Node APIs that can modify files will not
|
||||
work with `asar` archives.
|
||||
|
||||
### Working Directory Can Not Be Set to Directories in Archive
|
||||
|
||||
Though `asar` archives are treated as directories, there are no actual
|
||||
directories in the filesystem, so you can never set the working directory to
|
||||
directories in `asar` archives. Passing them as the `cwd` option of some APIs
|
||||
will also cause errors.
|
||||
|
||||
### Extra Unpacking on Some APIs
|
||||
|
||||
Most `fs` APIs can read a file or get a file's information from `asar` archives
|
||||
without unpacking, but for some APIs that rely on passing the real file path to
|
||||
underlying system calls, Electron will extract the needed file into a
|
||||
temporary file and pass the path of the temporary file to the APIs to make them
|
||||
work. This adds a little overhead for those APIs.
|
||||
|
||||
APIs that requires extra unpacking are:
|
||||
|
||||
* `child_process.execFile`
|
||||
* `child_process.execFileSync`
|
||||
* `fs.open`
|
||||
* `fs.openSync`
|
||||
* `process.dlopen` - Used by `require` on native modules
|
||||
|
||||
### Fake Stat Information of `fs.stat`
|
||||
|
||||
The `Stats` object returned by `fs.stat` and its friends on files in `asar`
|
||||
archives is generated by guessing, because those files do not exist on the
|
||||
filesystem. So you should not trust the `Stats` object except for getting file
|
||||
size and checking file type.
|
||||
|
||||
### Executing Binaries Inside `asar` Archive
|
||||
|
||||
There are Node APIs that can execute binaries like `child_process.exec`,
|
||||
`child_process.spawn` and `child_process.execFile`, but only `execFile` is
|
||||
supported to execute binaries inside `asar` archive.
|
||||
|
||||
This is because `exec` and `spawn` accept `command` instead of `file` as input,
|
||||
and `command`s are executed under shell. There is no reliable way to determine
|
||||
whether a command uses a file in asar archive, and even if we do, we can not be
|
||||
sure whether we can replace the path in command without side effects.
|
||||
|
||||
## Adding Unpacked Files to `asar` Archives
|
||||
|
||||
As stated above, some Node APIs will unpack the file to the filesystem when
|
||||
called. Apart from the performance issues, various anti-virus scanners might
|
||||
be triggered by this behavior.
|
||||
|
||||
As a workaround, you can leave various files unpacked using the `--unpack` option.
|
||||
In the following example, shared libraries of native Node.js modules will not be
|
||||
packed:
|
||||
|
||||
```sh
|
||||
$ asar pack app app.asar --unpack *.node
|
||||
```
|
||||
|
||||
After running the command, you will notice that a folder named `app.asar.unpacked`
|
||||
was created together with the `app.asar` file. It contains the unpacked files
|
||||
and should be shipped together with the `app.asar` archive.
|
||||
|
||||
[asar]: https://github.com/electron/asar
|
||||
[electron-packager]: https://github.com/electron/electron-packager
|
||||
[electron-forge]: https://github.com/electron-userland/electron-forge
|
||||
[electron-builder]: https://github.com/electron-userland/electron-builder
|
||||
@@ -196,11 +196,11 @@ it may be worth your time to shop around. Popular resellers include:
|
||||
|
||||
There are a number of tools for signing your packaged app:
|
||||
|
||||
- [`electron-winstaller`] will generate an installer for windows and sign it for
|
||||
* [`electron-winstaller`] will generate an installer for windows and sign it for
|
||||
you
|
||||
- [`electron-forge`] can sign installers it generates through the
|
||||
* [`electron-forge`] can sign installers it generates through the
|
||||
Squirrel.Windows or MSI targets.
|
||||
- [`electron-builder`] can sign some of its windows targets
|
||||
* [`electron-builder`] can sign some of its windows targets
|
||||
|
||||
## Windows Store
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ the system's dark mode setting. You can do this by using the
|
||||
|
||||
If you want to manually switch between light/dark modes, you can do this by
|
||||
setting the desired mode in the
|
||||
[themeSource](https://www.electronjs.org/docs/api/native-theme#nativethemethemesource)
|
||||
[themeSource](../api/native-theme.md#nativethemethemesource)
|
||||
property of the `nativeTheme` module. This property's value will be propagated
|
||||
to your Renderer process. Any CSS rules related to `prefers-color-scheme` will
|
||||
be updated accordingly.
|
||||
@@ -96,7 +96,7 @@ color scheme, and update the "Current Theme Source" label to `System`.
|
||||
|
||||
To add listeners and handlers, add the following lines to the `renderer.js` file:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
document.getElementById('toggle-dark-mode').addEventListener('click', async () => {
|
||||
@@ -130,7 +130,7 @@ active using the `nativeTheme.shouldUseDarkColors` property, and set the
|
||||
`themeSource` to the opposite theme.
|
||||
* Upon receiving `dark-mode:system`, we reset the `themeSource` to `system`.
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
@@ -180,7 +180,7 @@ attribute. The value of `prefers-color-scheme` will follow your
|
||||
|
||||
Create a `styles.css` file and add the following lines:
|
||||
|
||||
```css
|
||||
```css fiddle='docs/fiddles/features/macos-dark-mode'
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body { background: #333; color: white; }
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ $ code electron-quick-start
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### 3. Debugging
|
||||
|
||||
Set some breakpoints in `main.js`, and start debugging in the [Debug View](https://code.visualstudio.com/docs/editor/debugging). You should be able to hit the breakpoints.
|
||||
@@ -84,16 +83,16 @@ $ code electron-quick-start
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Configuration Notes**
|
||||
|
||||
- `cppvsdbg` requires the [built-in C/C++ extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) be enabled.
|
||||
- `${workspaceFolder}` is the full path to Chromium's `src` directory.
|
||||
- `your-executable-location` will be one of the following depending on a few items:
|
||||
- `Testing`: If you are using the default settings of [Electron's Build-Tools](https://github.com/electron/build-tools) or the default instructions when [building from source](https://www.electronjs.org/docs/development/build-instructions-gn#building).
|
||||
- `Release`: If you built a Release build rather than a Testing build.
|
||||
- `your-directory-name`: If you modified this during your build process from the default, this will be whatever you specified.
|
||||
- The `args` array string `"your-electron-project-path"` should be the absolute path to either the directory or `main.js` file of the Electron project you are using for testing. In this example, it should be your path to `electron-quick-start`.
|
||||
|
||||
* `cppvsdbg` requires the [built-in C/C++ extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) be enabled.
|
||||
* `${workspaceFolder}` is the full path to Chromium's `src` directory.
|
||||
* `your-executable-location` will be one of the following depending on a few items:
|
||||
* `Testing`: If you are using the default settings of [Electron's Build-Tools](https://github.com/electron/build-tools) or the default instructions when [building from source](https://www.electronjs.org/docs/development/build-instructions-gn#building).
|
||||
* `Release`: If you built a Release build rather than a Testing build.
|
||||
* `your-directory-name`: If you modified this during your build process from the default, this will be whatever you specified.
|
||||
* The `args` array string `"your-electron-project-path"` should be the absolute path to either the directory or `main.js` file of the Electron project you are using for testing. In this example, it should be your path to `electron-quick-start`.
|
||||
|
||||
#### 3. Debugging
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Electron versions *< 2.0* did not conform to the [semver](https://semver.org) sp
|
||||
|
||||
Here is an example of the 1.x strategy:
|
||||
|
||||

|
||||

|
||||
|
||||
An app developed with `1.8.1` cannot take the `1.8.3` bug fix without either absorbing the `1.8.2` feature, or by backporting the fix and maintaining a new release line.
|
||||
|
||||
@@ -54,12 +54,12 @@ Note that most Chromium updates will be considered breaking. Fixes that can be b
|
||||
|
||||
Stabilization branches are branches that run parallel to master, taking in only cherry-picked commits that are related to security or stability. These branches are never merged back to master.
|
||||
|
||||

|
||||

|
||||
|
||||
Since Electron 8, stabilization branches are always **major** version lines, and named against the following template `$MAJOR-x-y` e.g. `8-x-y`. Prior to that we used **minor** version lines and named them as `$MAJOR-$MINOR-x` e.g. `2-0-x`
|
||||
|
||||
We allow for multiple stabilization branches to exist simultaneously, and intend to support at least two in parallel at all times, backporting security fixes as necessary.
|
||||

|
||||

|
||||
|
||||
Older lines will not be supported by GitHub, but other groups can take ownership and backport stability and security fixes on their own. We discourage this, but recognize that it makes life easier for many app developers.
|
||||
|
||||
@@ -104,17 +104,17 @@ For each major and minor bump, you should expect to see something like the follo
|
||||
An example lifecycle in pictures:
|
||||
|
||||
* A new release branch is created that includes the latest set of features. It is published as `2.0.0-beta.1`.
|
||||

|
||||

|
||||
* A bug fix comes into master that can be backported to the release branch. The patch is applied, and a new beta is published as `2.0.0-beta.2`.
|
||||

|
||||

|
||||
* The beta is considered _generally stable_ and it is published again as a non-beta under `2.0.0`.
|
||||

|
||||

|
||||
* Later, a zero-day exploit is revealed and a fix is applied to master. We backport the fix to the `2-0-x` line and release `2.0.1`.
|
||||

|
||||

|
||||
|
||||
A few examples of how various semver ranges will pick up new releases:
|
||||
|
||||

|
||||

|
||||
|
||||
# Missing Features: Alphas
|
||||
|
||||
@@ -145,7 +145,7 @@ We seek to increase clarity at all levels of the update and releases process. St
|
||||
|
||||
# Versioned `master`
|
||||
|
||||
- The `master` branch will always contain the next major version `X.0.0-nightly.DATE` in its `package.json`
|
||||
- Release branches are never merged back to master
|
||||
- Release branches _do_ contain the correct version in their `package.json`
|
||||
- As soon as a release branch is cut for a major, master must be bumped to the next major. I.e. `master` is always versioned as the next theoretical release branch
|
||||
* The `master` branch will always contain the next major version `X.0.0-nightly.DATE` in its `package.json`
|
||||
* Release branches are never merged back to master
|
||||
* Release branches _do_ contain the correct version in their `package.json`
|
||||
* As soon as a release branch is cut for a major, master must be bumped to the next major. I.e. `master` is always versioned as the next theoretical release branch
|
||||
|
||||
@@ -17,7 +17,7 @@ Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
following lines:
|
||||
|
||||
```js
|
||||
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/local'
|
||||
const { Menu, MenuItem } = require('electron')
|
||||
|
||||
const menu = new Menu()
|
||||
@@ -56,7 +56,7 @@ Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
following lines:
|
||||
|
||||
```js
|
||||
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/global'
|
||||
const { app, globalShortcut } = require('electron')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
@@ -101,7 +101,7 @@ Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
following lines:
|
||||
|
||||
```js
|
||||
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/interception-from-main'
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
@@ -24,7 +24,7 @@ Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
following lines:
|
||||
|
||||
```javascript
|
||||
```javascript fiddle='docs/fiddles/features/macos-dock-menu'
|
||||
const { app, Menu } = require('electron')
|
||||
|
||||
const dockMenu = Menu.buildFromTemplate([
|
||||
|
||||
@@ -25,7 +25,7 @@ Starting with a working application from the
|
||||
|
||||
and add the following lines to the `renderer.js` file:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
document.getElementById('drag').ondragstart = (event) => {
|
||||
@@ -40,7 +40,7 @@ and forward the information to the Main process.
|
||||
In the Main process(`main.js` file), expand the received event with a path to the file that is
|
||||
being dragged and an icon:
|
||||
|
||||
```javascript
|
||||
```javascript fiddle='docs/fiddles/features/drag-and-drop'
|
||||
const { ipcMain } = require('electron')
|
||||
|
||||
ipcMain.on('ondragstart', (event, filePath) => {
|
||||
|
||||
@@ -28,7 +28,7 @@ Assuming you have a working Electron application from the
|
||||
|
||||
and add the `renderer.js` file:
|
||||
|
||||
```js
|
||||
```javascript fiddle='docs/fiddles/features/notifications/renderer'
|
||||
const myNotification = new Notification('Title', {
|
||||
body: 'Notification from the Renderer process'
|
||||
})
|
||||
@@ -52,7 +52,7 @@ message that was generated after triggering the `onclick` event:
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the following lines:
|
||||
|
||||
```js
|
||||
```javascript fiddle='docs/fiddles/features/notifications/main'
|
||||
const { Notification } = require('electron')
|
||||
|
||||
function showNotification () {
|
||||
|
||||
@@ -1,59 +1,67 @@
|
||||
# Offscreen Rendering
|
||||
|
||||
Offscreen rendering lets you obtain the content of a browser window in a bitmap,
|
||||
so it can be rendered anywhere, for example on a texture in a 3D scene. The
|
||||
offscreen rendering in Electron uses a similar approach than the [Chromium
|
||||
Embedded Framework](https://bitbucket.org/chromiumembedded/cef) project.
|
||||
## Overview
|
||||
|
||||
Two modes of rendering can be used and only the dirty area is passed in the
|
||||
`'paint'` event to be more efficient. The rendering can be stopped, continued
|
||||
and the frame rate can be set. The specified frame rate is a top limit value,
|
||||
when there is nothing happening on a webpage, no frames are generated. The
|
||||
maximum frame rate is 60, because above that there is no benefit, only
|
||||
performance loss.
|
||||
Offscreen rendering lets you obtain the content of a `BrowserWindow` in a
|
||||
bitmap, so it can be rendered anywhere, for example, on texture in a 3D scene.
|
||||
The offscreen rendering in Electron uses a similar approach to that of the
|
||||
[Chromium Embedded Framework](https://bitbucket.org/chromiumembedded/cef)
|
||||
project.
|
||||
|
||||
**Note:** An offscreen window is always created as a [Frameless Window](../api/frameless-window.md).
|
||||
*Notes*:
|
||||
|
||||
## Rendering Modes
|
||||
* There are two rendering modes that can be used (see the section below) and only
|
||||
the dirty area is passed to the `paint` event to be more efficient.
|
||||
* You can stop/continue the rendering as well as set the frame rate.
|
||||
* The maximum frame rate is 240 because greater values bring only performance
|
||||
losses with no benefits.
|
||||
* When nothing is happening on a webpage, no frames are generated.
|
||||
* An offscreen window is always created as a
|
||||
[Frameless Window](../api/frameless-window.md).
|
||||
|
||||
### GPU accelerated
|
||||
### Rendering Modes
|
||||
|
||||
#### GPU accelerated
|
||||
|
||||
GPU accelerated rendering means that the GPU is used for composition. Because of
|
||||
that the frame has to be copied from the GPU which requires more performance,
|
||||
thus this mode is quite a bit slower than the other one. The benefit of this
|
||||
that, the frame has to be copied from the GPU which requires more resources,
|
||||
thus this mode is slower than the Software output device. The benefit of this
|
||||
mode is that WebGL and 3D CSS animations are supported.
|
||||
|
||||
### Software output device
|
||||
#### Software output device
|
||||
|
||||
This mode uses a software output device for rendering in the CPU, so the frame
|
||||
generation is much faster, thus this mode is preferred over the GPU accelerated
|
||||
one.
|
||||
generation is much faster. As a result, this mode is preferred over the GPU
|
||||
accelerated one.
|
||||
|
||||
To enable this mode GPU acceleration has to be disabled by calling the
|
||||
To enable this mode, GPU acceleration has to be disabled by calling the
|
||||
[`app.disableHardwareAcceleration()`][disablehardwareacceleration] API.
|
||||
|
||||
## Usage
|
||||
## Example
|
||||
|
||||
``` javascript
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), add the following lines to the
|
||||
`main.js` file:
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/offscreen-rendering'
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const fs = require('fs')
|
||||
|
||||
app.disableHardwareAcceleration()
|
||||
|
||||
let win
|
||||
|
||||
app.whenReady().then(() => {
|
||||
win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
offscreen: true
|
||||
}
|
||||
})
|
||||
win = new BrowserWindow({ webPreferences: { offscreen: true } })
|
||||
|
||||
win.loadURL('http://github.com')
|
||||
win.loadURL('https://github.com')
|
||||
win.webContents.on('paint', (event, dirty, image) => {
|
||||
// updateBitmap(dirty, image.getBitmap())
|
||||
fs.writeFileSync('ex.png', image.toPNG())
|
||||
})
|
||||
win.webContents.setFrameRate(30)
|
||||
win.webContents.setFrameRate(60)
|
||||
})
|
||||
```
|
||||
|
||||
After launching the Electron application, navigate to your application's
|
||||
working folder.
|
||||
[disablehardwareacceleration]: ../api/app.md#appdisablehardwareacceleration
|
||||
|
||||
@@ -34,11 +34,11 @@ let onlineStatusWindow
|
||||
|
||||
app.whenReady().then(() => {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false })
|
||||
onlineStatusWindow.loadURL(`file://${__dirname}/online-status.html`)
|
||||
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
|
||||
})
|
||||
```
|
||||
|
||||
create the `online-status.html` file and add the following line before the
|
||||
in the `index.html` file, add the following line before the
|
||||
closing `</body>` tag:
|
||||
|
||||
```html
|
||||
@@ -47,7 +47,7 @@ closing `</body>` tag:
|
||||
|
||||
and add the `renderer.js` file:
|
||||
|
||||
```javascript
|
||||
```javascript fiddle='docs/fiddles/features/online-detection/renderer'
|
||||
const alertOnlineStatus = () => { window.alert(navigator.onLine ? 'online' : 'offline') }
|
||||
|
||||
window.addEventListener('online', alertOnlineStatus)
|
||||
@@ -78,7 +78,7 @@ let onlineStatusWindow
|
||||
|
||||
app.whenReady().then(() => {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false, webPreferences: { nodeIntegration: true } })
|
||||
onlineStatusWindow.loadURL(`file://${__dirname}/online-status.html`)
|
||||
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
|
||||
})
|
||||
|
||||
ipcMain.on('online-status-changed', (event, status) => {
|
||||
@@ -86,7 +86,7 @@ ipcMain.on('online-status-changed', (event, status) => {
|
||||
})
|
||||
```
|
||||
|
||||
create the `online-status.html` file and add the following line before the
|
||||
in the `index.html` file, add the following line before the
|
||||
closing `</body>` tag:
|
||||
|
||||
```html
|
||||
@@ -95,7 +95,7 @@ closing `</body>` tag:
|
||||
|
||||
and add the `renderer.js` file:
|
||||
|
||||
```javascript
|
||||
```javascript fiddle='docs/fiddles/features/online-detection/main'
|
||||
const { ipcRenderer } = require('electron')
|
||||
const updateOnlineStatus = () => { ipcRenderer.send('online-status-changed', navigator.onLine ? 'online' : 'offline') }
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), add the following lines to the
|
||||
`main.js` file:
|
||||
|
||||
```javascript
|
||||
```javascript fiddle='docs/fiddles/features/progress-bar'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ If both commands succeeded, you are ready to install Electron.
|
||||
|
||||
From a development perspective, an Electron application is essentially a Node.js application. This means that the starting point of your Electron application will be a `package.json` file like in any other Node.js application. A minimal Electron application has the following structure:
|
||||
|
||||
```plain
|
||||
```plaintext
|
||||
my-electron-app/
|
||||
├── package.json
|
||||
├── main.js
|
||||
@@ -53,7 +53,7 @@ The main script specifies the entry point of your Electron application (in our c
|
||||
|
||||
The main script may look as follows:
|
||||
|
||||
```js
|
||||
```javascript fiddle='docs/fiddles/quick-start'
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
@@ -66,7 +66,6 @@ function createWindow () {
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
win.webContents.openDevTools()
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
@@ -87,10 +86,10 @@ app.on('activate', () => {
|
||||
##### What is going on above?
|
||||
|
||||
1. Line 1: First, you import the `app` and `BrowserWindow` modules of the `electron` package to be able to manage your application's lifecycle events, as well as create and control browser windows.
|
||||
2. Line 3: After that, you define a function that creates a [new browser window](../api/browser-window.md#new-browserwindowoptions) with node integration enabled, loads `index.html` file into this window (line 12, we will discuss the file later) and opens Developer Tools (line 13).
|
||||
3. Line 16: You create a new browser window by invoking the `createWindow` function once the Electron application [is initialized](../api/app.md#appwhenready).
|
||||
4. Line 18: You add a new listener that tries to quit the application when it no longer has any open windows. This listener is a no-op on macOS due to the operating system's [window management behavior](https://support.apple.com/en-ca/guide/mac-help/mchlp2469/mac).
|
||||
5. Line 24: You add a new listener that creates a new browser window only if when the application has no visible windows after being activated. For example, after launching the application for the first time, or re-launching the already running application.
|
||||
2. Line 3: After that, you define a function that creates a [new browser window](../api/browser-window.md#new-browserwindowoptions) with node integration enabled, loads `index.html` file into this window (line 12, we will discuss the file later).
|
||||
3. Line 15: You create a new browser window by invoking the `createWindow` function once the Electron application [is initialized](../api/app.md#appwhenready).
|
||||
4. Line 17: You add a new listener that tries to quit the application when it no longer has any open windows. This listener is a no-op on macOS due to the operating system's [window management behavior](https://support.apple.com/en-ca/guide/mac-help/mchlp2469/mac).
|
||||
5. Line 23: You add a new listener that creates a new browser window only if when the application has no visible windows after being activated. For example, after launching the application for the first time, or re-launching the already running application.
|
||||
|
||||
#### Create a web page
|
||||
|
||||
@@ -98,7 +97,7 @@ This is the web page you want to display once the application is initialized. Th
|
||||
|
||||
The `index.html` page looks as follows:
|
||||
|
||||
```html
|
||||
```html fiddle='docs/fiddles/quick-start'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -108,9 +107,11 @@ The `index.html` page looks as follows:
|
||||
</head>
|
||||
<body style="background: white;">
|
||||
<h1>Hello World!</h1>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -123,18 +124,24 @@ Your Electron application uses the `package.json` file as the main entry point (
|
||||
{
|
||||
"name": "my-electron-app",
|
||||
"version": "0.1.0",
|
||||
"author": "your name",
|
||||
"description": "My Electron app",
|
||||
"main": "main.js"
|
||||
}
|
||||
```
|
||||
|
||||
> NOTE: If the `main` field is omitted, Electron will attempt to load an `index.js` file from the directory containing `package.json`.
|
||||
|
||||
> NOTE: The `author` and `description` fields are required for packaging, otherwise error will occur when running `npm run make`.
|
||||
|
||||
By default, the `npm start` command will run the main script with Node.js. To run the script with Electron, you need to change it as such:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-electron-app",
|
||||
"version": "0.1.0",
|
||||
"author": "your name",
|
||||
"description": "My Electron app",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"start": "electron ."
|
||||
|
||||
@@ -24,7 +24,7 @@ Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), add the following lines to the
|
||||
`main.js` file:
|
||||
|
||||
```javascript
|
||||
```javascript fiddle='docs/fiddles/features/recent-documents'
|
||||
const { app } = require('electron')
|
||||
|
||||
app.addRecentDocument('/Users/USERNAME/Desktop/work.type')
|
||||
|
||||
@@ -24,7 +24,7 @@ Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), add the following lines to the
|
||||
`main.js` file:
|
||||
|
||||
```javascript
|
||||
```javascript fiddle='docs/fiddles/features/represented-file'
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
@@ -818,7 +818,7 @@ which potential security issues are not as widely known.
|
||||
[browser-view]: ../api/browser-view.md
|
||||
[webview-tag]: ../api/webview-tag.md
|
||||
[web-contents]: ../api/web-contents.md
|
||||
[window-open-handler]: ../api/web-contents.md#contentssetwindowopenhandler-handler
|
||||
[window-open-handler]: ../api/web-contents.md#contentssetwindowopenhandlerhandler
|
||||
[will-navigate]: ../api/web-contents.md#event-will-navigate
|
||||
[open-external]: ../api/shell.md#shellopenexternalurl-options
|
||||
[sandbox]: ../api/sandbox-option.md
|
||||
|
||||
@@ -71,4 +71,4 @@ Although the spellchecker itself does not send any typings, words or user input
|
||||
myWindow.session.setSpellCheckerDictionaryDownloadURL('https://example.com/dictionaries/')
|
||||
```
|
||||
|
||||
Check out the docs for [`session.setSpellCheckerDictionaryDownloadURL`](https://www.electronjs.org/docs/api/session#sessetspellcheckerdictionarydownloadurlurl) for more information on where to get the dictionary files from and how you need to host them.
|
||||
Check out the docs for [`session.setSpellCheckerDictionaryDownloadURL`](../api/session.md#sessetspellcheckerdictionarydownloadurlurl) for more information on where to get the dictionary files from and how you need to host them.
|
||||
|
||||
@@ -10,21 +10,21 @@ for answers to questions,
|
||||
or to join in discussion with other developers who use Electron,
|
||||
you can interact with the community in these locations:
|
||||
|
||||
- [`Electron's Discord`](https://discord.com/invite/electron) has channels for:
|
||||
- Getting help
|
||||
- Ecosystem apps like [Electron Forge](https://github.com/electron-userland/electron-forge) and [Electron Fiddle](https://github.com/electron/fiddle)
|
||||
- Sharing ideas with other Electron app developers
|
||||
- And more!
|
||||
- [`electron`](https://discuss.atom.io/c/electron) category on the Atom forums
|
||||
- `#atom-shell` channel on Freenode
|
||||
- `#electron` channel on [Atom's Slack](https://discuss.atom.io/t/join-us-on-slack/16638?source_topic_id=25406)
|
||||
- [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*
|
||||
- [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
|
||||
- [`electron-kr`](https://electron-kr.github.io/electron-kr) *(Korean)*
|
||||
- [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
|
||||
- [`electron-tr`](https://electron-tr.herokuapp.com) *(Turkish)*
|
||||
- [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
|
||||
- [`electron-pl`](https://electronpl.github.io) *(Poland)*
|
||||
* [`Electron's Discord`](https://discord.com/invite/electron) has channels for:
|
||||
* Getting help
|
||||
* Ecosystem apps like [Electron Forge](https://github.com/electron-userland/electron-forge) and [Electron Fiddle](https://github.com/electron/fiddle)
|
||||
* Sharing ideas with other Electron app developers
|
||||
* And more!
|
||||
* [`electron`](https://discuss.atom.io/c/electron) category on the Atom forums
|
||||
* `#atom-shell` channel on Freenode
|
||||
* `#electron` channel on [Atom's Slack](https://discuss.atom.io/t/join-us-on-slack/16638?source_topic_id=25406)
|
||||
* [`electron-ru`](https://telegram.me/electron_ru) *(Russian)*
|
||||
* [`electron-br`](https://electron-br.slack.com) *(Brazilian Portuguese)*
|
||||
* [`electron-kr`](https://electron-kr.github.io/electron-kr) *(Korean)*
|
||||
* [`electron-jp`](https://electron-jp.slack.com) *(Japanese)*
|
||||
* [`electron-tr`](https://electron-tr.herokuapp.com) *(Turkish)*
|
||||
* [`electron-id`](https://electron-id.slack.com) *(Indonesia)*
|
||||
* [`electron-pl`](https://electronpl.github.io) *(Poland)*
|
||||
|
||||
If you'd like to contribute to Electron,
|
||||
see the [contributing document](https://github.com/electron/electron/blob/master/CONTRIBUTING.md).
|
||||
@@ -64,9 +64,9 @@ until the maintainers feel the maintenance burden is too high to continue doing
|
||||
|
||||
### Currently supported versions
|
||||
|
||||
- 11.x.y
|
||||
- 10.x.y
|
||||
- 9.x.y
|
||||
* 11.x.y
|
||||
* 10.x.y
|
||||
* 9.x.y
|
||||
|
||||
### End-of-life
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Using Native Node Modules
|
||||
|
||||
Native Node modules are supported by Electron, but since Electron is very
|
||||
likely to use a different V8 version from the Node binary installed on your
|
||||
system, the modules you use will need to be recompiled for Electron. Otherwise,
|
||||
Native Node.js modules are supported by Electron, but since Electron has a different
|
||||
[application binary interface (ABI)][abi] from a given Node.js binary (due to
|
||||
differences such as using Chromium's BoringSSL instead of OpenSSL), the native
|
||||
modules you use will need to be recompiled for Electron. Otherwise,
|
||||
you will get the following class of error when you try to run your app:
|
||||
|
||||
```sh
|
||||
@@ -23,9 +24,11 @@ You can install modules like other Node projects, and then rebuild the modules
|
||||
for Electron with the [`electron-rebuild`][electron-rebuild] package. This
|
||||
module can automatically determine the version of Electron and handle the
|
||||
manual steps of downloading headers and rebuilding native modules for your app.
|
||||
If you are using [Electron Forge][electron-forge], this tool is used automatically
|
||||
in both development mode and when making distributables.
|
||||
|
||||
For example, to install `electron-rebuild` and then rebuild modules with it
|
||||
via the command line:
|
||||
For example, to install the standalone `electron-rebuild` tool and then rebuild
|
||||
modules with it via the command line:
|
||||
|
||||
```sh
|
||||
npm install --save-dev electron-rebuild
|
||||
@@ -33,12 +36,12 @@ npm install --save-dev electron-rebuild
|
||||
# Every time you run "npm install", run this:
|
||||
./node_modules/.bin/electron-rebuild
|
||||
|
||||
# On Windows if you have trouble, try:
|
||||
# If you have trouble on Windows, try:
|
||||
.\node_modules\.bin\electron-rebuild.cmd
|
||||
```
|
||||
|
||||
For more information on usage and integration with other tools, consult the
|
||||
project's README.
|
||||
For more information on usage and integration with other tools such as [Electron
|
||||
Packager][electron-packager], consult the project's README.
|
||||
|
||||
### Using `npm`
|
||||
|
||||
@@ -129,13 +132,13 @@ should look like this:
|
||||
|
||||
In particular, it's important that:
|
||||
|
||||
- you link against `node.lib` from _Electron_ and not Node. If you link against
|
||||
* you link against `node.lib` from _Electron_ and not Node. If you link against
|
||||
the wrong `node.lib` you will get load-time errors when you require the
|
||||
module in Electron.
|
||||
- you include the flag `/DELAYLOAD:node.exe`. If the `node.exe` link is not
|
||||
* you include the flag `/DELAYLOAD:node.exe`. If the `node.exe` link is not
|
||||
delayed, then the delay-load hook won't get a chance to fire and the node
|
||||
symbols won't be correctly resolved.
|
||||
- `win_delay_load_hook.obj` is linked directly into the final DLL. If the hook
|
||||
* `win_delay_load_hook.obj` is linked directly into the final DLL. If the hook
|
||||
is set up in a dependent DLL, it won't fire at the right time.
|
||||
|
||||
See [`node-gyp`](https://github.com/nodejs/node-gyp/blob/e2401e1395bef1d3c8acec268b42dc5fb71c4a38/src/win_delay_load_hook.cc)
|
||||
@@ -147,23 +150,25 @@ for an example delay-load hook if you're implementing your own.
|
||||
native Node modules with prebuilt binaries for multiple versions of Node
|
||||
and Electron.
|
||||
|
||||
If modules provide binaries for the usage in Electron, make sure to omit
|
||||
`--build-from-source` and the `npm_config_build_from_source` environment
|
||||
variable in order to take full advantage of the prebuilt binaries.
|
||||
If the `prebuild`-powered module provide binaries for the usage in Electron,
|
||||
make sure to omit `--build-from-source` and the `npm_config_build_from_source`
|
||||
environment variable in order to take full advantage of the prebuilt binaries.
|
||||
|
||||
## Modules that rely on `node-pre-gyp`
|
||||
|
||||
The [`node-pre-gyp` tool][node-pre-gyp] provides a way to deploy native Node
|
||||
modules with prebuilt binaries, and many popular modules are using it.
|
||||
|
||||
Usually those modules work fine under Electron, but sometimes when Electron uses
|
||||
a newer version of V8 than Node and/or there are ABI changes, bad things may
|
||||
happen. So in general, it is recommended to always build native modules from
|
||||
source code. `electron-rebuild` handles this for you automatically.
|
||||
Sometimes those modules work fine under Electron, but when there are no
|
||||
Electron-specific binaries available, you'll need to build from source.
|
||||
Because of this, it is recommended to use `electron-rebuild` for these modules.
|
||||
|
||||
If you are following the `npm` way of installing modules, then this is done
|
||||
by default, if not, you have to pass `--build-from-source` to `npm`, or set the
|
||||
`npm_config_build_from_source` environment variable.
|
||||
If you are following the `npm` way of installing modules, you'll need to pass
|
||||
`--build-from-source` to `npm`, or set the `npm_config_build_from_source`
|
||||
environment variable.
|
||||
|
||||
[abi]: https://en.wikipedia.org/wiki/Application_binary_interface
|
||||
[electron-rebuild]: https://github.com/electron/electron-rebuild
|
||||
[electron-forge]: https://electronforge.io/
|
||||
[electron-packager]: https://github.com/electron/electron-packager
|
||||
[node-pre-gyp]: https://github.com/mapbox/node-pre-gyp
|
||||
|
||||
@@ -20,7 +20,7 @@ and only allow the capabilities you want to support.
|
||||
### WebViews
|
||||
|
||||
> Important Note:
|
||||
[we do not recommend you to use use WebViews](https://www.electronjs.org/docs/api/webview-tag#warning),
|
||||
[we do not recommend you to use use WebViews](../api/webview-tag.md#warning),
|
||||
as this tag undergoes dramatic architectural changes that may affect stability
|
||||
of your application. Consider switching to alternatives, like `iframe` and
|
||||
Electron's `BrowserView`, or an architecture that avoids embedded content
|
||||
|
||||
@@ -231,7 +231,6 @@ auto_filenames = {
|
||||
"lib/browser/api/web-contents-view.ts",
|
||||
"lib/browser/api/web-contents.ts",
|
||||
"lib/browser/api/web-frame-main.ts",
|
||||
"lib/browser/chrome-extension-shim.ts",
|
||||
"lib/browser/default-menu.ts",
|
||||
"lib/browser/desktop-capturer.ts",
|
||||
"lib/browser/devtools.ts",
|
||||
|
||||
@@ -345,6 +345,8 @@ filenames = {
|
||||
"shell/browser/electron_browser_client.h",
|
||||
"shell/browser/electron_browser_context.cc",
|
||||
"shell/browser/electron_browser_context.h",
|
||||
"shell/browser/electron_browser_handler_impl.cc",
|
||||
"shell/browser/electron_browser_handler_impl.h",
|
||||
"shell/browser/electron_browser_main_parts.cc",
|
||||
"shell/browser/electron_browser_main_parts.h",
|
||||
"shell/browser/electron_download_manager_delegate.cc",
|
||||
|
||||
@@ -615,9 +615,10 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
if (options.withFileTypes) {
|
||||
const dirents = [];
|
||||
for (const file of files) {
|
||||
const stats = archive.stat(file);
|
||||
const childPath = path.join(filePath, file);
|
||||
const stats = archive.stat(childPath);
|
||||
if (!stats) {
|
||||
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath: file });
|
||||
const error = createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||
nextTick(callback!, [error]);
|
||||
return;
|
||||
}
|
||||
@@ -657,9 +658,10 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
if (options && (options as any).withFileTypes) {
|
||||
const dirents = [];
|
||||
for (const file of files) {
|
||||
const stats = archive.stat(file);
|
||||
const childPath = path.join(filePath, file);
|
||||
const stats = archive.stat(childPath);
|
||||
if (!stats) {
|
||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: file });
|
||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||
}
|
||||
if (stats.isFile) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
||||
@@ -689,7 +691,8 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
if (info.size === 0) return ['', false];
|
||||
if (info.unpacked) {
|
||||
const realPath = archive.copyFileOut(filePath);
|
||||
return fs.readFileSync(realPath, { encoding: 'utf8' });
|
||||
const str = fs.readFileSync(realPath, { encoding: 'utf8' });
|
||||
return [str, str.length > 0];
|
||||
}
|
||||
|
||||
logASARAccess(asarPath, filePath, info.offset);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user