mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
273 Commits
v10.1.5
...
v11.0.0-ni
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75372e933f | ||
|
|
f859d4ce44 | ||
|
|
9c37e12e2d | ||
|
|
834408a50f | ||
|
|
b6321cc22d | ||
|
|
38fafe4986 | ||
|
|
e6cf5906f6 | ||
|
|
362da77c0a | ||
|
|
3f45fc24bb | ||
|
|
75c3a426ea | ||
|
|
4e15273b9f | ||
|
|
c6c986648f | ||
|
|
bac232689d | ||
|
|
76e3ee6fe6 | ||
|
|
4829b0f816 | ||
|
|
a612fb00c8 | ||
|
|
2f02a469f4 | ||
|
|
b39a5b71fe | ||
|
|
91f5837344 | ||
|
|
5fc354df73 | ||
|
|
ee31611e84 | ||
|
|
071c5930b9 | ||
|
|
5cfe956fe1 | ||
|
|
b500294c1d | ||
|
|
3b250b649b | ||
|
|
2162eeb609 | ||
|
|
00fc8066de | ||
|
|
6b1de271a7 | ||
|
|
ec838cfc11 | ||
|
|
6fa3406912 | ||
|
|
b57f5086ef | ||
|
|
734753dd7a | ||
|
|
10bf50e1fd | ||
|
|
5795e59352 | ||
|
|
2fb14f53fe | ||
|
|
d4a4269989 | ||
|
|
cd805544d1 | ||
|
|
95dd81bd68 | ||
|
|
a76e74ac3f | ||
|
|
74e7f2773f | ||
|
|
b43e601b83 | ||
|
|
589968f9fc | ||
|
|
a12602dbc3 | ||
|
|
77eea08a54 | ||
|
|
86b441d599 | ||
|
|
509740c357 | ||
|
|
bcba4baa85 | ||
|
|
f0953902db | ||
|
|
e5cb22b7f9 | ||
|
|
682f78b9a8 | ||
|
|
8f5280a821 | ||
|
|
fa1323d6cd | ||
|
|
f146a164af | ||
|
|
6f53457a17 | ||
|
|
45551f6bf2 | ||
|
|
14bbc07f1e | ||
|
|
3806f4cb64 | ||
|
|
eb7c04c7c4 | ||
|
|
f649e604be | ||
|
|
4c3da359fc | ||
|
|
3f37ff87d2 | ||
|
|
24fb498fd3 | ||
|
|
d8be385d4b | ||
|
|
e4180b3a3a | ||
|
|
eb550c57d3 | ||
|
|
cdd5bb1eba | ||
|
|
9c8cdd63fd | ||
|
|
3f54f240bd | ||
|
|
36900df7d9 | ||
|
|
ce87a7e69f | ||
|
|
990a6f8b6c | ||
|
|
e002f7315d | ||
|
|
8bbdc224ac | ||
|
|
36bd940bc3 | ||
|
|
f0a0e10bd1 | ||
|
|
b02748e607 | ||
|
|
1719f073c1 | ||
|
|
91cdedfea9 | ||
|
|
cbb47570bd | ||
|
|
e18f508e66 | ||
|
|
6c4017ff45 | ||
|
|
5737fda154 | ||
|
|
8847517798 | ||
|
|
c9aa68e32c | ||
|
|
42f716bbc6 | ||
|
|
ef9addcb92 | ||
|
|
dcb56923cb | ||
|
|
eb6616e4e9 | ||
|
|
9bd0fc5348 | ||
|
|
66d65a6d35 | ||
|
|
4305707ca8 | ||
|
|
8d25847318 | ||
|
|
ad16e6c647 | ||
|
|
80a6adb597 | ||
|
|
7dd365784d | ||
|
|
e59370f541 | ||
|
|
6cfbee9f34 | ||
|
|
2aeaca6f7b | ||
|
|
cadc142d05 | ||
|
|
446100cdfe | ||
|
|
7fd96cd188 | ||
|
|
25a36a43c1 | ||
|
|
b0be3fbb7f | ||
|
|
71a7e1b2e3 | ||
|
|
2a3437e5b5 | ||
|
|
cf74ee3d83 | ||
|
|
99079c3bc7 | ||
|
|
1f23807271 | ||
|
|
82af855579 | ||
|
|
f6e21d59e7 | ||
|
|
4398ecb6c8 | ||
|
|
9106d0c6d5 | ||
|
|
92d9de93a4 | ||
|
|
fd0eaf4507 | ||
|
|
2a6d6d6ea7 | ||
|
|
d330c6f9fe | ||
|
|
82ae18dd1c | ||
|
|
c157311373 | ||
|
|
354ea00f17 | ||
|
|
4c449fbc75 | ||
|
|
3cb833821a | ||
|
|
a69a655386 | ||
|
|
dc3905cef4 | ||
|
|
22e64dc328 | ||
|
|
6bd30bf09e | ||
|
|
c6db47182a | ||
|
|
451086d7f2 | ||
|
|
ee61eb9aa4 | ||
|
|
2cbd091e89 | ||
|
|
af4876296c | ||
|
|
d9d07c65b2 | ||
|
|
6e069a7df8 | ||
|
|
ef3579eae3 | ||
|
|
80e5007c47 | ||
|
|
1c49e4e376 | ||
|
|
8eb198bab4 | ||
|
|
16a3f41fd3 | ||
|
|
605e50269e | ||
|
|
9b4572de44 | ||
|
|
5b80556da2 | ||
|
|
4290555a0d | ||
|
|
1429a8961c | ||
|
|
46f58b28c3 | ||
|
|
6369748a2a | ||
|
|
abf2e9c93d | ||
|
|
b2b5a6a3de | ||
|
|
acb64a2d3c | ||
|
|
3853fd3e99 | ||
|
|
659e79fc08 | ||
|
|
4c77fe318d | ||
|
|
72a089262e | ||
|
|
61a05caa78 | ||
|
|
563a8c83ea | ||
|
|
046a05944a | ||
|
|
0629c6c2ea | ||
|
|
48d1a70b52 | ||
|
|
5c6d8c2b7d | ||
|
|
0f44682be0 | ||
|
|
2376c45443 | ||
|
|
b665eb6d43 | ||
|
|
4e66f1b2c6 | ||
|
|
a54fcde3f4 | ||
|
|
7cc780d077 | ||
|
|
59f9d75324 | ||
|
|
cb6476fd12 | ||
|
|
e1e73fa5f5 | ||
|
|
09c0ee8f87 | ||
|
|
cf284991d8 | ||
|
|
f9fe8a67b9 | ||
|
|
7bf0af7d96 | ||
|
|
7a216a8fab | ||
|
|
673169a7ba | ||
|
|
9c7d73c6d6 | ||
|
|
0b830ba9e5 | ||
|
|
c0182bca15 | ||
|
|
8412aae231 | ||
|
|
b9ac334efc | ||
|
|
379bb174e9 | ||
|
|
178e46cd23 | ||
|
|
66744ecb4d | ||
|
|
a7599a0838 | ||
|
|
d5f642938d | ||
|
|
7274467f73 | ||
|
|
7c7ea141f0 | ||
|
|
c66282a460 | ||
|
|
78fe545d18 | ||
|
|
81d09bea44 | ||
|
|
130b176796 | ||
|
|
2e2e9a3702 | ||
|
|
04be1ac4a1 | ||
|
|
a33c10c3ed | ||
|
|
ce042184de | ||
|
|
b1574f9e59 | ||
|
|
9554d063a5 | ||
|
|
3eade2c228 | ||
|
|
71e2b7151c | ||
|
|
d08cfce6cb | ||
|
|
b2ef299efc | ||
|
|
fc8b49485a | ||
|
|
aa32fbf1d6 | ||
|
|
980e592271 | ||
|
|
c6c022dc46 | ||
|
|
261f385b5e | ||
|
|
6e710a20a6 | ||
|
|
46c9e15182 | ||
|
|
5185501b85 | ||
|
|
27d629abb9 | ||
|
|
9d960e29eb | ||
|
|
a1c55a13e1 | ||
|
|
491caf59c1 | ||
|
|
2d47daa8c4 | ||
|
|
25e4a9431c | ||
|
|
3fa4299939 | ||
|
|
90caa5eac9 | ||
|
|
b1adbf7fd7 | ||
|
|
2fadb73032 | ||
|
|
ac81a39e09 | ||
|
|
83247c48c3 | ||
|
|
5de6adfb84 | ||
|
|
d8594f7a78 | ||
|
|
087567655a | ||
|
|
512e1541c6 | ||
|
|
c36981da8b | ||
|
|
d3fa5ed1e8 | ||
|
|
edc5050a2e | ||
|
|
a5efc387c7 | ||
|
|
0062b126b4 | ||
|
|
969f46a48f | ||
|
|
c6f4573a13 | ||
|
|
95037a7d2a | ||
|
|
5218a6e6ab | ||
|
|
5918dd6e65 | ||
|
|
fbf397e15d | ||
|
|
066b8c5ab3 | ||
|
|
634ab45095 | ||
|
|
a4de915b74 | ||
|
|
4a551bde16 | ||
|
|
b809d104d0 | ||
|
|
4133c71105 | ||
|
|
f67aff2704 | ||
|
|
aa8d81511f | ||
|
|
236c1334e3 | ||
|
|
9f21d09dfd | ||
|
|
9dec16d81e | ||
|
|
b086197968 | ||
|
|
e8ea007104 | ||
|
|
e5da2caa34 | ||
|
|
a1edf5cf94 | ||
|
|
6516110c70 | ||
|
|
3a7775fa73 | ||
|
|
5d88d0ee74 | ||
|
|
7b0a84477a | ||
|
|
f78504515b | ||
|
|
ca6a415626 | ||
|
|
f445e0a797 | ||
|
|
204f001c5d | ||
|
|
dc72f74020 | ||
|
|
2b39111e30 | ||
|
|
2bc85b2579 | ||
|
|
0a026cde0c | ||
|
|
db5cf816b4 | ||
|
|
08f288faf1 | ||
|
|
0dabd5e8c7 | ||
|
|
2029ff1903 | ||
|
|
9bc5e98238 | ||
|
|
762f7bcca2 | ||
|
|
75847a0c5b | ||
|
|
e3c2ec9f7c | ||
|
|
fdf40ce07a | ||
|
|
82924679fe | ||
|
|
f373cc770f | ||
|
|
78d74bf8b4 | ||
|
|
5ed2512881 |
@@ -37,10 +37,18 @@ parameters:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
run-osx-publish-arm64:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
run-mas-publish:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
run-mas-publish-arm64:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
run-linux-publish:
|
||||
type: boolean
|
||||
default: false
|
||||
@@ -61,7 +69,7 @@ parameters:
|
||||
# Build machines configs.
|
||||
docker-image: &docker-image
|
||||
docker:
|
||||
- image: electron.azurecr.io/build:4cec2c5ab66765caa724e37bae2bffb9b29722a5
|
||||
- image: electronjs/build:d09fd95029bd8c1c73069888231b29688ef385ed
|
||||
|
||||
machine-linux-medium: &machine-linux-medium
|
||||
<<: *docker-image
|
||||
@@ -77,12 +85,17 @@ machine-linux-2xlarge: &machine-linux-2xlarge
|
||||
|
||||
machine-mac: &machine-mac
|
||||
macos:
|
||||
xcode: "11.1.0"
|
||||
xcode: "11.5.0"
|
||||
|
||||
machine-mac-large: &machine-mac-large
|
||||
resource_class: large
|
||||
macos:
|
||||
xcode: "11.1.0"
|
||||
xcode: "11.5.0"
|
||||
|
||||
machine-mac-large-arm: &machine-mac-large-arm
|
||||
resource_class: large
|
||||
macos:
|
||||
xcode: "12.0.0-UA"
|
||||
|
||||
# Build configurations options.
|
||||
env-testing-build: &env-testing-build
|
||||
@@ -123,6 +136,10 @@ env-arm: &env-arm
|
||||
BUILD_NATIVE_MKSNAPSHOT: 1
|
||||
TARGET_ARCH: arm
|
||||
|
||||
env-apple-silicon: &env-apple-silicon
|
||||
GN_EXTRA_ARGS: 'target_cpu = "arm64"'
|
||||
TARGET_ARCH: arm64
|
||||
|
||||
env-arm64: &env-arm64
|
||||
GN_EXTRA_ARGS: 'target_cpu = "arm64" fatal_linker_warnings = false enable_linux_installer = false'
|
||||
MKSNAPSHOT_TOOLCHAIN: //build/toolchain/linux:clang_arm64
|
||||
@@ -133,6 +150,11 @@ env-mas: &env-mas
|
||||
GN_EXTRA_ARGS: 'is_mas_build = true'
|
||||
MAS_BUILD: 'true'
|
||||
|
||||
env-mas-apple-silicon: &env-mas-apple-silicon
|
||||
GN_EXTRA_ARGS: 'target_cpu = "arm64" is_mas_build = true'
|
||||
MAS_BUILD: 'true'
|
||||
TARGET_ARCH: arm64
|
||||
|
||||
# Misc build configuration options.
|
||||
env-enable-sccache: &env-enable-sccache
|
||||
USE_SCCACHE: true
|
||||
@@ -312,17 +334,25 @@ step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||
name: Free up space on MacOS
|
||||
command: |
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
sudo rm -rf /Library/Developer/CoreSimulator
|
||||
sudo rm -rf $(xcode-select -p)/Platforms/AppleTVOS.platform
|
||||
sudo rm -rf $(xcode-select -p)/Platforms/iPhoneOS.platform
|
||||
sudo rm -rf $(xcode-select -p)/Platforms/WatchOS.platform
|
||||
sudo rm -rf $(xcode-select -p)/Platforms/WatchSimulator.platform
|
||||
sudo rm -rf $(xcode-select -p)/Platforms/AppleTVSimulator.platform
|
||||
sudo rm -rf $(xcode-select -p)/Platforms/iPhoneSimulator.platform
|
||||
sudo rm -rf ~/.rubies
|
||||
sudo rm -rf ~/Library/Caches/Homebrew
|
||||
sudo rm -rf /usr/local/Homebrew
|
||||
sudo mkdir -p $TMPDIR/del-target
|
||||
tmpify() {
|
||||
if [ -d "$1" ]; then
|
||||
sudo mv $1 $TMPDIR/del-target/$(echo $1|shasum -a 256|head -n1|cut -d " " -f1)
|
||||
fi
|
||||
}
|
||||
tmpify /Library/Developer/CoreSimulator
|
||||
tmpify $(xcode-select -p)/Platforms/AppleTVOS.platform
|
||||
tmpify $(xcode-select -p)/Platforms/iPhoneOS.platform
|
||||
tmpify $(xcode-select -p)/Platforms/WatchOS.platform
|
||||
tmpify $(xcode-select -p)/Platforms/WatchSimulator.platform
|
||||
tmpify $(xcode-select -p)/Platforms/AppleTVSimulator.platform
|
||||
tmpify $(xcode-select -p)/Platforms/iPhoneSimulator.platform
|
||||
tmpify ~/.rubies
|
||||
tmpify ~/Library/Caches/Homebrew
|
||||
tmpify /usr/local/Homebrew
|
||||
sudo rm -rf $TMPDIR/del-target
|
||||
fi
|
||||
background: true
|
||||
|
||||
# On macOS delete all .git directories under src/ expect for
|
||||
# third_party/angle/ because of build time generation of file
|
||||
@@ -715,6 +745,8 @@ step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols
|
||||
if [ "$GENERATE_SYMBOLS" == "true" ]; then
|
||||
cd src
|
||||
ninja -C out/Default electron:electron_symbols
|
||||
cd out/Default/breakpad_symbols
|
||||
find . -name \*.sym -print0 | xargs -0 npx @sentry/cli@1.51.1 difutil bundle-sources
|
||||
fi
|
||||
|
||||
step-maybe-zip-symbols: &step-maybe-zip-symbols
|
||||
@@ -743,9 +775,13 @@ step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
|
||||
elif [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
export MKSNAPSHOT_PATH="clang_x64_v8_arm64"
|
||||
fi
|
||||
cp "out/Default/$MKSNAPSHOT_PATH/mksnapshot" out/Default
|
||||
cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.so" out/Default
|
||||
cp "out/Default/$MKSNAPSHOT_PATH/mksnapshot" out/Default
|
||||
cp "out/Default/$MKSNAPSHOT_PATH/v8_context_snapshot_generator" out/Default
|
||||
if [ "`uname`" == "Linux" ]; then
|
||||
cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.so" out/Default
|
||||
elif [ "`uname`" == "Darwin" ]; then
|
||||
cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.dylib" out/Default
|
||||
fi
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
|
||||
mkdir cross-arch-snapshots
|
||||
cp out/Default-mksnapshot-test/*.bin cross-arch-snapshots
|
||||
@@ -764,8 +800,13 @@ step-maybe-trigger-arm-test: &step-maybe-trigger-arm-test
|
||||
# Only run for non-fork prs
|
||||
if [ "$TRIGGER_ARM_TEST" == "true" ] && [ -z "$CIRCLE_PR_NUMBER" ]; then
|
||||
#Trigger VSTS job, passing along CircleCI job number and branch to build
|
||||
echo "Triggering electron-$TARGET_ARCH-testing build on VSTS"
|
||||
node electron/script/release/ci-release-build.js --job=electron-$TARGET_ARCH-testing --ci=VSTS --armTest --circleBuildNum=$CIRCLE_BUILD_NUM $CIRCLE_BRANCH
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
echo "Triggering electron-arm2-testing build on Azure DevOps"
|
||||
node electron/script/release/ci-release-build.js --job=electron-arm2-testing --ci=DevOps --armTest --circleBuildNum=$CIRCLE_BUILD_NUM $CIRCLE_BRANCH
|
||||
else
|
||||
echo "Triggering electron-$TARGET_ARCH-testing build on VSTS"
|
||||
node electron/script/release/ci-release-build.js --job=electron-$TARGET_ARCH-testing --ci=VSTS --armTest --circleBuildNum=$CIRCLE_BUILD_NUM $CIRCLE_BRANCH
|
||||
fi
|
||||
fi
|
||||
|
||||
step-maybe-generate-typescript-defs: &step-maybe-generate-typescript-defs
|
||||
@@ -813,8 +854,13 @@ step-touch-sync-done: &step-touch-sync-done
|
||||
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
|
||||
restore_cache:
|
||||
keys:
|
||||
- v7-src-cache-{{ checksum "src/electron/.depshash" }}
|
||||
- v8-src-cache-{{ checksum "src/electron/.depshash" }}
|
||||
name: Restoring src cache
|
||||
step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
|
||||
restore_cache:
|
||||
keys:
|
||||
- v1-src-cache-marker-{{ checksum "src/electron/.depshash" }}
|
||||
name: Restoring src cache marker
|
||||
|
||||
# Restore exact or closest git cache based on the hash of DEPS and .circle-sync-done
|
||||
# If the src cache was restored above then this will match an empty cache
|
||||
@@ -833,7 +879,7 @@ step-restore-out-cache: &step-restore-out-cache
|
||||
paths:
|
||||
- ./src/out/Default
|
||||
keys:
|
||||
- v8-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
- v9-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
name: Restoring out cache
|
||||
|
||||
step-set-git-cache-path: &step-set-git-cache-path
|
||||
@@ -857,7 +903,7 @@ step-save-out-cache: &step-save-out-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- ./src/out/Default
|
||||
key: v8-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
key: v9-out-cache-{{ checksum "src/electron/.depshash" }}-{{ checksum "src/electron/.depshash-target" }}
|
||||
name: Persisting out cache
|
||||
|
||||
step-run-electron-only-hooks: &step-run-electron-only-hooks
|
||||
@@ -891,9 +937,18 @@ step-minimize-workspace-size-from-checkout: &step-minimize-workspace-size-from-c
|
||||
step-save-src-cache: &step-save-src-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- /portal
|
||||
key: v7-src-cache-{{ checksum "/portal/src/electron/.depshash" }}
|
||||
- /var/portal
|
||||
key: v8-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
name: Persisting src cache
|
||||
step-make-src-cache-marker: &step-make-src-cache-marker
|
||||
run:
|
||||
name: Making src cache marker
|
||||
command: touch .src-cache-marker
|
||||
step-save-src-cache-marker: &step-save-src-cache-marker
|
||||
save_cache:
|
||||
paths:
|
||||
- .src-cache-marker
|
||||
key: v1-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
|
||||
# Check for doc only change
|
||||
step-check-for-doc-only-change: &step-check-for-doc-only-change
|
||||
@@ -999,7 +1054,8 @@ steps-checkout-and-save-cache: &steps-checkout-and-save-cache
|
||||
|
||||
- *step-generate-deps-hash
|
||||
- *step-touch-sync-done
|
||||
- maybe-restore-portaled-src-cache
|
||||
- maybe-restore-portaled-src-cache:
|
||||
halt-if-successful: true
|
||||
- *step-maybe-restore-git-cache
|
||||
- *step-set-git-cache-path
|
||||
# This sync call only runs if .circle-sync-done is an EMPTY file
|
||||
@@ -1020,10 +1076,12 @@ steps-checkout-and-save-cache: &steps-checkout-and-save-cache
|
||||
- run:
|
||||
name: Move src folder to the cross-OS portal
|
||||
command: |
|
||||
sudo mkdir -p /portal
|
||||
sudo chown -R $(id -u):$(id -g) /portal
|
||||
mv ./src /portal
|
||||
sudo mkdir -p /var/portal
|
||||
sudo chown -R $(id -u):$(id -g) /var/portal
|
||||
mv ./src /var/portal
|
||||
- *step-save-src-cache
|
||||
- *step-make-src-cache-marker
|
||||
- *step-save-src-cache-marker
|
||||
|
||||
steps-electron-gn-check: &steps-electron-gn-check
|
||||
steps:
|
||||
@@ -1227,20 +1285,34 @@ chromium-upgrade-branches: &chromium-upgrade-branches
|
||||
# Command Aliases
|
||||
commands:
|
||||
maybe-restore-portaled-src-cache:
|
||||
parameters:
|
||||
halt-if-successful:
|
||||
type: boolean
|
||||
default: false
|
||||
steps:
|
||||
- run:
|
||||
name: Prepare for cross-OS sync restore
|
||||
command: |
|
||||
sudo mkdir -p /portal
|
||||
sudo chown -R $(id -u):$(id -g) /portal
|
||||
sudo mkdir -p /var/portal
|
||||
sudo chown -R $(id -u):$(id -g) /var/portal
|
||||
- when:
|
||||
condition: << parameters.halt-if-successful >>
|
||||
steps:
|
||||
- *step-maybe-restore-src-cache-marker
|
||||
- run:
|
||||
name: Halt the job early if the src cache exists
|
||||
command: |
|
||||
if [ -f ".src-cache-marker" ]; then
|
||||
circleci-agent step halt
|
||||
fi
|
||||
- *step-maybe-restore-src-cache
|
||||
- run:
|
||||
name: Fix the src cache restore point on macOS
|
||||
command: |
|
||||
if [ -d "/portal/src" ]; then
|
||||
if [ -d "/var/portal/src" ]; then
|
||||
echo Relocating Cache
|
||||
rm -rf src
|
||||
mv /portal/src ./
|
||||
mv /var/portal/src ./
|
||||
fi
|
||||
checkout-from-cache:
|
||||
steps:
|
||||
@@ -1703,7 +1775,7 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
@@ -1715,7 +1787,7 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
@@ -1767,7 +1839,7 @@ jobs:
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
@@ -1781,7 +1853,7 @@ jobs:
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
@@ -1834,7 +1906,7 @@ jobs:
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
@@ -1848,7 +1920,7 @@ jobs:
|
||||
<<: *env-32bit-release
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
@@ -1908,7 +1980,7 @@ jobs:
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
@@ -1921,11 +1993,11 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
osx-testing:
|
||||
osx-testing-x64:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
@@ -1940,22 +2012,14 @@ jobs:
|
||||
checkout-and-assume-cache: true
|
||||
attach: false
|
||||
|
||||
osx-testing-gn-check:
|
||||
osx-testing-x64-gn-check:
|
||||
<<: *machine-mac
|
||||
environment:
|
||||
<<: *env-machine-mac
|
||||
<<: *env-testing-build
|
||||
<<: *steps-electron-gn-check
|
||||
|
||||
osx-chromedriver:
|
||||
<<: *machine-mac
|
||||
environment:
|
||||
<<: *env-machine-mac
|
||||
<<: *env-release-build
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-chromedriver-build
|
||||
|
||||
osx-release:
|
||||
osx-release-x64:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
@@ -1969,7 +2033,7 @@ jobs:
|
||||
checkout-and-assume-cache: true
|
||||
attach: false
|
||||
|
||||
osx-publish:
|
||||
osx-publish-x64:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
@@ -1978,11 +2042,25 @@ jobs:
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
osx-publish-skip-checkout:
|
||||
osx-publish-arm64:
|
||||
<<: *machine-mac-large-arm
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-apple-silicon
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
osx-publish-x64-skip-checkout:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
@@ -1990,11 +2068,40 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
mas-testing:
|
||||
osx-publish-arm64-skip-checkout:
|
||||
<<: *machine-mac-large-arm
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
<<: *env-apple-silicon
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
osx-testing-arm64:
|
||||
<<: *machine-mac-large-arm
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
<<: *env-testing-build
|
||||
<<: *env-ninja-status
|
||||
<<: *env-macos-build
|
||||
<<: *env-apple-silicon
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
attach: false
|
||||
|
||||
mas-testing-x64:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
@@ -2010,7 +2117,7 @@ jobs:
|
||||
checkout-and-assume-cache: true
|
||||
attach: false
|
||||
|
||||
mas-testing-gn-check:
|
||||
mas-testing-x64-gn-check:
|
||||
<<: *machine-mac
|
||||
environment:
|
||||
<<: *env-machine-mac
|
||||
@@ -2043,11 +2150,25 @@ jobs:
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
mas-publish-skip-checkout:
|
||||
mas-publish-arm64:
|
||||
<<: *machine-mac-large-arm
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-mas-apple-silicon
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: false
|
||||
checkout: true
|
||||
|
||||
mas-publish-x64-skip-checkout:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
@@ -2056,10 +2177,39 @@ jobs:
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
mas-publish-arm64-skip-checkout:
|
||||
<<: *machine-mac-large-arm
|
||||
environment:
|
||||
<<: *env-mac-large-release
|
||||
<<: *env-mas-apple-silicon
|
||||
<<: *env-release-build
|
||||
<<: *env-enable-sccache
|
||||
UPLOAD_TO_S3: << pipeline.parameters.upload-to-s3 >>
|
||||
steps:
|
||||
- electron-publish:
|
||||
attach: true
|
||||
checkout: false
|
||||
|
||||
mas-testing-arm64:
|
||||
<<: *machine-mac-large-arm
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
<<: *env-testing-build
|
||||
<<: *env-ninja-status
|
||||
<<: *env-macos-build
|
||||
<<: *env-mas-apple-silicon
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
attach: false
|
||||
|
||||
# Layer 3: Tests.
|
||||
linux-x64-unittests:
|
||||
<<: *machine-linux-2xlarge
|
||||
@@ -2183,7 +2333,7 @@ jobs:
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-verify-ffmpeg
|
||||
|
||||
osx-testing-tests:
|
||||
osx-testing-x64-tests:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
@@ -2191,7 +2341,7 @@ jobs:
|
||||
parallelism: 2
|
||||
<<: *steps-tests
|
||||
|
||||
osx-release-tests:
|
||||
osx-release-x64-tests:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
@@ -2206,7 +2356,7 @@ jobs:
|
||||
<<: *env-send-slack-notifications
|
||||
<<: *steps-verify-ffmpeg
|
||||
|
||||
mas-testing-tests:
|
||||
mas-testing-x64-tests:
|
||||
<<: *machine-mac-large
|
||||
environment:
|
||||
<<: *env-mac-large
|
||||
@@ -2270,7 +2420,7 @@ jobs:
|
||||
steps:
|
||||
- *step-maybe-notify-slack-success
|
||||
|
||||
osx-release-summary:
|
||||
osx-release-x64-summary:
|
||||
<<: *machine-mac
|
||||
environment:
|
||||
<<: *env-machine-mac
|
||||
@@ -2335,7 +2485,7 @@ workflows:
|
||||
publish-osx:
|
||||
when: << pipeline.parameters.run-osx-publish >>
|
||||
jobs:
|
||||
- osx-publish:
|
||||
- osx-publish-x64:
|
||||
context: release-env
|
||||
|
||||
publish-mas:
|
||||
@@ -2344,14 +2494,32 @@ workflows:
|
||||
- mas-publish:
|
||||
context: release-env
|
||||
|
||||
publish-osx-arm64:
|
||||
when: << pipeline.parameters.run-osx-publish-arm64 >>
|
||||
jobs:
|
||||
- osx-publish-arm64:
|
||||
context: release-env
|
||||
|
||||
publish-mas-arm64:
|
||||
when: << pipeline.parameters.run-mas-publish-arm64 >>
|
||||
jobs:
|
||||
- mas-publish-arm64:
|
||||
context: release-env
|
||||
|
||||
publish-macos:
|
||||
when: << pipeline.parameters.run-macos-publish >>
|
||||
jobs:
|
||||
- mac-checkout
|
||||
- osx-publish-skip-checkout:
|
||||
- osx-publish-x64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
- mas-publish-skip-checkout:
|
||||
- mas-publish-x64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
- osx-publish-arm64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
- mas-publish-arm64-skip-checkout:
|
||||
requires:
|
||||
- mac-checkout
|
||||
|
||||
@@ -2406,29 +2574,37 @@ workflows:
|
||||
- mac-checkout-fast
|
||||
- mac-checkout-and-save-cache
|
||||
|
||||
- osx-testing:
|
||||
- osx-testing-x64:
|
||||
requires:
|
||||
- mac-checkout-and-save-cache
|
||||
|
||||
- osx-testing-gn-check:
|
||||
- osx-testing-x64-gn-check:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
|
||||
- osx-testing-tests:
|
||||
- osx-testing-x64-tests:
|
||||
requires:
|
||||
- osx-testing
|
||||
- osx-testing-x64
|
||||
|
||||
- mas-testing:
|
||||
- osx-testing-arm64:
|
||||
requires:
|
||||
- mac-checkout-and-save-cache
|
||||
|
||||
- mas-testing-gn-check:
|
||||
- mas-testing-x64:
|
||||
requires:
|
||||
- mac-checkout-and-save-cache
|
||||
|
||||
- mas-testing-x64-gn-check:
|
||||
requires:
|
||||
- mac-checkout-fast
|
||||
|
||||
- mas-testing-tests:
|
||||
- mas-testing-x64-tests:
|
||||
requires:
|
||||
- mas-testing
|
||||
- mas-testing-x64
|
||||
|
||||
- mas-testing-arm64:
|
||||
requires:
|
||||
- mac-checkout-and-save-cache
|
||||
|
||||
nightly-linux-release-test:
|
||||
triggers:
|
||||
@@ -2492,19 +2668,19 @@ workflows:
|
||||
- mac-checkout-fast
|
||||
- mac-checkout-and-save-cache
|
||||
|
||||
- osx-release:
|
||||
- osx-release-x64:
|
||||
requires:
|
||||
- mac-checkout-and-save-cache
|
||||
- osx-release-tests:
|
||||
- osx-release-x64-tests:
|
||||
requires:
|
||||
- osx-release
|
||||
- osx-release-x64
|
||||
- osx-verify-ffmpeg:
|
||||
requires:
|
||||
- osx-release
|
||||
- osx-release-summary:
|
||||
- osx-release-x64
|
||||
- osx-release-x64-summary:
|
||||
requires:
|
||||
- osx-release
|
||||
- osx-release-tests
|
||||
- osx-release-x64
|
||||
- osx-release-x64-tests
|
||||
- osx-verify-ffmpeg
|
||||
|
||||
- mas-release:
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
},
|
||||
"globals": {
|
||||
"standardScheme": "readonly",
|
||||
"globalThis": "readonly",
|
||||
"BUILDFLAG": "readonly",
|
||||
"ENABLE_DESKTOP_CAPTURER": "readonly",
|
||||
"ENABLE_REMOTE_MODULE": "readonly",
|
||||
|
||||
10
.gitattributes
vendored
10
.gitattributes
vendored
@@ -2,13 +2,3 @@
|
||||
# files to be checked out with LF endings even if core.autocrlf is true.
|
||||
*.patch text eol=lf
|
||||
patches/**/.patches merge=union
|
||||
|
||||
# Source code and markdown files should always use LF as line ending.
|
||||
*.cc text eol=lf
|
||||
*.mm text eol=lf
|
||||
*.h text eol=lf
|
||||
*.js text eol=lf
|
||||
*.ts text eol=lf
|
||||
*.py text eol=lf
|
||||
*.ps1 text eol=lf
|
||||
*.md text eol=lf
|
||||
|
||||
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -15,6 +15,7 @@ Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTIN
|
||||
- [ ] relevant documentation is changed or added
|
||||
- [ ] PR title follows semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines)
|
||||
- [ ] [PR release notes](https://github.com/electron/clerk/blob/master/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/master/README.md#examples).
|
||||
- [ ] This is **NOT A BREAKING CHANGE**. Breaking changes may not be merged to master until 11-x-y is branched.
|
||||
|
||||
#### Release Notes
|
||||
|
||||
|
||||
142
BUILD.gn
142
BUILD.gn
@@ -94,6 +94,15 @@ npm_action("build_electron_definitions") {
|
||||
outputs = [ "$target_gen_dir/tsc/typings/electron.d.ts" ]
|
||||
}
|
||||
|
||||
webpack_build("electron_asar_bundle") {
|
||||
deps = [ ":build_electron_definitions" ]
|
||||
|
||||
inputs = auto_filenames.asar_bundle_deps
|
||||
|
||||
config_file = "//electron/build/webpack/webpack.config.asar.js"
|
||||
out_file = "$target_gen_dir/js2c/asar_bundle.js"
|
||||
}
|
||||
|
||||
webpack_build("electron_browser_bundle") {
|
||||
deps = [ ":build_electron_definitions" ]
|
||||
|
||||
@@ -139,25 +148,18 @@ webpack_build("electron_isolated_renderer_bundle") {
|
||||
out_file = "$target_gen_dir/js2c/isolated_bundle.js"
|
||||
}
|
||||
|
||||
copy("electron_js2c_copy") {
|
||||
sources = [
|
||||
"lib/common/asar.js",
|
||||
"lib/common/asar_init.js",
|
||||
]
|
||||
outputs = [ "$target_gen_dir/js2c/{{source_file_part}}" ]
|
||||
}
|
||||
|
||||
action("electron_js2c") {
|
||||
deps = [
|
||||
":electron_asar_bundle",
|
||||
":electron_browser_bundle",
|
||||
":electron_isolated_renderer_bundle",
|
||||
":electron_js2c_copy",
|
||||
":electron_renderer_bundle",
|
||||
":electron_sandboxed_renderer_bundle",
|
||||
":electron_worker_bundle",
|
||||
]
|
||||
|
||||
webpack_sources = [
|
||||
sources = [
|
||||
"$target_gen_dir/js2c/asar_bundle.js",
|
||||
"$target_gen_dir/js2c/browser_init.js",
|
||||
"$target_gen_dir/js2c/isolated_bundle.js",
|
||||
"$target_gen_dir/js2c/renderer_init.js",
|
||||
@@ -165,11 +167,6 @@ action("electron_js2c") {
|
||||
"$target_gen_dir/js2c/worker_init.js",
|
||||
]
|
||||
|
||||
sources = webpack_sources + [
|
||||
"$target_gen_dir/js2c/asar.js",
|
||||
"$target_gen_dir/js2c/asar_init.js",
|
||||
]
|
||||
|
||||
inputs = sources + [ "//third_party/electron_node/tools/js2c.py" ]
|
||||
outputs = [ "$root_gen_dir/electron_natives.cc" ]
|
||||
|
||||
@@ -347,6 +344,7 @@ source_set("electron_lib") {
|
||||
"//device/bluetooth",
|
||||
"//device/bluetooth/public/cpp",
|
||||
"//gin",
|
||||
"//media/blink:blink",
|
||||
"//media/capture/mojom:video_capture",
|
||||
"//media/mojo/mojom",
|
||||
"//net:extras",
|
||||
@@ -362,7 +360,6 @@ source_set("electron_lib") {
|
||||
"//services/viz/privileged/mojom/compositing",
|
||||
"//skia",
|
||||
"//third_party/blink/public:blink",
|
||||
"//third_party/blink/public:blink_devtools_inspector_resources",
|
||||
"//third_party/boringssl",
|
||||
"//third_party/electron_node:node_lib",
|
||||
"//third_party/inspector_protocol:crdtp",
|
||||
@@ -468,7 +465,7 @@ source_set("electron_lib") {
|
||||
deps += [ "//third_party/crashpad/crashpad/client" ]
|
||||
}
|
||||
|
||||
libs = [
|
||||
frameworks = [
|
||||
"AVFoundation.framework",
|
||||
"Carbon.framework",
|
||||
"LocalAuthentication.framework",
|
||||
@@ -495,18 +492,19 @@ source_set("electron_lib") {
|
||||
"shell/common/crash_keys.h",
|
||||
]
|
||||
} else {
|
||||
libs += [
|
||||
frameworks += [
|
||||
"Squirrel.framework",
|
||||
"ReactiveCocoa.framework",
|
||||
"ReactiveObjC.framework",
|
||||
"Mantle.framework",
|
||||
]
|
||||
cflags_objcc = [
|
||||
"-F",
|
||||
rebase_path("external_binaries", root_build_dir),
|
||||
|
||||
deps += [
|
||||
"//third_party/squirrel.mac:reactiveobjc_framework+link",
|
||||
"//third_party/squirrel.mac:squirrel_framework+link",
|
||||
]
|
||||
|
||||
# ReactiveCocoa which is used by Squirrel requires using __weak.
|
||||
cflags_objcc += [ "-fobjc-weak" ]
|
||||
# ReactiveObjC which is used by Squirrel requires using __weak.
|
||||
cflags_objcc = [ "-fobjc-weak" ]
|
||||
}
|
||||
}
|
||||
if (is_linux) {
|
||||
@@ -602,15 +600,6 @@ source_set("electron_lib") {
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_remote_module) {
|
||||
sources += [
|
||||
"shell/common/api/remote/remote_callback_freer.cc",
|
||||
"shell/common/api/remote/remote_callback_freer.h",
|
||||
"shell/common/api/remote/remote_object_freer.cc",
|
||||
"shell/common/api/remote/remote_object_freer.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_desktop_capturer) {
|
||||
if (is_component_build && !is_linux) {
|
||||
# On windows the implementation relies on unexported
|
||||
@@ -669,6 +658,7 @@ source_set("electron_lib") {
|
||||
deps += [
|
||||
"//components/pdf/browser",
|
||||
"//components/pdf/renderer",
|
||||
"//pdf:pdf_ppapi",
|
||||
]
|
||||
sources += [
|
||||
"shell/browser/electron_pdf_web_contents_helper_client.cc",
|
||||
@@ -813,15 +803,13 @@ if (is_mac) {
|
||||
|
||||
include_dirs = [ "." ]
|
||||
sources = filenames.framework_sources
|
||||
libs = []
|
||||
frameworks = []
|
||||
|
||||
if (enable_osr) {
|
||||
libs += [ "IOSurface.framework" ]
|
||||
frameworks += [ "IOSurface.framework" ]
|
||||
}
|
||||
|
||||
ldflags = [
|
||||
"-F",
|
||||
rebase_path("external_binaries", root_build_dir),
|
||||
"-Wl,-install_name,@rpath/$output_name.framework/$output_name",
|
||||
"-rpath",
|
||||
"@loader_path/Libraries",
|
||||
@@ -872,17 +860,49 @@ if (is_mac) {
|
||||
}
|
||||
}
|
||||
|
||||
template("stripped_framework") {
|
||||
action(target_name) {
|
||||
assert(defined(invoker.framework))
|
||||
|
||||
script = "//electron/build/strip_framework.py"
|
||||
|
||||
forward_variables_from(invoker, [ "deps" ])
|
||||
inputs = [ "$root_out_dir/" + invoker.framework ]
|
||||
outputs = [ "$target_out_dir/stripped_frameworks/" + invoker.framework ]
|
||||
|
||||
args = rebase_path(inputs) + rebase_path(outputs)
|
||||
}
|
||||
}
|
||||
|
||||
stripped_framework("stripped_mantle_framework") {
|
||||
framework = "Mantle.framework"
|
||||
deps = [ "//third_party/squirrel.mac:mantle_framework" ]
|
||||
}
|
||||
|
||||
stripped_framework("stripped_reactiveobjc_framework") {
|
||||
framework = "ReactiveObjC.framework"
|
||||
deps = [ "//third_party/squirrel.mac:reactiveobjc_framework" ]
|
||||
}
|
||||
|
||||
stripped_framework("stripped_squirrel_framework") {
|
||||
framework = "Squirrel.framework"
|
||||
deps = [ "//third_party/squirrel.mac:squirrel_framework" ]
|
||||
}
|
||||
|
||||
bundle_data("electron_app_framework_bundle_data") {
|
||||
sources = [ "$root_out_dir/$electron_framework_name.framework" ]
|
||||
if (!is_mas_build) {
|
||||
sources += [
|
||||
"external_binaries/Mantle.framework",
|
||||
"external_binaries/ReactiveCocoa.framework",
|
||||
"external_binaries/Squirrel.framework",
|
||||
]
|
||||
sources += get_target_outputs(":stripped_mantle_framework") +
|
||||
get_target_outputs(":stripped_reactiveobjc_framework") +
|
||||
get_target_outputs(":stripped_squirrel_framework")
|
||||
}
|
||||
outputs = [ "{{bundle_contents_dir}}/Frameworks/{{source_file_part}}" ]
|
||||
public_deps = [ ":electron_framework+link" ]
|
||||
public_deps = [
|
||||
":electron_framework+link",
|
||||
":stripped_mantle_framework",
|
||||
":stripped_reactiveobjc_framework",
|
||||
":stripped_squirrel_framework",
|
||||
]
|
||||
|
||||
foreach(helper_params, content_mac_helpers) {
|
||||
sources +=
|
||||
@@ -895,7 +915,7 @@ if (is_mac) {
|
||||
output_name = electron_login_helper_name
|
||||
sources = filenames.login_helper_sources
|
||||
include_dirs = [ "." ]
|
||||
libs = [ "AppKit.framework" ]
|
||||
frameworks = [ "AppKit.framework" ]
|
||||
info_plist = "shell/app/resources/mac/loginhelper-Info.plist"
|
||||
extra_substitutions =
|
||||
[ "ELECTRON_BUNDLE_ID=$electron_mac_bundle_id.loginhelper" ]
|
||||
@@ -1080,7 +1100,9 @@ if (is_mac) {
|
||||
data += [ "$root_out_dir/resources/default_app.asar" ]
|
||||
}
|
||||
|
||||
public_deps = [ "//tools/v8_context_snapshot:v8_context_snapshot" ]
|
||||
if (use_v8_context_snapshot) {
|
||||
public_deps = [ "//tools/v8_context_snapshot:v8_context_snapshot" ]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
sources += [
|
||||
@@ -1094,17 +1116,20 @@ if (is_mac) {
|
||||
"//components/crash/core/app:run_as_crashpad_handler",
|
||||
]
|
||||
|
||||
ldflags = []
|
||||
|
||||
libs = [
|
||||
"comctl32.lib",
|
||||
"uiautomationcore.lib",
|
||||
"wtsapi32.lib",
|
||||
]
|
||||
|
||||
configs += [
|
||||
"//build/config/win:windowed",
|
||||
"//build/config/win:delayloads",
|
||||
configs += [ "//build/config/win:windowed" ]
|
||||
|
||||
ldflags = [
|
||||
# Windows 7 doesn't have these DLLs.
|
||||
# TODO: are there other DLLs we need to list here to be win7
|
||||
# compatible?
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-string-l1-1-0.dll",
|
||||
]
|
||||
|
||||
# This is to support renaming of electron.exe. node-gyp has hard-coded
|
||||
@@ -1185,18 +1210,6 @@ test("shell_browser_ui_unittests") {
|
||||
"//ui/base",
|
||||
"//ui/strings",
|
||||
]
|
||||
|
||||
if (is_mac) {
|
||||
# Resolve paths owing to different test executable locations
|
||||
ldflags = [
|
||||
"-F",
|
||||
rebase_path("external_binaries", root_build_dir),
|
||||
"-rpath",
|
||||
"@loader_path",
|
||||
"-rpath",
|
||||
"@executable_path/" + rebase_path("external_binaries", root_build_dir),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
template("dist_zip") {
|
||||
@@ -1294,10 +1307,13 @@ dist_zip("electron_chromedriver_zip") {
|
||||
|
||||
mksnapshot_deps = [
|
||||
":licenses",
|
||||
"//tools/v8_context_snapshot:v8_context_snapshot_generator($v8_snapshot_toolchain)",
|
||||
"//v8:mksnapshot($v8_snapshot_toolchain)",
|
||||
]
|
||||
|
||||
if (use_v8_context_snapshot) {
|
||||
mksnapshot_deps += [ "//tools/v8_context_snapshot:v8_context_snapshot_generator($v8_snapshot_toolchain)" ]
|
||||
}
|
||||
|
||||
group("electron_mksnapshot") {
|
||||
public_deps = mksnapshot_deps
|
||||
}
|
||||
|
||||
28
DEPS
28
DEPS
@@ -14,11 +14,13 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'85.0.4183.121',
|
||||
'93a6ebbe22f1a093e6a0cb5e72ba78990fe39824',
|
||||
'node_version':
|
||||
'v12.16.3',
|
||||
'v12.18.3',
|
||||
'nan_version':
|
||||
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
|
||||
'squirrel.mac_version':
|
||||
'44468f858ce0d25c27bd5e674abfa104e0119738',
|
||||
|
||||
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
|
||||
'pyyaml_version': '3.12',
|
||||
@@ -30,6 +32,7 @@ vars = {
|
||||
'nodejs_git': 'https://github.com/nodejs',
|
||||
'requests_git': 'https://github.com/kennethreitz',
|
||||
'yaml_git': 'https://github.com/yaml',
|
||||
'squirrel_git': 'https://github.com/Squirrel',
|
||||
|
||||
# KEEP IN SYNC WITH utils.js FILE
|
||||
'yarn_version': '1.15.2',
|
||||
@@ -104,6 +107,18 @@ deps = {
|
||||
'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',
|
||||
},
|
||||
'src/third_party/squirrel.mac/vendor/ReactiveObjC': {
|
||||
'url': 'https://github.com/ReactiveCocoa/ReactiveObjC.git@74ab5baccc6f7202c8ac69a8d1e152c29dc1ea76',
|
||||
'condition': 'process_deps'
|
||||
},
|
||||
'src/third_party/squirrel.mac/vendor/Mantle': {
|
||||
'url': 'https://github.com/Mantle/Mantle.git@78d3966b3c331292ea29ec38661b25df0a245948',
|
||||
'condition': 'process_deps',
|
||||
}
|
||||
}
|
||||
|
||||
hooks = [
|
||||
@@ -112,7 +127,7 @@ hooks = [
|
||||
'condition': '(checkout_chromium and apply_patches) and process_deps',
|
||||
'pattern': 'src/electron',
|
||||
'action': [
|
||||
'python',
|
||||
'python3',
|
||||
'src/electron/script/apply_all_patches.py',
|
||||
'src/electron/patches/config.json',
|
||||
],
|
||||
@@ -130,7 +145,7 @@ hooks = [
|
||||
'name': 'electron_npm_deps',
|
||||
'pattern': 'src/electron/package.json',
|
||||
'action': [
|
||||
'python',
|
||||
'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"]);',
|
||||
],
|
||||
@@ -140,7 +155,7 @@ hooks = [
|
||||
'pattern': 'src/electron',
|
||||
'condition': 'checkout_boto and process_deps',
|
||||
'action': [
|
||||
'python',
|
||||
'python3',
|
||||
'-c',
|
||||
'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "boto")); subprocess.check_call(["python", "setup.py", "build"]);',
|
||||
],
|
||||
@@ -150,7 +165,7 @@ hooks = [
|
||||
'pattern': 'src/electron',
|
||||
'condition': 'checkout_requests and process_deps',
|
||||
'action': [
|
||||
'python',
|
||||
'python3',
|
||||
'-c',
|
||||
'import os, subprocess; os.chdir(os.path.join("src", "electron", "vendor", "requests")); subprocess.check_call(["python", "setup.py", "build"]);',
|
||||
],
|
||||
@@ -159,4 +174,5 @@ hooks = [
|
||||
|
||||
recursedeps = [
|
||||
'src',
|
||||
'src/third_party/squirrel.mac',
|
||||
]
|
||||
|
||||
@@ -1 +1 @@
|
||||
10.1.5
|
||||
11.0.0-nightly.20200729
|
||||
@@ -53,9 +53,7 @@ build_script:
|
||||
} else {
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
|
||||
$result = node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
|
||||
Write-Output $result
|
||||
if ($result.ExitCode -eq 0) {
|
||||
if ($(node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH;$LASTEXITCODE -eq 0)) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
}
|
||||
@@ -63,6 +61,7 @@ build_script:
|
||||
- git config --global core.longpaths true
|
||||
- cd ..
|
||||
- mkdir src
|
||||
- update_depot_tools.bat
|
||||
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: $env:SCCACHE_PATH="$pwd\src\electron\external_binaries\sccache.exe"
|
||||
|
||||
104
azure-pipelines-arm.yml
Normal file
104
azure-pipelines-arm.yml
Normal file
@@ -0,0 +1,104 @@
|
||||
steps:
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy Files to: src/electron'
|
||||
inputs:
|
||||
TargetFolder: src/electron
|
||||
|
||||
- bash: |
|
||||
cd src/electron
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
displayName: 'Yarn install'
|
||||
|
||||
- bash: |
|
||||
export ZIP_DEST=$PWD/src/out/Default
|
||||
echo "##vso[task.setvariable variable=ZIP_DEST]$ZIP_DEST"
|
||||
mkdir -p $ZIP_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=dist.zip --dest=$ZIP_DEST
|
||||
cd $ZIP_DEST
|
||||
unzip -o dist.zip
|
||||
displayName: 'Download and unzip dist files for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export FFMPEG_ZIP_DEST=$PWD/src/out/ffmpeg
|
||||
mkdir -p $FFMPEG_ZIP_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=ffmpeg.zip --dest=$FFMPEG_ZIP_DEST
|
||||
cd $FFMPEG_ZIP_DEST
|
||||
unzip -o ffmpeg.zip
|
||||
displayName: 'Download and unzip ffmpeg for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export NODE_HEADERS_DEST=$PWD/src/out/Default/gen
|
||||
mkdir -p $NODE_HEADERS_DEST
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=node_headers.tar.gz --dest=$NODE_HEADERS_DEST
|
||||
cd $NODE_HEADERS_DEST
|
||||
tar xzf node_headers.tar.gz
|
||||
displayName: 'Download and untar node header files for test'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export CROSS_ARCH_SNAPSHOTS=$PWD/src/out/Default/cross-arch-snapshots
|
||||
mkdir -p $CROSS_ARCH_SNAPSHOTS
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/snapshot_blob.bin --dest=$CROSS_ARCH_SNAPSHOTS
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/v8_context_snapshot.bin --dest=$CROSS_ARCH_SNAPSHOTS
|
||||
displayName: 'Download cross arch snapshot files'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
export NATIVE_UNITTESTS_DEST=$PWD/src/out/Default
|
||||
cd src/electron
|
||||
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=shell_browser_ui_unittests --dest=$NATIVE_UNITTESTS_DEST
|
||||
chmod +x $NATIVE_UNITTESTS_DEST/shell_browser_ui_unittests
|
||||
displayName: 'Download native unittest executables'
|
||||
env:
|
||||
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
export ELECTRON_OUT_DIR=Default
|
||||
set npm_config_arch=arm64
|
||||
(cd electron && node script/yarn test -- --enable-logging)
|
||||
displayName: 'Run Electron tests'
|
||||
timeoutInMinutes: 20
|
||||
env:
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
python electron/script/verify-ffmpeg.py --source-root "$PWD" --build-dir out/Default --ffmpeg-path out/ffmpeg
|
||||
displayName: Verify non proprietary ffmpeg
|
||||
timeoutInMinutes: 5
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- bash: |
|
||||
cd src
|
||||
echo Verify cross arch snapshot
|
||||
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/out/Default/cross-arch-snapshots
|
||||
displayName: Verify cross arch snapshot
|
||||
timeoutInMinutes: 5
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results'
|
||||
inputs:
|
||||
testResultsFiles: '*.xml'
|
||||
|
||||
searchFolder: '$(System.DefaultWorkingDirectory)/src/junit/'
|
||||
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
|
||||
displayName: 'Clean Agent Directories'
|
||||
|
||||
condition: always()
|
||||
@@ -87,11 +87,7 @@ steps:
|
||||
|
||||
- powershell: |
|
||||
Get-Process | Where Name –Like "electron*" | Stop-Process
|
||||
Get-Process | Where Name –Like "MicrosoftEdge*" | Stop-Process
|
||||
Get-Process | Where Name –Like "msedge*" | Stop-Process
|
||||
displayName: 'Kill processes left running from last test run'
|
||||
condition: always()
|
||||
|
||||
- powershell: |
|
||||
Remove-Item -path $env:APPDATA/Electron* -Recurse
|
||||
displayName: 'Delete user app data directories'
|
||||
condition: always()
|
||||
|
||||
16
build/strip_framework.py
Executable file
16
build/strip_framework.py
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
source = sys.argv[1]
|
||||
dest = sys.argv[2]
|
||||
|
||||
# Ensure any existing framework is removed
|
||||
subprocess.check_output(["rm", "-rf", dest])
|
||||
|
||||
subprocess.check_output(["cp", "-a", source, dest])
|
||||
|
||||
# Strip headers, we do not need to ship them
|
||||
subprocess.check_output(["rm", "-r", os.path.join(dest, 'Headers')])
|
||||
subprocess.check_output(["rm", "-r", os.path.join(dest, 'Versions', 'Current', 'Headers')])
|
||||
@@ -1,2 +1,2 @@
|
||||
process.env.PRINT_WEBPACK_GRAPH = true
|
||||
require('./run-compiler')
|
||||
process.env.PRINT_WEBPACK_GRAPH = true;
|
||||
require('./run-compiler');
|
||||
|
||||
@@ -1,36 +1,29 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const configPath = process.argv[2]
|
||||
const outPath = path.resolve(process.argv[3])
|
||||
const config = require(configPath)
|
||||
const configPath = process.argv[2];
|
||||
const outPath = path.resolve(process.argv[3]);
|
||||
const config = require(configPath);
|
||||
config.output = {
|
||||
path: path.dirname(outPath),
|
||||
filename: path.basename(outPath)
|
||||
}
|
||||
};
|
||||
|
||||
const { wrapInitWithProfilingTimeout, wrapInitWithTryCatch, ...webpackConfig } = config;
|
||||
const { wrapInitWithProfilingTimeout } = config;
|
||||
delete config.wrapInitWithProfilingTimeout;
|
||||
|
||||
webpack(webpackConfig, (err, stats) => {
|
||||
webpack(config, (err, stats) => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
} else if (stats.hasErrors()) {
|
||||
console.error(stats.toString('normal'))
|
||||
process.exit(1)
|
||||
console.error(stats.toString('normal'));
|
||||
process.exit(1);
|
||||
} else {
|
||||
let contents = fs.readFileSync(outPath, 'utf8');
|
||||
if (wrapInitWithTryCatch) {
|
||||
contents = `try {
|
||||
${contents}
|
||||
} catch (err) {
|
||||
console.error('Electron ${webpackConfig.output.filename} script failed to run');
|
||||
console.error(err);
|
||||
}`;
|
||||
}
|
||||
if (wrapInitWithProfilingTimeout) {
|
||||
contents = `function ___electron_webpack_init__() {
|
||||
const contents = fs.readFileSync(outPath, 'utf8');
|
||||
const newContents = `function ___electron_webpack_init__() {
|
||||
${contents}
|
||||
};
|
||||
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
|
||||
@@ -38,8 +31,8 @@ if ((globalThis.process || binding.process).argv.includes("--profile-electron-in
|
||||
} else {
|
||||
___electron_webpack_init__();
|
||||
}`;
|
||||
fs.writeFileSync(outPath, newContents);
|
||||
}
|
||||
fs.writeFileSync(outPath, contents)
|
||||
process.exit(0)
|
||||
process.exit(0);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
5
build/webpack/webpack.config.asar.js
Normal file
5
build/webpack/webpack.config.asar.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'asar',
|
||||
alwaysHasNode: true,
|
||||
targetDeletesNodeGlobals: true
|
||||
});
|
||||
@@ -1,39 +1,39 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
|
||||
const electronRoot = path.resolve(__dirname, '../..')
|
||||
const electronRoot = path.resolve(__dirname, '../..');
|
||||
|
||||
const onlyPrintingGraph = !!process.env.PRINT_WEBPACK_GRAPH
|
||||
const onlyPrintingGraph = !!process.env.PRINT_WEBPACK_GRAPH;
|
||||
|
||||
class AccessDependenciesPlugin {
|
||||
apply(compiler) {
|
||||
apply (compiler) {
|
||||
// Only hook into webpack when we are printing the dependency graph
|
||||
if (!onlyPrintingGraph) return
|
||||
if (!onlyPrintingGraph) return;
|
||||
|
||||
compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
|
||||
compilation.hooks.finishModules.tap('AccessDependenciesPlugin', modules => {
|
||||
const filePaths = modules.map(m => m.resource).filter(p => p).map(p => path.relative(electronRoot, p))
|
||||
console.info(JSON.stringify(filePaths))
|
||||
})
|
||||
})
|
||||
const filePaths = modules.map(m => m.resource).filter(p => p).map(p => path.relative(electronRoot, p));
|
||||
console.info(JSON.stringify(filePaths));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const defines = {
|
||||
BUILDFLAG: onlyPrintingGraph ? '(a => a)' : ''
|
||||
}
|
||||
};
|
||||
|
||||
const buildFlagsPrefix = '--buildflags='
|
||||
const buildFlagsPrefix = '--buildflags=';
|
||||
const buildFlagArg = process.argv.find(arg => arg.startsWith(buildFlagsPrefix));
|
||||
|
||||
if (buildFlagArg) {
|
||||
const buildFlagPath = buildFlagArg.substr(buildFlagsPrefix.length)
|
||||
const buildFlagPath = buildFlagArg.substr(buildFlagsPrefix.length);
|
||||
|
||||
const flagFile = fs.readFileSync(buildFlagPath, 'utf8')
|
||||
const flagFile = fs.readFileSync(buildFlagPath, 'utf8');
|
||||
for (const line of flagFile.split(/(\r\n|\r|\n)/g)) {
|
||||
const flagMatch = line.match(/#define BUILDFLAG_INTERNAL_(.+?)\(\) \(([01])\)/)
|
||||
const flagMatch = line.match(/#define BUILDFLAG_INTERNAL_(.+?)\(\) \(([01])\)/);
|
||||
if (flagMatch) {
|
||||
const [, flagName, flagValue] = flagMatch;
|
||||
defines[flagName] = JSON.stringify(Boolean(parseInt(flagValue, 10)));
|
||||
@@ -41,27 +41,27 @@ if (buildFlagArg) {
|
||||
}
|
||||
}
|
||||
|
||||
const ignoredModules = []
|
||||
const ignoredModules = [];
|
||||
|
||||
if (defines['ENABLE_DESKTOP_CAPTURER'] === 'false') {
|
||||
if (defines.ENABLE_DESKTOP_CAPTURER === 'false') {
|
||||
ignoredModules.push(
|
||||
'@electron/internal/browser/desktop-capturer',
|
||||
'@electron/internal/browser/api/desktop-capturer',
|
||||
'@electron/internal/renderer/api/desktop-capturer'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (defines['ENABLE_REMOTE_MODULE'] === 'false') {
|
||||
if (defines.ENABLE_REMOTE_MODULE === 'false') {
|
||||
ignoredModules.push(
|
||||
'@electron/internal/browser/remote/server',
|
||||
'@electron/internal/renderer/api/remote'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (defines['ENABLE_VIEWS_API'] === 'false') {
|
||||
if (defines.ENABLE_VIEWS_API === 'false') {
|
||||
ignoredModules.push(
|
||||
'@electron/internal/browser/api/views/image-view.js'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = ({
|
||||
@@ -69,14 +69,15 @@ module.exports = ({
|
||||
loadElectronFromAlternateTarget,
|
||||
targetDeletesNodeGlobals,
|
||||
target,
|
||||
wrapInitWithProfilingTimeout,
|
||||
wrapInitWithTryCatch
|
||||
wrapInitWithProfilingTimeout
|
||||
}) => {
|
||||
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts')
|
||||
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts');
|
||||
if (!fs.existsSync(entry)) {
|
||||
entry = path.resolve(electronRoot, 'lib', target, 'init.js')
|
||||
entry = path.resolve(electronRoot, 'lib', target, 'init.js');
|
||||
}
|
||||
|
||||
const electronAPIFile = path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts');
|
||||
|
||||
return ({
|
||||
mode: 'development',
|
||||
devtool: false,
|
||||
@@ -86,20 +87,22 @@ module.exports = ({
|
||||
filename: `${target}.bundle.js`
|
||||
},
|
||||
wrapInitWithProfilingTimeout,
|
||||
wrapInitWithTryCatch,
|
||||
resolve: {
|
||||
alias: {
|
||||
'@electron/internal': path.resolve(electronRoot, 'lib'),
|
||||
'electron': path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts'),
|
||||
electron$: electronAPIFile,
|
||||
'electron/main$': electronAPIFile,
|
||||
'electron/renderer$': electronAPIFile,
|
||||
'electron/common$': electronAPIFile,
|
||||
// Force timers to resolve to our dependency that doesn't use window.postMessage
|
||||
'timers': path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
|
||||
timers: path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
|
||||
},
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
module: {
|
||||
rules: [{
|
||||
test: (moduleName) => !onlyPrintingGraph && ignoredModules.includes(moduleName),
|
||||
loader: 'null-loader',
|
||||
loader: 'null-loader'
|
||||
}, {
|
||||
test: /\.ts$/,
|
||||
loader: 'ts-loader',
|
||||
@@ -108,7 +111,7 @@ module.exports = ({
|
||||
transpileOnly: onlyPrintingGraph,
|
||||
ignoreDiagnostics: [
|
||||
// File '{0}' is not under 'rootDir' '{1}'.
|
||||
6059,
|
||||
6059
|
||||
]
|
||||
}
|
||||
}]
|
||||
@@ -118,7 +121,7 @@ module.exports = ({
|
||||
__filename: false,
|
||||
// We provide our own "timers" import above, any usage of setImmediate inside
|
||||
// one of our renderer bundles should import it from the 'timers' package
|
||||
setImmediate: false,
|
||||
setImmediate: false
|
||||
},
|
||||
optimization: {
|
||||
minimize: true,
|
||||
@@ -126,24 +129,24 @@ module.exports = ({
|
||||
new TerserPlugin({
|
||||
terserOptions: {
|
||||
keep_classnames: true,
|
||||
keep_fnames: true,
|
||||
},
|
||||
}),
|
||||
],
|
||||
keep_fnames: true
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new AccessDependenciesPlugin(),
|
||||
...(targetDeletesNodeGlobals ? [
|
||||
new webpack.ProvidePlugin({
|
||||
process: ['@electron/internal/renderer/webpack-provider', 'process'],
|
||||
global: ['@electron/internal/renderer/webpack-provider', '_global'],
|
||||
Buffer: ['@electron/internal/renderer/webpack-provider', 'Buffer'],
|
||||
process: ['@electron/internal/common/webpack-provider', 'process'],
|
||||
global: ['@electron/internal/common/webpack-provider', '_global'],
|
||||
Buffer: ['@electron/internal/common/webpack-provider', 'Buffer']
|
||||
})
|
||||
] : []),
|
||||
new webpack.ProvidePlugin({
|
||||
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise'],
|
||||
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise']
|
||||
}),
|
||||
new webpack.DefinePlugin(defines),
|
||||
new webpack.DefinePlugin(defines)
|
||||
]
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'browser',
|
||||
alwaysHasNode: true
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'isolated_renderer',
|
||||
alwaysHasNode: false,
|
||||
wrapInitWithTryCatch: true
|
||||
})
|
||||
alwaysHasNode: false
|
||||
});
|
||||
|
||||
@@ -2,6 +2,5 @@ module.exports = require('./webpack.config.base')({
|
||||
target: 'renderer',
|
||||
alwaysHasNode: true,
|
||||
targetDeletesNodeGlobals: true,
|
||||
wrapInitWithProfilingTimeout: true,
|
||||
wrapInitWithTryCatch: true
|
||||
})
|
||||
wrapInitWithProfilingTimeout: true
|
||||
});
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
module.exports = require('./webpack.config.base')({
|
||||
target: 'sandboxed_renderer',
|
||||
alwaysHasNode: false,
|
||||
wrapInitWithProfilingTimeout: true,
|
||||
wrapInitWithTryCatch: true
|
||||
})
|
||||
wrapInitWithProfilingTimeout: true
|
||||
});
|
||||
|
||||
@@ -2,6 +2,5 @@ module.exports = require('./webpack.config.base')({
|
||||
target: 'worker',
|
||||
loadElectronFromAlternateTarget: 'renderer',
|
||||
alwaysHasNode: true,
|
||||
targetDeletesNodeGlobals: true,
|
||||
wrapInitWithTryCatch: true
|
||||
})
|
||||
targetDeletesNodeGlobals: true
|
||||
});
|
||||
|
||||
@@ -32,6 +32,8 @@ PATHS_TO_SKIP = [
|
||||
# On Linux, we don't use crashpad, but this binary is still built for some
|
||||
# reason. Exclude it from the zip.
|
||||
'./crashpad_handler',
|
||||
|
||||
'resources/inspector', #Skipping because these are outputs that we don't need
|
||||
]
|
||||
|
||||
def skip_path(dep, dist_zip, target_cpu):
|
||||
|
||||
@@ -12,6 +12,8 @@ import("//third_party/widevine/cdm/widevine.gni")
|
||||
static_library("chrome") {
|
||||
visibility = [ "//electron:electron_lib" ]
|
||||
sources = [
|
||||
"//chrome/browser/accessibility/accessibility_ui.cc",
|
||||
"//chrome/browser/accessibility/accessibility_ui.h",
|
||||
"//chrome/browser/browser_process.cc",
|
||||
"//chrome/browser/browser_process.h",
|
||||
"//chrome/browser/crash_upload_list/crash_upload_list_crashpad.cc",
|
||||
@@ -62,18 +64,20 @@ static_library("chrome") {
|
||||
"//extensions/browser/app_window/size_constraints.cc",
|
||||
"//extensions/browser/app_window/size_constraints.h",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
"//chrome/common",
|
||||
"//chrome/common:version_header",
|
||||
"//components/keyed_service/content",
|
||||
"//components/paint_preview/buildflags",
|
||||
"//components/proxy_config",
|
||||
"//components/security_state/content",
|
||||
"//content/public/browser",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//chrome/browser:resource_prefetch_predictor_proto",
|
||||
"//chrome/services/speech:buildflags",
|
||||
"//components/feature_engagement:buildflags",
|
||||
"//components/optimization_guide/proto:optimization_guide_proto",
|
||||
]
|
||||
|
||||
@@ -267,7 +271,7 @@ static_library("chrome") {
|
||||
source_set("plugins") {
|
||||
sources = []
|
||||
deps = []
|
||||
libs = []
|
||||
frameworks = []
|
||||
|
||||
# browser side
|
||||
sources += [
|
||||
@@ -301,7 +305,7 @@ source_set("plugins") {
|
||||
"//chrome/browser/renderer_host/pepper/monitor_finder_mac.h",
|
||||
"//chrome/browser/renderer_host/pepper/monitor_finder_mac.mm",
|
||||
]
|
||||
libs += [ "CoreGraphics.framework" ]
|
||||
frameworks += [ "CoreGraphics.framework" ]
|
||||
}
|
||||
if (is_linux) {
|
||||
deps += [ "//components/services/font/public/cpp" ]
|
||||
@@ -365,8 +369,8 @@ source_set("chrome_spellchecker") {
|
||||
"//chrome/browser/spellchecker/spellcheck_factory.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blacklist_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blocklist_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_blocklist_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.cc",
|
||||
"//chrome/browser/spellchecker/spellcheck_language_policy_handler.h",
|
||||
"//chrome/browser/spellchecker/spellcheck_service.cc",
|
||||
|
||||
@@ -36,7 +36,6 @@ net::NSSCertDatabase* GetNSSCertDatabaseForResourceContext(
|
||||
// Linux has only a single persistent slot compared to ChromeOS's separate
|
||||
// public and private slot.
|
||||
// Redirect any slot usage to this persistent slot on Linux.
|
||||
crypto::EnsureNSSInit();
|
||||
g_nss_cert_database = new net::NSSCertDatabase(
|
||||
crypto::ScopedPK11Slot(PK11_GetInternalKeySlot()) /* public slot */,
|
||||
crypto::ScopedPK11Slot(PK11_GetInternalKeySlot()) /* private slot */);
|
||||
|
||||
@@ -53,31 +53,31 @@
|
||||
<nav>
|
||||
<div class="linkcol">
|
||||
<a class="hero-link" target="_blank" href="https://electronjs.org/blog">
|
||||
<span class="octicon hero-octicon octicon-gist" aria-hidden="true"></span>
|
||||
<span class="octicon hero-octicon octicon-code-square-24" aria-hidden="true"></span>
|
||||
<h4>Blog</h4>
|
||||
</a>
|
||||
</div>
|
||||
<div class="linkcol">
|
||||
<a class="hero-link" target="_blank" href="https://github.com/electron/electron">
|
||||
<span class="octicon hero-octicon octicon-mark-github" aria-hidden="true"></span>
|
||||
<span class="octicon hero-octicon octicon-mark-github-16" aria-hidden="true"></span>
|
||||
<h4>Repository</h4>
|
||||
</a>
|
||||
</div>
|
||||
<div class="linkcol">
|
||||
<a class="hero-link" target="_blank" href="https://electronjs.org/docs">
|
||||
<span class="octicon hero-octicon octicon-gear" aria-hidden="true"></span>
|
||||
<span class="octicon hero-octicon octicon-book-24" aria-hidden="true"></span>
|
||||
<h4>Docs</h4>
|
||||
</a>
|
||||
</div>
|
||||
<div class="linkcol">
|
||||
<a class="hero-link" target="_blank" href="https://github.com/electron/electron-api-demos">
|
||||
<span class="octicon hero-octicon octicon-star" aria-hidden="true"></span>
|
||||
<span class="octicon hero-octicon octicon-star-fill-24" aria-hidden="true"></span>
|
||||
<h4>API Demos</h4>
|
||||
</a>
|
||||
</div>
|
||||
<div class="linkcol">
|
||||
<a class="hero-link" target="_blank" href="https://electronforge.io">
|
||||
<span class="octicon hero-octicon octicon-gift" aria-hidden="true"></span>
|
||||
<span class="octicon hero-octicon octicon-gift-24" aria-hidden="true"></span>
|
||||
<h4>Forge</h4>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { app, dialog } from 'electron';
|
||||
import * as electron from 'electron';
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as url from 'url';
|
||||
const { app, dialog } = electron;
|
||||
|
||||
type DefaultAppOptions = {
|
||||
file: null | string;
|
||||
@@ -145,13 +146,90 @@ function startRepl () {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// prevent quitting
|
||||
// Prevent quitting.
|
||||
app.on('window-all-closed', () => {});
|
||||
|
||||
const repl = require('repl');
|
||||
repl.start('> ').on('exit', () => {
|
||||
const GREEN = '32';
|
||||
const colorize = (color: string, s: string) => `\x1b[${color}m${s}\x1b[0m`;
|
||||
const electronVersion = colorize(GREEN, `v${process.versions.electron}`);
|
||||
const nodeVersion = colorize(GREEN, `v${process.versions.node}`);
|
||||
|
||||
console.info(`
|
||||
Welcome to the Electron.js REPL \\[._.]/
|
||||
|
||||
You can access all Electron.js modules here as well as Node.js modules.
|
||||
Using: Node.js ${nodeVersion} and Electron.js ${electronVersion}
|
||||
`);
|
||||
|
||||
const { REPLServer } = require('repl');
|
||||
const repl = new REPLServer({
|
||||
prompt: '> '
|
||||
}).on('exit', () => {
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
function defineBuiltin (context: any, name: string, getter: Function) {
|
||||
const setReal = (val: any) => {
|
||||
// Deleting the property before re-assigning it disables the
|
||||
// getter/setter mechanism.
|
||||
delete context[name];
|
||||
context[name] = val;
|
||||
};
|
||||
|
||||
Object.defineProperty(context, name, {
|
||||
get: () => {
|
||||
const lib = getter();
|
||||
|
||||
delete context[name];
|
||||
Object.defineProperty(context, name, {
|
||||
get: () => lib,
|
||||
set: setReal,
|
||||
configurable: true,
|
||||
enumerable: false
|
||||
});
|
||||
|
||||
return lib;
|
||||
},
|
||||
set: setReal,
|
||||
configurable: true,
|
||||
enumerable: false
|
||||
});
|
||||
}
|
||||
|
||||
defineBuiltin(repl.context, 'electron', () => electron);
|
||||
for (const api of Object.keys(electron) as (keyof typeof electron)[]) {
|
||||
defineBuiltin(repl.context, api, () => electron[api]);
|
||||
}
|
||||
|
||||
// Copied from node/lib/repl.js. For better DX, we don't want to
|
||||
// show e.g 'contentTracing' at a higher priority than 'const', so
|
||||
// we only trigger custom tab-completion when no common words are
|
||||
// potentially matches.
|
||||
const commonWords = [
|
||||
'async', 'await', 'break', 'case', 'catch', 'const', 'continue',
|
||||
'debugger', 'default', 'delete', 'do', 'else', 'export', 'false',
|
||||
'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof', 'let',
|
||||
'new', 'null', 'return', 'switch', 'this', 'throw', 'true', 'try',
|
||||
'typeof', 'var', 'void', 'while', 'with', 'yield'
|
||||
];
|
||||
|
||||
const electronBuiltins = [...Object.keys(electron), 'original-fs', 'electron'];
|
||||
|
||||
const defaultComplete = repl.completer;
|
||||
repl.completer = (line: string, callback: Function) => {
|
||||
const lastSpace = line.lastIndexOf(' ');
|
||||
const currentSymbol = line.substring(lastSpace + 1, repl.cursor);
|
||||
|
||||
const filterFn = (c: string) => c.startsWith(currentSymbol);
|
||||
const ignores = commonWords.filter(filterFn);
|
||||
const hits = electronBuiltins.filter(filterFn);
|
||||
|
||||
if (!ignores.length && hits.length) {
|
||||
callback(null, [hits, currentSymbol]);
|
||||
} else {
|
||||
defaultComplete.apply(repl, [line, callback]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Start the specified app if there is one specified in command line, otherwise
|
||||
|
||||
@@ -92,7 +92,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)
|
||||
* [App Feedback Program](tutorial/app-feedback-program.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)
|
||||
|
||||
@@ -140,6 +140,16 @@ this event, such as launching the application for the first time, attempting
|
||||
to re-launch the application when it's already running, or clicking on the
|
||||
application's dock or taskbar icon.
|
||||
|
||||
### Event: 'did-become-active' _macOS_
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
|
||||
Emitted when mac application become active. Difference from `activate` event is
|
||||
that `did-become-active` is emitted every time the app becomes active, not only
|
||||
when Dock icon is clicked or application is re-launched.
|
||||
|
||||
### Event: 'continue-activity' _macOS_
|
||||
|
||||
Returns:
|
||||
@@ -350,7 +360,7 @@ page.
|
||||
|
||||
Emitted whenever there is a GPU info update.
|
||||
|
||||
### Event: 'gpu-process-crashed'
|
||||
### Event: 'gpu-process-crashed' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -359,6 +369,11 @@ Returns:
|
||||
|
||||
Emitted when the GPU process crashes or is killed.
|
||||
|
||||
**Deprecated:** This event is superceded by the `child-process-gone` event
|
||||
which contains more information about why the child process dissapeared. It
|
||||
isn't always because it crashed. The `killed` boolean can be replaced by
|
||||
checking `reason === 'killed'` when you switch to that event.
|
||||
|
||||
### Event: 'renderer-process-crashed' _Deprecated_
|
||||
|
||||
Returns:
|
||||
@@ -387,12 +402,42 @@ Returns:
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failed` - Process never successfully launched
|
||||
* `launch-failure` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
|
||||
Emitted when the renderer process unexpectedly dissapears. This is normally
|
||||
because it was crashed or killed.
|
||||
|
||||
#### Event: 'child-process-gone'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `type` String - Process type. One of the following values:
|
||||
* `Utility`
|
||||
* `Zygote`
|
||||
* `Sandbox helper`
|
||||
* `GPU`
|
||||
* `Pepper Plugin`
|
||||
* `Pepper Plugin Broker`
|
||||
* `Unknown`
|
||||
* `reason` String - The reason the child process is gone. Possible values:
|
||||
* `clean-exit` - Process exited with an exit code of zero
|
||||
* `abnormal-exit` - Process exited with a non-zero exit code
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failure` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
* `exitCode` Number - The exit code for the process
|
||||
(e.g. status from waitpid if on posix, from GetExitCodeProcess on Windows).
|
||||
* `name` String (optional) - The name of the process. i.e. for plugins it might be Flash.
|
||||
Examples for utility: `Audio Service`, `Content Decryption Module Service`, `Network Service`, `Video Capture`, etc.
|
||||
|
||||
Emitted when the child process unexpectedly dissapears. This is normally
|
||||
because it was crashed or killed. It does not include renderer processes.
|
||||
|
||||
### Event: 'accessibility-support-changed' _macOS_ _Windows_
|
||||
|
||||
Returns:
|
||||
@@ -805,6 +850,20 @@ Returns `String` - Name of the application handling the protocol, or an empty
|
||||
This method returns the application name of the default handler for the protocol
|
||||
(aka URI scheme) of a URL.
|
||||
|
||||
### `app.getApplicationInfoForProtocol(url)` _macOS_ _Windows_
|
||||
|
||||
* `url` String - a URL with the protocol name to check. Unlike the other
|
||||
methods in this family, this accepts an entire URL, including `://` at a
|
||||
minimum (e.g. `https://`).
|
||||
|
||||
Returns `Promise<Object>` - Resolve with an object containing the following:
|
||||
* `icon` NativeImage - the display icon of the app handling the protocol.
|
||||
* `path` String - installation path of the app handling the protocol.
|
||||
* `name` String - display name of the app handling the protocol.
|
||||
|
||||
This method returns a promise that contains the application name, icon and path of the default handler for the protocol
|
||||
(aka URI scheme) of a URL.
|
||||
|
||||
### `app.setUserTasks(tasks)` _Windows_
|
||||
|
||||
* `tasks` [Task[]](structures/task.md) - Array of `Task` objects
|
||||
@@ -966,6 +1025,7 @@ if (!gotTheLock) {
|
||||
|
||||
// Create myWindow, load the rest of the app, etc...
|
||||
app.whenReady().then(() => {
|
||||
myWindow = createWindow()
|
||||
})
|
||||
}
|
||||
```
|
||||
@@ -1081,8 +1141,10 @@ For `infoType` equal to `complete`:
|
||||
For `infoType` equal to `basic`:
|
||||
Promise is fulfilled with `Object` containing fewer attributes than when requested with `complete`. Here's an example of basic response:
|
||||
```js
|
||||
{ auxAttributes:
|
||||
{ amdSwitchable: true,
|
||||
{
|
||||
auxAttributes:
|
||||
{
|
||||
amdSwitchable: true,
|
||||
canSupportThreadedTextureMailbox: false,
|
||||
directComposition: false,
|
||||
directRendering: true,
|
||||
@@ -1095,12 +1157,14 @@ For `infoType` equal to `basic`:
|
||||
sandboxed: false,
|
||||
softwareRendering: false,
|
||||
supportsOverlays: false,
|
||||
videoDecodeAcceleratorFlags: 0 },
|
||||
gpuDevice:
|
||||
[ { active: true, deviceId: 26657, vendorId: 4098 },
|
||||
{ active: false, deviceId: 3366, vendorId: 32902 } ],
|
||||
machineModelName: 'MacBookPro',
|
||||
machineModelVersion: '11.5' }
|
||||
videoDecodeAcceleratorFlags: 0
|
||||
},
|
||||
gpuDevice:
|
||||
[{ active: true, deviceId: 26657, vendorId: 4098 },
|
||||
{ active: false, deviceId: 3366, vendorId: 32902 }],
|
||||
machineModelName: 'MacBookPro',
|
||||
machineModelVersion: '11.5'
|
||||
}
|
||||
```
|
||||
|
||||
Using `basic` should be preferred if only basic information like `vendorId` or `driverId` is needed.
|
||||
@@ -1222,7 +1286,7 @@ Show the app's about panel options. These options can be overridden with `app.se
|
||||
* `credits` String (optional) _macOS_ _Windows_ - Credit information.
|
||||
* `authors` String[] (optional) _Linux_ - List of app authors.
|
||||
* `website` String (optional) _Linux_ - The app's website.
|
||||
* `iconPath` String (optional) _Linux_ _Windows_ - Path to the app's icon. On Linux, will be shown as 64x64 pixels while retaining aspect ratio.
|
||||
* `iconPath` String (optional) _Linux_ _Windows_ - Path to the app's icon in a JPEG or PNG file format. On Linux, will be shown as 64x64 pixels while retaining aspect ratio.
|
||||
|
||||
Set the about panel options. This will override the values defined in the app's `.plist` file on macOS. See the [Apple docs][about-panel-options] for more details. On Linux, values must be set in order to be shown; there are no defaults.
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ The `autoUpdater` object has the following methods:
|
||||
* `options` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String> (optional) _macOS_ - HTTP request headers.
|
||||
* `serverType` String (optional) _macOS_ - Either `json` or `default`, see the [Squirrel.Mac][squirrel-mac]
|
||||
* `serverType` String (optional) _macOS_ - Can be `json` or `default`, see the [Squirrel.Mac][squirrel-mac]
|
||||
README for more information.
|
||||
|
||||
Sets the `url` and initialize the auto updater.
|
||||
|
||||
@@ -28,25 +28,6 @@ view.webContents.loadURL('https://electronjs.org')
|
||||
* `options` Object (optional)
|
||||
* `webPreferences` Object (optional) - See [BrowserWindow](browser-window.md).
|
||||
|
||||
### Static Methods
|
||||
|
||||
#### `BrowserView.getAllViews()`
|
||||
|
||||
Returns `BrowserView[]` - An array of all opened BrowserViews.
|
||||
|
||||
#### `BrowserView.fromWebContents(webContents)`
|
||||
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
|
||||
Returns `BrowserView | null` - The BrowserView that owns the given `webContents`
|
||||
or `null` if the contents are not owned by a BrowserView.
|
||||
|
||||
#### `BrowserView.fromId(id)`
|
||||
|
||||
* `id` Integer
|
||||
|
||||
Returns `BrowserView` - The view with the given `id`.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
Objects created with `new BrowserView` have the following properties:
|
||||
@@ -55,10 +36,6 @@ Objects created with `new BrowserView` have the following properties:
|
||||
|
||||
A [`WebContents`](web-contents.md) object owned by this view.
|
||||
|
||||
#### `view.id` _Experimental_
|
||||
|
||||
A `Integer` representing the unique ID of the view.
|
||||
|
||||
### Instance Methods
|
||||
|
||||
Objects created with `new BrowserView` have the following instance methods:
|
||||
|
||||
@@ -38,7 +38,7 @@ the window after this event will have no visual flash:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow({ show: false })
|
||||
const win = new BrowserWindow({ show: false })
|
||||
win.once('ready-to-show', () => {
|
||||
win.show()
|
||||
})
|
||||
@@ -60,7 +60,7 @@ immediately, and use a `backgroundColor` close to your app's background:
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
let win = new BrowserWindow({ backgroundColor: '#2e2c29' })
|
||||
const win = new BrowserWindow({ backgroundColor: '#2e2c29' })
|
||||
win.loadURL('https://github.com')
|
||||
```
|
||||
|
||||
@@ -74,8 +74,8 @@ By using `parent` option, you can create child windows:
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
let top = new BrowserWindow()
|
||||
let child = new BrowserWindow({ parent: top })
|
||||
const top = new BrowserWindow()
|
||||
const child = new BrowserWindow({ parent: top })
|
||||
child.show()
|
||||
top.show()
|
||||
```
|
||||
@@ -90,7 +90,7 @@ window, you have to set both `parent` and `modal` options:
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
let child = new BrowserWindow({ parent: top, modal: true, show: false })
|
||||
const child = new BrowserWindow({ parent: top, modal: true, show: false })
|
||||
child.loadURL('https://github.com')
|
||||
child.once('ready-to-show', () => {
|
||||
child.show()
|
||||
@@ -207,15 +207,11 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
* `opacity` Number (optional) - Set the initial opacity of the window, between 0.0 (fully
|
||||
transparent) and 1.0 (fully opaque). This is only implemented on Windows and macOS.
|
||||
* `darkTheme` Boolean (optional) - Forces using dark theme for the window, only works on
|
||||
some GTK+3 desktop environments. Default is `false`.
|
||||
some GTK desktop environments. Default is [`nativeTheme.shouldUseDarkColors`](native-theme.md).
|
||||
* `transparent` Boolean (optional) - Makes the window [transparent](frameless-window.md#transparent-window).
|
||||
Default is `false`. On Windows, does not work unless the window is frameless.
|
||||
* `type` String (optional) - The type of window, default is normal window. See more about
|
||||
this below.
|
||||
* `visualEffectState` String (optional) - Specify how the material appearance should reflect window activity state on macOS. Must be used with the `vibrancy` property. Possible values are:
|
||||
* `followWindow` - The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default.
|
||||
* `active` - The backdrop should always appear active.
|
||||
* `inactive` - The backdrop should always appear inactive.
|
||||
* `titleBarStyle` String (optional) - The style of window title bar.
|
||||
Default is `default`. Possible values are:
|
||||
* `default` - Results in the standard gray opaque Mac title
|
||||
@@ -275,7 +271,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
the `nodeIntegration` option and the APIs available to the preload script
|
||||
are more limited. Read more about the option [here](sandbox-option.md).
|
||||
* `enableRemoteModule` Boolean (optional) - Whether to enable the [`remote`](remote.md) module.
|
||||
Default is `false`.
|
||||
Default is `true`.
|
||||
* `session` [Session](session.md#class-session) (optional) - Sets the session used by the
|
||||
page. Instead of passing the Session object directly, you can also choose to
|
||||
use the `partition` option instead, which accepts a partition string. When
|
||||
@@ -604,7 +600,7 @@ e.g. `APPCOMMAND_BROWSER_BACKWARD` is emitted as `browser-backward`.
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow()
|
||||
const win = new BrowserWindow()
|
||||
win.on('app-command', (e, cmd) => {
|
||||
// Navigate the window back when the user hits their mouse back button
|
||||
if (cmd === 'browser-backward' && win.webContents.canGoBack()) {
|
||||
@@ -699,7 +695,7 @@ Returns `BrowserWindow | null` - The window that owns the given `browserView`. I
|
||||
|
||||
* `id` Integer
|
||||
|
||||
Returns `BrowserWindow` - The window with the given `id`.
|
||||
Returns `BrowserWindow | null` - The window with the given `id`.
|
||||
|
||||
#### `BrowserWindow.addExtension(path)` _Deprecated_
|
||||
|
||||
@@ -779,7 +775,7 @@ To check if a DevTools extension is installed you can run the following:
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
let installed = BrowserWindow.getDevToolsExtensions().hasOwnProperty('devtron')
|
||||
const installed = 'devtron' in BrowserWindow.getDevToolsExtensions()
|
||||
console.log(installed)
|
||||
```
|
||||
|
||||
@@ -796,7 +792,7 @@ Objects created with `new BrowserWindow` have the following properties:
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
// In this example `win` is our instance
|
||||
let win = new BrowserWindow({ width: 800, height: 600 })
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
win.loadURL('https://github.com')
|
||||
```
|
||||
|
||||
@@ -1321,9 +1317,9 @@ a HTML-rendered toolbar. For example:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow()
|
||||
const win = new BrowserWindow()
|
||||
|
||||
let toolbarRect = document.getElementById('toolbar').getBoundingClientRect()
|
||||
const toolbarRect = document.getElementById('toolbar').getBoundingClientRect()
|
||||
win.setSheetOffset(toolbarRect.height)
|
||||
```
|
||||
|
||||
@@ -1447,7 +1443,7 @@ Node's [`url.format`](https://nodejs.org/api/url.html#url_url_format_urlobject)
|
||||
method:
|
||||
|
||||
```javascript
|
||||
let url = require('url').format({
|
||||
const url = require('url').format({
|
||||
protocol: 'file',
|
||||
slashes: true,
|
||||
pathname: require('path').join(__dirname, 'index.html')
|
||||
@@ -1673,12 +1669,9 @@ Sets whether the menu bar should be visible. If the menu bar is auto-hide, users
|
||||
|
||||
Returns `Boolean` - Whether the menu bar is visible.
|
||||
|
||||
#### `win.setVisibleOnAllWorkspaces(visible[, options])`
|
||||
#### `win.setVisibleOnAllWorkspaces(visible)`
|
||||
|
||||
* `visible` Boolean
|
||||
* `options` Object (optional)
|
||||
* `visibleOnFullScreen` Boolean (optional) _macOS_ - Sets whether
|
||||
the window should be visible above fullscreen windows
|
||||
|
||||
Sets whether the window should be visible on all workspaces.
|
||||
|
||||
|
||||
@@ -198,14 +198,6 @@ logging level for all code in the source files under a `foo/bar` directory.
|
||||
|
||||
This switch only works when `--enable-logging` is also passed.
|
||||
|
||||
### --force_high_performance_gpu
|
||||
|
||||
Force using discrete GPU when there are multiple GPUs available.
|
||||
|
||||
### --force_low_power_gpu
|
||||
|
||||
Force using integrated GPU when there are multiple GPUs available.
|
||||
|
||||
## Node.js Flags
|
||||
|
||||
Electron supports some of the [CLI flags][node-cli] supported by Node.js.
|
||||
|
||||
@@ -83,4 +83,4 @@ Returns `Promise<Object>` - Resolves with an object containing the `value` and `
|
||||
Get the maximum usage across processes of trace buffer as a percentage of the
|
||||
full state.
|
||||
|
||||
[trace viewer]: https://github.com/catapult-project/catapult/blob/master/tracing
|
||||
[trace viewer]: https://chromium.googlesource.com/catapult/+/HEAD/tracing/README.md
|
||||
|
||||
@@ -156,16 +156,10 @@ parameters in a renderer process will not result in those parameters being sent
|
||||
with crashes that occur in other renderer processes or in the main process.
|
||||
|
||||
**Note:** Parameters have limits on the length of the keys and values. Key
|
||||
names must be no longer than 39 bytes, and values must be no longer than 20320
|
||||
names must be no longer than 39 bytes, 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:** On linux values that are longer than 127 bytes will be chunked into
|
||||
multiple keys, each 127 bytes in length. E.g. `addExtraParameter('foo', 'a'.repeat(130))`
|
||||
will result in two chunked keys `foo__1` and `foo__2`, the first will contain
|
||||
the first 127 bytes and the second will contain the remaining 3 bytes. On
|
||||
your crash reporting backend you should stitch together keys in this format.
|
||||
|
||||
### `crashReporter.removeExtraParameter(key)`
|
||||
|
||||
* `key` String - Parameter key, must be no longer than 39 bytes.
|
||||
|
||||
@@ -9,7 +9,7 @@ runtime that allows interacting with pages and instrumenting them.
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow()
|
||||
const win = new BrowserWindow()
|
||||
|
||||
try {
|
||||
win.webContents.debugger.attach('1.1')
|
||||
|
||||
@@ -72,6 +72,50 @@ const constraints = {
|
||||
}
|
||||
```
|
||||
|
||||
This example shows how to capture a video from a [WebContents](web-contents.md)
|
||||
|
||||
```javascript
|
||||
// In the renderer process.
|
||||
const { desktopCapturer, remote } = require('electron')
|
||||
|
||||
desktopCapturer.getMediaSourceIdForWebContents(remote.getCurrentWebContents().id).then(async mediaSourceId => {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'tab',
|
||||
chromeMediaSourceId: mediaSourceId
|
||||
}
|
||||
},
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'tab',
|
||||
chromeMediaSourceId: mediaSourceId,
|
||||
minWidth: 1280,
|
||||
maxWidth: 1280,
|
||||
minHeight: 720,
|
||||
maxHeight: 720
|
||||
}
|
||||
}
|
||||
})
|
||||
handleStream(stream)
|
||||
} catch (e) {
|
||||
handleError(e)
|
||||
}
|
||||
})
|
||||
|
||||
function handleStream (stream) {
|
||||
const video = document.querySelector('video')
|
||||
video.srcObject = stream
|
||||
video.onloadedmetadata = (e) => video.play()
|
||||
}
|
||||
|
||||
function handleError (e) {
|
||||
console.log(e)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Methods
|
||||
|
||||
The `desktopCapturer` module has the following methods:
|
||||
@@ -94,6 +138,15 @@ Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`Desktop
|
||||
**Note** Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher,
|
||||
which can detected by [`systemPreferences.getMediaAccessStatus`].
|
||||
|
||||
### `desktopCapturer.getMediaSourceIdForWebContents(webContentsId)`
|
||||
|
||||
* `webContentsId` number - Id of the WebContents to get stream of
|
||||
|
||||
Returns `Promise<string>` - Resolves with the identifier of a WebContents stream, this identifier can be
|
||||
used with [`navigator.mediaDevices.getUserMedia`].
|
||||
The identifier is **only valid for 10 seconds**.
|
||||
The identifier may be empty if not requested from a renderer process.
|
||||
|
||||
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
|
||||
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-macos
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ control the download item.
|
||||
```javascript
|
||||
// In the main process.
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow()
|
||||
const win = new BrowserWindow()
|
||||
win.webContents.session.on('will-download', (event, item, webContents) => {
|
||||
// Set the save path, making Electron not to prompt a save dialog.
|
||||
item.setSavePath('/tmp/save.pdf')
|
||||
|
||||
@@ -102,15 +102,3 @@ The following methods of `chrome.tabs` are supported:
|
||||
> **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active
|
||||
> tab". Since Electron has no such concept, passing `-1` as a tab ID is not
|
||||
> supported and will raise an error.
|
||||
|
||||
### `chrome.management`
|
||||
|
||||
The following methods of `chrome.management` are supported:
|
||||
|
||||
- `chrome.management.getAll`
|
||||
- `chrome.management.get`
|
||||
- `chrome.management.getSelf`
|
||||
- `chrome.management.getPermissionWarningsById`
|
||||
- `chrome.management.getPermissionWarningsByManifest`
|
||||
- `chrome.management.onEnabled`
|
||||
- `chrome.management.onDisabled`
|
||||
|
||||
@@ -15,7 +15,7 @@ To create a frameless window, you need to set `frame` to `false` in
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow({ width: 800, height: 600, frame: false })
|
||||
const win = new BrowserWindow({ width: 800, height: 600, frame: false })
|
||||
win.show()
|
||||
```
|
||||
|
||||
@@ -33,7 +33,7 @@ Results in a hidden title bar and a full size content window, yet the title bar
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow({ titleBarStyle: 'hidden' })
|
||||
const win = new BrowserWindow({ titleBarStyle: 'hidden' })
|
||||
win.show()
|
||||
```
|
||||
|
||||
@@ -43,7 +43,7 @@ Results in a hidden title bar with an alternative look where the traffic light b
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
|
||||
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
|
||||
win.show()
|
||||
```
|
||||
|
||||
@@ -58,7 +58,7 @@ This option is only applicable for frameless windows.
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover', frame: false })
|
||||
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover', frame: false })
|
||||
win.show()
|
||||
```
|
||||
|
||||
@@ -69,7 +69,7 @@ window transparent:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow({ transparent: true, frame: false })
|
||||
const win = new BrowserWindow({ transparent: true, frame: false })
|
||||
win.show()
|
||||
```
|
||||
|
||||
@@ -100,7 +100,7 @@ API:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow()
|
||||
const win = new BrowserWindow()
|
||||
win.setIgnoreMouseEvents(true)
|
||||
```
|
||||
|
||||
@@ -112,8 +112,8 @@ optional parameter can be used to forward mouse move messages to the web page,
|
||||
allowing events such as `mouseleave` to be emitted:
|
||||
|
||||
```javascript
|
||||
let win = require('electron').remote.getCurrentWindow()
|
||||
let el = document.getElementById('clickThroughElement')
|
||||
const win = require('electron').remote.getCurrentWindow()
|
||||
const el = document.getElementById('clickThroughElement')
|
||||
el.addEventListener('mouseenter', () => {
|
||||
win.setIgnoreMouseEvents(true, { forward: true })
|
||||
})
|
||||
|
||||
@@ -148,4 +148,4 @@ found in the [`ipc-main-invoke-event`](structures/ipc-main-invoke-event.md)
|
||||
structure docs.
|
||||
|
||||
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
|
||||
[web-contents-send]: web-contents.md#contentssendchannel-arg1-arg2-
|
||||
[web-contents-send]: web-contents.md#contentssendchannel-args
|
||||
|
||||
@@ -96,7 +96,7 @@ Appends the `menuItem` to the menu.
|
||||
|
||||
* `id` String
|
||||
|
||||
Returns `MenuItem` the item with the specified `id`
|
||||
Returns `MenuItem | null` the item with the specified `id`
|
||||
|
||||
#### `menu.insert(pos, menuItem)`
|
||||
|
||||
@@ -195,8 +195,8 @@ const template = [
|
||||
{
|
||||
label: 'Speech',
|
||||
submenu: [
|
||||
{ role: 'startspeaking' },
|
||||
{ role: 'stopspeaking' }
|
||||
{ role: 'startSpeaking' },
|
||||
{ role: 'stopSpeaking' }
|
||||
]
|
||||
}
|
||||
] : [
|
||||
@@ -211,12 +211,12 @@ const template = [
|
||||
label: 'View',
|
||||
submenu: [
|
||||
{ role: 'reload' },
|
||||
{ role: 'forcereload' },
|
||||
{ role: 'toggledevtools' },
|
||||
{ role: 'forceReload' },
|
||||
{ role: 'toggleDevTools' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'resetzoom' },
|
||||
{ role: 'zoomin' },
|
||||
{ role: 'zoomout' },
|
||||
{ role: 'resetZoom' },
|
||||
{ role: 'zoomIn' },
|
||||
{ role: 'zoomOut' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'togglefullscreen' }
|
||||
]
|
||||
|
||||
@@ -119,13 +119,6 @@ Returns `NativeImage`
|
||||
|
||||
Creates an empty `NativeImage` instance.
|
||||
|
||||
### `nativeImage.createThumbnailFromPath(path, maxSize)` _macOS_ _Windows_
|
||||
|
||||
* `path` String - path to a file that we intend to construct a thumbnail out of.
|
||||
* `maxSize` [Size](structures/size.md) - the maximum width and height (positive numbers) the thumbnail returned can be. The Windows implementation will ignore `maxSize.height` and scale the height according to `maxSize.width`.
|
||||
|
||||
Returns `Promise<NativeImage>` - fulfilled with the file's thumbnail preview image, which is a [NativeImage](native-image.md).
|
||||
|
||||
### `nativeImage.createFromPath(path)`
|
||||
|
||||
* `path` String
|
||||
|
||||
@@ -8,19 +8,19 @@ Process: [Main](../glossary.md#main-process)
|
||||
|
||||
The `powerMonitor` module emits the following events:
|
||||
|
||||
### Event: 'suspend' _macOS_ _Windows_
|
||||
### Event: 'suspend'
|
||||
|
||||
Emitted when the system is suspending.
|
||||
|
||||
### Event: 'resume' _macOS_ _Windows_
|
||||
### Event: 'resume'
|
||||
|
||||
Emitted when system is resuming.
|
||||
|
||||
### Event: 'on-ac' _macOS_ _Windows_
|
||||
### Event: 'on-ac' _Windows_
|
||||
|
||||
Emitted when the system changes to AC power.
|
||||
|
||||
### Event: 'on-battery' _macOS_ _Windows_
|
||||
### Event: 'on-battery' _Windows_
|
||||
|
||||
Emitted when system changes to battery power.
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ The `protocol` module has the following methods:
|
||||
module gets emitted and can be called only once.
|
||||
|
||||
Registers the `scheme` as standard, secure, bypasses content security policy for
|
||||
resources, allows registering ServiceWorker and supports fetch API. Specify a
|
||||
privilege with the value of `true` to enable the capability.
|
||||
resources, allows registering ServiceWorker, supports fetch API, and streaming
|
||||
video/audio. Specify a privilege with the value of `true` to enable the capability.
|
||||
|
||||
An example of registering a privileged scheme, that bypasses Content Security
|
||||
Policy:
|
||||
@@ -103,6 +103,11 @@ cookies) are disabled for non standard schemes. So in general if you want to
|
||||
register a custom protocol to replace the `http` protocol, you have to register
|
||||
it as a standard scheme.
|
||||
|
||||
Protocols that use streams (http and stream protocols) should set `stream: true`.
|
||||
The `<video>` and `<audio>` HTML elements expect protocols to buffer their
|
||||
responses by default. The `stream` flag configures those elements to correctly
|
||||
expect streaming responses.
|
||||
|
||||
### `protocol.registerFileProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
|
||||
@@ -17,7 +17,7 @@ renderer process:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
let win = new BrowserWindow({ width: 800, height: 600 })
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
win.loadURL('https://github.com')
|
||||
```
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ const { app, BrowserWindow, screen } = require('electron')
|
||||
let win
|
||||
|
||||
app.whenReady().then(() => {
|
||||
let displays = screen.getAllDisplays()
|
||||
let externalDisplay = displays.find((display) => {
|
||||
const displays = screen.getAllDisplays()
|
||||
const externalDisplay = displays.find((display) => {
|
||||
return display.bounds.x !== 0 || display.bounds.y !== 0
|
||||
})
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ Returns:
|
||||
* `message` String - The actual console message
|
||||
* `versionId` Number - The version ID of the service worker that sent the log message
|
||||
* `source` String - The type of source for this message. Can be `javascript`, `xml`, `network`, `console-api`, `storage`, `app-cache`, `rendering`, `security`, `deprecation`, `worker`, `violation`, `intervention`, `recommendation` or `other`.
|
||||
* `level` Number - The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and `error`.
|
||||
* `level` Number - The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and `error`.
|
||||
* `sourceUrl` String - The URL the message came from
|
||||
* `lineNumber` Number - The line number of the source that triggered this console message
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ property of [`WebContents`](web-contents.md), or from the `session` module.
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
let win = new BrowserWindow({ width: 800, height: 600 })
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
win.loadURL('http://github.com')
|
||||
|
||||
const ses = win.webContents.session
|
||||
@@ -332,7 +332,7 @@ verify proc.
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow()
|
||||
const win = new BrowserWindow()
|
||||
|
||||
win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
const { hostname } = request
|
||||
@@ -348,8 +348,16 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
|
||||
* `handler` Function | null
|
||||
* `webContents` [WebContents](web-contents.md) - WebContents requesting the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
|
||||
* `permission` String - Enum of 'media', 'geolocation', 'notifications', 'midiSysex',
|
||||
'pointerLock', 'fullscreen', 'openExternal'.
|
||||
* `permission` String - The type of requested permission.
|
||||
* `media` - Request access to media devices such as camera, microphone and speakers.
|
||||
* `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.
|
||||
* `midi` - Request MIDI access in the `webmidi` API.
|
||||
* `midiSysex` - Request the use of system exclusive messages in the `webmidi` API.
|
||||
* `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.
|
||||
* `callback` Function
|
||||
* `permissionGranted` Boolean - Allow or deny the permission.
|
||||
* `details` Object - Some properties are only available on certain permission types.
|
||||
@@ -655,7 +663,7 @@ const path = require('path')
|
||||
app.whenReady().then(() => {
|
||||
const protocol = session.fromPartition('some-partition').protocol
|
||||
protocol.registerFileProtocol('atom', (request, callback) => {
|
||||
let url = request.url.substr(7)
|
||||
const url = request.url.substr(7)
|
||||
callback({ path: path.normalize(`${__dirname}/${url}`) })
|
||||
}, (error) => {
|
||||
if (error) console.error('Failed to register protocol')
|
||||
|
||||
@@ -8,3 +8,4 @@
|
||||
* `allowServiceWorkers` Boolean (optional) - Default false.
|
||||
* `supportFetchAPI` Boolean (optional) - Default false.
|
||||
* `corsEnabled` Boolean (optional) - Default false.
|
||||
* `stream` Boolean (optional) - Default false.
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
* `Pepper Plugin`
|
||||
* `Pepper Plugin Broker`
|
||||
* `Unknown`
|
||||
* `name` String (optional) - The name of the process. i.e. for plugins it might be Flash.
|
||||
Examples for utility: `Audio Service`, `Content Decryption Module Service`, `Network Service`, `Video Capture`, etc.
|
||||
* `cpu` [CPUUsage](cpu-usage.md) - CPU usage of the process.
|
||||
* `creationTime` Number - Creation time for this process.
|
||||
The time is represented as number of milliseconds since epoch.
|
||||
|
||||
@@ -7,5 +7,4 @@
|
||||
* `contentLengths` Number[] - The total size of the content, in bytes.
|
||||
* `price` Number - The cost of the product in the local currency.
|
||||
* `formattedPrice` String - The locale formatted price of the product.
|
||||
* `currencyCode` String - 3 character code presenting a product's currency based on the ISO 4217 standard.
|
||||
* `isDownloadable` Boolean - A Boolean value that indicates whether the App Store has downloadable content for this product. `true` if at least one file has been associated with the product.
|
||||
|
||||
5
docs/api/structures/stream-protocol-response.md
Normal file
5
docs/api/structures/stream-protocol-response.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# StreamProtocolResponse Object
|
||||
|
||||
* `statusCode` Number (optional) - The HTTP response code.
|
||||
* `headers` Record<String, String | String[]> (optional) - An object containing the response headers.
|
||||
* `data` ReadableStream | null - A Node.js readable stream representing the response body.
|
||||
5
docs/api/structures/string-protocol-response.md
Normal file
5
docs/api/structures/string-protocol-response.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# StringProtocolResponse Object
|
||||
|
||||
* `mimeType` String (optional) - MIME type of the response.
|
||||
* `charset` String (optional) - Charset of the response.
|
||||
* `data` String | null - A string representing the response body.
|
||||
@@ -6,7 +6,7 @@
|
||||
* `trace_buffer_size_in_events` number (optional) - maximum size of the trace
|
||||
recording buffer in events.
|
||||
* `enable_argument_filter` boolean (optional) - if true, filter event data
|
||||
according to a whitelist of events that have been manually vetted to not
|
||||
according to a specific list of events that have been manually vetted to not
|
||||
include any PII. See [the implementation in
|
||||
Chromium][trace_event_args_whitelist.cc] for specifics.
|
||||
* `included_categories` String[] (optional) - a list of tracing categories to
|
||||
@@ -41,7 +41,7 @@ An example TraceConfig that roughly matches what Chrome DevTools records:
|
||||
'disabled-by-default-v8.cpu_profiler',
|
||||
'disabled-by-default-v8.cpu_profiler.hires'
|
||||
],
|
||||
excluded_categories: [ '*' ]
|
||||
excluded_categories: ['*']
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ not (transparent windows won't work correctly when DWM composition is disabled):
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow, systemPreferences } = require('electron')
|
||||
let browserOptions = { width: 1000, height: 800 }
|
||||
const browserOptions = { width: 1000, height: 800 }
|
||||
|
||||
// Make the window transparent only if the platform supports it.
|
||||
if (process.platform !== 'win32' || systemPreferences.isAeroGlassEnabled()) {
|
||||
@@ -218,7 +218,7 @@ if (process.platform !== 'win32' || systemPreferences.isAeroGlassEnabled()) {
|
||||
}
|
||||
|
||||
// Create the window.
|
||||
let win = new BrowserWindow(browserOptions)
|
||||
const win = new BrowserWindow(browserOptions)
|
||||
|
||||
// Navigate.
|
||||
if (browserOptions.transparent) {
|
||||
|
||||
@@ -41,6 +41,10 @@ the button in the touch bar.
|
||||
A `NativeImage` representing the button's current icon. Changing this value immediately updates the button
|
||||
in the touch bar.
|
||||
|
||||
#### `touchBarButton.iconPosition`
|
||||
|
||||
A `String` - Can be `left`, `right` or `overlay`. Defaults to `overlay`.
|
||||
|
||||
#### `touchBarButton.enabled`
|
||||
|
||||
A `Boolean` representing whether the button is in an enabled state.
|
||||
|
||||
@@ -49,3 +49,7 @@ updates the control in the touch bar. Updating deep properties inside this array
|
||||
|
||||
An `Integer` representing the currently selected segment. Changing this value immediately updates the control
|
||||
in the touch bar. User interaction with the touch bar will update this value automatically.
|
||||
|
||||
#### `touchBarSegmentedControl.mode`
|
||||
|
||||
A `String` representing the current selection mode of the control. Can be `single`, `multiple` or `buttons`.
|
||||
|
||||
@@ -11,3 +11,11 @@ Process: [Main](../tutorial/application-architecture.md#main-and-renderer-proces
|
||||
* `small` - Small space between items. Maps to `NSTouchBarItemIdentifierFixedSpaceSmall`. This is the default.
|
||||
* `large` - Large space between items. Maps to `NSTouchBarItemIdentifierFixedSpaceLarge`.
|
||||
* `flexible` - Take up all available space. Maps to `NSTouchBarItemIdentifierFlexibleSpace`.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
The following properties are available on instances of `TouchBarSpacer`:
|
||||
|
||||
#### `touchBarSpacer.size`
|
||||
|
||||
A `String` representing the size of the spacer. Can be `small`, `large` or `flexible`.
|
||||
|
||||
@@ -12,10 +12,10 @@ the [`BrowserWindow`](browser-window.md) object. An example of accessing the
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
let win = new BrowserWindow({ width: 800, height: 1500 })
|
||||
const win = new BrowserWindow({ width: 800, height: 1500 })
|
||||
win.loadURL('http://github.com')
|
||||
|
||||
let contents = win.webContents
|
||||
const contents = win.webContents
|
||||
console.log(contents)
|
||||
```
|
||||
|
||||
@@ -364,7 +364,7 @@ Returns:
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failed` - Process never successfully launched
|
||||
* `launch-failure` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
|
||||
Emitted when the renderer process unexpectedly dissapears. This is normally
|
||||
@@ -418,7 +418,7 @@ To only prevent the menu shortcuts, use
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
let win = new BrowserWindow({ width: 800, height: 600 })
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
|
||||
win.webContents.on('before-input-event', (event, input) => {
|
||||
// For example, only enable application menu keyboard shortcuts when
|
||||
@@ -665,7 +665,7 @@ app.whenReady().then(() => {
|
||||
win = new BrowserWindow({ width: 800, height: 600 })
|
||||
win.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
|
||||
event.preventDefault()
|
||||
let result = deviceList.find((device) => {
|
||||
const result = deviceList.find((device) => {
|
||||
return device.deviceName === 'test'
|
||||
})
|
||||
if (!result) {
|
||||
@@ -691,7 +691,7 @@ buffer.
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
let win = new BrowserWindow({ webPreferences: { offscreen: true } })
|
||||
const win = new BrowserWindow({ webPreferences: { offscreen: true } })
|
||||
win.webContents.on('paint', (event, dirty, image) => {
|
||||
// updateBitmap(dirty, image.getBitmap())
|
||||
})
|
||||
@@ -738,9 +738,9 @@ Emitted when a `<webview>` has been attached to this web contents.
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `level` Integer
|
||||
* `message` String
|
||||
* `line` Integer
|
||||
* `level` Integer - The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and `error`.
|
||||
* `message` String - The actual console message
|
||||
* `line` Integer - The line number of the source that triggered this console message
|
||||
* `sourceId` String
|
||||
|
||||
Emitted when the associated window logs a console message.
|
||||
@@ -907,7 +907,7 @@ Returns `String` - The URL of the current web page.
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow({ width: 800, height: 600 })
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
win.loadURL('http://github.com').then(() => {
|
||||
const currentURL = win.webContents.getURL()
|
||||
console.log(currentURL)
|
||||
@@ -1296,9 +1296,9 @@ Returns [`PrinterInfo[]`](structures/printer-info.md)
|
||||
* `pagesPerSheet` Number (optional) - The number of pages to print per page sheet.
|
||||
* `collate` Boolean (optional) - Whether the web page should be collated.
|
||||
* `copies` Number (optional) - The number of copies of the web page to print.
|
||||
* `pageRanges` Object[] (optional) - The page range to print. On macOS, only one range is honored.
|
||||
* `from` Number - Index of the first page to print (0-based).
|
||||
* `to` Number - Index of the last page to print (inclusive) (0-based).
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` Number - the start page.
|
||||
* `to` Number - the end page.
|
||||
* `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`.
|
||||
* `dpi` Record<string, number> (optional)
|
||||
* `horizontal` Number (optional) - The horizontal dpi.
|
||||
@@ -1321,7 +1321,14 @@ Use `page-break-before: always;` CSS style to force to print to a new page.
|
||||
Example usage:
|
||||
|
||||
```js
|
||||
const options = { silent: true, deviceName: 'My-Printer' }
|
||||
const options = {
|
||||
silent: true,
|
||||
deviceName: 'My-Printer',
|
||||
pageRanges: {
|
||||
from: 0,
|
||||
to: 1
|
||||
}
|
||||
}
|
||||
win.webContents.print(options, (success, errorType) => {
|
||||
if (!success) console.log(errorType)
|
||||
})
|
||||
@@ -1338,8 +1345,8 @@ win.webContents.print(options, (success, errorType) => {
|
||||
default margin, 1 for no margin, and 2 for minimum margin.
|
||||
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` Number - Index of the first page to print (0-based).
|
||||
* `to` Number - Index of the last page to print (inclusive) (0-based).
|
||||
* `from` Number - zero-based index of the first page to print.
|
||||
* `to` Number - zero-based index of the last page to print (inclusive).
|
||||
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width` in microns.
|
||||
* `printBackground` Boolean (optional) - Whether to print CSS backgrounds.
|
||||
@@ -1375,7 +1382,7 @@ const fs = require('fs')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
let win = new BrowserWindow({ width: 800, height: 600 })
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
win.loadURL('http://github.com')
|
||||
|
||||
win.webContents.on('did-finish-load', () => {
|
||||
@@ -1401,7 +1408,7 @@ creation:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow()
|
||||
const win = new BrowserWindow()
|
||||
win.webContents.on('devtools-opened', () => {
|
||||
win.webContents.addWorkSpace(__dirname)
|
||||
})
|
||||
@@ -1722,7 +1729,7 @@ Returns `Promise<void>` - resolves if the page is saved.
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow()
|
||||
const win = new BrowserWindow()
|
||||
|
||||
win.loadURL('https://github.com')
|
||||
|
||||
|
||||
@@ -560,9 +560,9 @@ Stops any `findInPage` request for the `webview` with the provided `action`.
|
||||
* `pagesPerSheet` Number (optional) - The number of pages to print per page sheet.
|
||||
* `collate` Boolean (optional) - Whether the web page should be collated.
|
||||
* `copies` Number (optional) - The number of copies of the web page to print.
|
||||
* `pageRanges` Object[] (optional) - The page range to print. On macOS, only the first range is honored.
|
||||
* `from` Number - Index of the first page to print (0-based).
|
||||
* `to` Number - Index of the last page to print (inclusive) (0-based).
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` Number - zero-based index of the first page to print.
|
||||
* `to` Number - zero-based index of the last page to print (inclusive).
|
||||
* `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`.
|
||||
* `dpi` Record<string, number> (optional)
|
||||
* `horizontal` Number (optional) - The horizontal dpi.
|
||||
@@ -588,8 +588,8 @@ Prints `webview`'s web page. Same as `webContents.print([options])`.
|
||||
and `width` in microns.
|
||||
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` Number - Index of the first page to print (0-based).
|
||||
* `to` Number - Index of the last page to print (inclusive) (0-based).
|
||||
* `from` Number - the first page to print.
|
||||
* `to` Number - the last page to print (inclusive).
|
||||
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`
|
||||
* `printBackground` Boolean (optional) - Whether to print CSS backgrounds.
|
||||
@@ -755,9 +755,9 @@ Fired when page leaves fullscreen triggered by HTML API.
|
||||
|
||||
Returns:
|
||||
|
||||
* `level` Integer
|
||||
* `message` String
|
||||
* `line` Integer
|
||||
* `level` Integer - The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and `error`.
|
||||
* `message` String - The actual console message
|
||||
* `line` Integer - The line number of the source that triggered this console message
|
||||
* `sourceId` String
|
||||
|
||||
Fired when the guest window logs a console message.
|
||||
@@ -816,7 +816,7 @@ const { shell } = require('electron')
|
||||
const webview = document.querySelector('webview')
|
||||
|
||||
webview.addEventListener('new-window', async (e) => {
|
||||
const protocol = require('url').parse(e.url).protocol
|
||||
const protocol = (new URL(e.url)).protocol
|
||||
if (protocol === 'http:' || protocol === 'https:') {
|
||||
await shell.openExternal(e.url)
|
||||
}
|
||||
|
||||
@@ -94,6 +94,6 @@ mainWindow.webContents.on('new-window', (event, url, frameName, disposition, opt
|
||||
|
||||
```javascript
|
||||
// renderer process (mainWindow)
|
||||
let modal = window.open('', 'modal')
|
||||
const modal = window.open('', 'modal')
|
||||
modal.document.write('<h1>Hello</h1>')
|
||||
```
|
||||
|
||||
61
docs/breaking-changes-ns.md
Normal file
61
docs/breaking-changes-ns.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Breaking changes (NetworkService) (Draft)
|
||||
|
||||
This document describes changes to Electron APIs after migrating network code
|
||||
to NetworkService API.
|
||||
|
||||
We don't currently have an estimate of when we will enable `NetworkService` by
|
||||
default in Electron, but as Chromium is already removing non-`NetworkService`
|
||||
code, we might switch before Electron 10.
|
||||
|
||||
The content of this document should be moved to `breaking-changes.md` once we have
|
||||
determined when to enable `NetworkService` in Electron.
|
||||
|
||||
## Planned Breaking API Changes
|
||||
|
||||
### `protocol.unregisterProtocol`
|
||||
### `protocol.uninterceptProtocol`
|
||||
|
||||
The APIs are now synchronous and the optional callback is no longer needed.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.unregisterProtocol(scheme, () => { /* ... */ })
|
||||
// Replace with
|
||||
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.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.registerFileProtocol(scheme, handler, () => { /* ... */ })
|
||||
// Replace with
|
||||
protocol.registerFileProtocol(scheme, handler)
|
||||
```
|
||||
|
||||
The registered or intercepted protocol does not have effect on current page
|
||||
until navigation happens.
|
||||
|
||||
### `protocol.isProtocolHandled`
|
||||
|
||||
This API is deprecated and users should use `protocol.isProtocolRegistered`
|
||||
and `protocol.isProtocolIntercepted` instead.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.isProtocolHandled(scheme).then(() => { /* ... */ })
|
||||
// Replace with
|
||||
const isRegistered = protocol.isProtocolRegistered(scheme)
|
||||
const isIntercepted = protocol.isProtocolIntercepted(scheme)
|
||||
```
|
||||
@@ -14,6 +14,15 @@ This document uses the following convention to categorize breaking changes:
|
||||
|
||||
## Planned Breaking API Changes (12.0)
|
||||
|
||||
### Default Changed: `contextIsolation` defaults to `true`
|
||||
|
||||
In Electron 12, `contextIsolation` will be enabled by default. To restore
|
||||
the previous behavior, `contextIsolation: false` must be specified in WebPreferences.
|
||||
|
||||
We [recommend having contextIsolation enabled](https://github.com/electron/electron/blob/master/docs/tutorial/security.md#3-enable-context-isolation-for-remote-content) for the security of your application.
|
||||
|
||||
For more details see: https://github.com/electron/electron/issues/23506
|
||||
|
||||
### Removed: `crashReporter` methods in the renderer process
|
||||
|
||||
The following `crashReporter` methods are no longer available in the renderer
|
||||
@@ -124,54 +133,6 @@ const w = new BrowserWindow({
|
||||
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.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.unregisterProtocol(scheme, () => { /* ... */ })
|
||||
// Replace with
|
||||
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.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.registerFileProtocol(scheme, handler, () => { /* ... */ })
|
||||
// Replace with
|
||||
protocol.registerFileProtocol(scheme, handler)
|
||||
```
|
||||
|
||||
The registered or intercepted protocol does not have effect on current page
|
||||
until navigation happens.
|
||||
|
||||
### `protocol.isProtocolHandled`
|
||||
|
||||
This API is deprecated and users should use `protocol.isProtocolRegistered`
|
||||
and `protocol.isProtocolIntercepted` instead.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.isProtocolHandled(scheme).then(() => { /* ... */ })
|
||||
// Replace with
|
||||
const isRegistered = protocol.isProtocolRegistered(scheme)
|
||||
const isIntercepted = protocol.isProtocolIntercepted(scheme)
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (9.0)
|
||||
|
||||
### Default Changed: Loading non-context-aware native modules in the renderer process is disabled by default
|
||||
@@ -305,7 +266,7 @@ const getGuestForWebContents = (webContentsId, contents) => {
|
||||
throw new Error(`Invalid webContentsId: ${webContentsId}`)
|
||||
}
|
||||
if (guest.hostWebContents !== contents) {
|
||||
throw new Error(`Access denied to webContents`)
|
||||
throw new Error('Access denied to webContents')
|
||||
}
|
||||
return guest
|
||||
}
|
||||
@@ -361,7 +322,7 @@ powerMonitor.querySystemIdleState(threshold, callback)
|
||||
const idleState = powerMonitor.getSystemIdleState(threshold)
|
||||
```
|
||||
|
||||
### API Changed: `powerMonitor.querySystemIdleTime` is now `powerMonitor.getSystemIdleState`
|
||||
### API Changed: `powerMonitor.querySystemIdleTime` is now `powerMonitor.getSystemIdleTime`
|
||||
|
||||
```js
|
||||
// Removed in Electron 7.0
|
||||
@@ -649,11 +610,11 @@ const { memory } = metrics[0] // Deprecated property
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
let optionsA = { webPreferences: { blinkFeatures: '' } }
|
||||
let windowA = new BrowserWindow(optionsA)
|
||||
const optionsA = { webPreferences: { blinkFeatures: '' } }
|
||||
const windowA = new BrowserWindow(optionsA)
|
||||
// Replace with
|
||||
let optionsB = { webPreferences: { enableBlinkFeatures: '' } }
|
||||
let windowB = new BrowserWindow(optionsB)
|
||||
const optionsB = { webPreferences: { enableBlinkFeatures: '' } }
|
||||
const windowB = new BrowserWindow(optionsB)
|
||||
|
||||
// Deprecated
|
||||
window.on('app-command', (e, cmd) => {
|
||||
@@ -824,11 +785,11 @@ The following list includes the breaking API changes made in Electron 2.0.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
let optionsA = { titleBarStyle: 'hidden-inset' }
|
||||
let windowA = new BrowserWindow(optionsA)
|
||||
const optionsA = { titleBarStyle: 'hidden-inset' }
|
||||
const windowA = new BrowserWindow(optionsA)
|
||||
// Replace with
|
||||
let optionsB = { titleBarStyle: 'hiddenInset' }
|
||||
let windowB = new BrowserWindow(optionsB)
|
||||
const optionsB = { titleBarStyle: 'hiddenInset' }
|
||||
const windowB = new BrowserWindow(optionsB)
|
||||
```
|
||||
|
||||
### `menu`
|
||||
|
||||
@@ -23,4 +23,3 @@ For guides on Electron app development, see
|
||||
* [Debugging on macOS](debugging-instructions-macos.md)
|
||||
* [Setting Up Symbol Server in Debugger](setting-up-symbol-server.md)
|
||||
* [Patches](patches.md)
|
||||
* [Upgrading Node](upgrading-node.md)
|
||||
|
||||
@@ -10,6 +10,10 @@ Check the build prerequisites for your platform before proceeding
|
||||
* [Linux](build-instructions-linux.md#prerequisites)
|
||||
* [Windows](build-instructions-windows.md#prerequisites)
|
||||
|
||||
## Build Tools
|
||||
|
||||
[Electron's Build Tools](https://github.com/electron/build-tools) automate much of the setup for compiling Electron from source with different configurations and build targets. If you wish to set up the environment manually, the instructions are listed below.
|
||||
|
||||
## GN prerequisites
|
||||
|
||||
You'll need to install [`depot_tools`][depot-tools], the toolset
|
||||
|
||||
@@ -15,7 +15,7 @@ calls, and other compiler optimizations. The only workaround is to build an
|
||||
unoptimized local build.
|
||||
|
||||
The official symbol server URL for Electron is
|
||||
https://electron-symbols.githubapp.com.
|
||||
https://symbols.electronjs.org.
|
||||
You cannot visit this URL directly, you must add it to the symbol path of your
|
||||
debugging tool. In the examples below, a local cache directory is used to avoid
|
||||
repeatedly fetching the PDB from the server. Replace `c:\code\symbols` with an
|
||||
@@ -30,7 +30,7 @@ directory on your computer, if you'd prefer a different location for downloaded
|
||||
symbols):
|
||||
|
||||
```powershell
|
||||
SRV*c:\code\symbols\*https://electron-symbols.githubapp.com
|
||||
SRV*c:\code\symbols\*https://symbols.electronjs.org
|
||||
```
|
||||
|
||||
Set this string as `_NT_SYMBOL_PATH` in the environment, using the Windbg menus,
|
||||
@@ -38,7 +38,7 @@ or by typing the `.sympath` command. If you would like to get symbols from
|
||||
Microsoft's symbol server as well, you should list that first:
|
||||
|
||||
```powershell
|
||||
SRV*c:\code\symbols\*https://msdl.microsoft.com/download/symbols;SRV*c:\code\symbols\*https://electron-symbols.githubapp.com
|
||||
SRV*c:\code\symbols\*https://msdl.microsoft.com/download/symbols;SRV*c:\code\symbols\*https://symbols.electronjs.org
|
||||
```
|
||||
|
||||
## Using the symbol server in Visual Studio
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
# Upgrading Node
|
||||
|
||||
## Discussion
|
||||
|
||||
Chromium and Node.js both depend on V8, and Electron contains
|
||||
only a single copy of V8, so it's important to ensure that the
|
||||
version of V8 chosen is compatible with the build's version of
|
||||
Node.js and Chromium.
|
||||
|
||||
Upgrading Node is much easier than upgrading Chromium, so fewer
|
||||
conflicts arise if one upgrades Chromium first, then chooses the
|
||||
upstream Node release whose version of V8 is closest to the one
|
||||
Chromium contains.
|
||||
|
||||
Electron has its own [Node fork](https://github.com/electron/node)
|
||||
with modifications for the V8 build details mentioned above
|
||||
and for exposing API needed by Electron. Once an upstream Node
|
||||
release is chosen, it's placed in a branch in Electron's Node fork
|
||||
and any Electron Node patches are applied there.
|
||||
|
||||
Another factor is that the Node project patches its version of V8.
|
||||
As mentioned above, Electron builds everything with a single copy
|
||||
of V8, so Node's V8 patches must be ported to that copy.
|
||||
|
||||
Once all of Electron's dependencies are building and using the same
|
||||
copy of V8, the next step is to fix any Electron code issues caused
|
||||
by the Node upgrade.
|
||||
|
||||
[FIXME] something about a Node debugger in Atom that we (e.g. deepak)
|
||||
use and need to confirm doesn't break with the Node upgrade?
|
||||
|
||||
So in short, the primary steps are:
|
||||
|
||||
1. Update Electron's Node fork to the desired version
|
||||
2. Backport Node's V8 patches to our copy of V8
|
||||
3. Update the GN build files, porting changes from node's GYP files
|
||||
4. Update Electron's DEPS to use new version of Node
|
||||
|
||||
## Updating Electron's Node [fork](https://github.com/electron/node)
|
||||
|
||||
1. Ensure that `master` on `electron/node` has updated release tags from `nodejs/node`
|
||||
2. Create a branch in https://github.com/electron/node: `electron-node-vX.X.X` where the base that you're branching from is the tag for the desired update
|
||||
- `vX.X.X` Must use a version of Node compatible with our current version of Chromium
|
||||
3. Re-apply our commits from the previous version of Node we were using (`vY.Y.Y`) to `v.X.X.X`
|
||||
- Check release tag and select the range of commits we need to re-apply
|
||||
- Cherry-pick commit range:
|
||||
1. Checkout both `vY.Y.Y` & `v.X.X.X`
|
||||
2. `git cherry-pick FIRST_COMMIT_HASH..LAST_COMMIT_HASH`
|
||||
- Resolve merge conflicts in each file encountered, then:
|
||||
1. `git add <conflict-file>`
|
||||
2. `git cherry-pick --continue`
|
||||
3. Repeat until finished
|
||||
|
||||
|
||||
## Updating [V8](https://github.com/electron/node/src/V8) Patches
|
||||
|
||||
We need to generate a patch file from each patch that Node
|
||||
applies to V8.
|
||||
|
||||
```sh
|
||||
$ cd third_party/electron_node
|
||||
$ CURRENT_NODE_VERSION=vX.Y.Z
|
||||
# Find the last commit with the message "deps: update V8 to <some version>"
|
||||
# This commit corresponds to Node resetting V8 to its pristine upstream
|
||||
# state at the stated version.
|
||||
$ LAST_V8_UPDATE="$(git log --grep='^deps: update V8' --format='%H' -1 deps/v8)"
|
||||
# This creates a patch file containing all changes in deps/v8 from
|
||||
# $LAST_V8_UPDATE up to the current Node version, formatted in a way that
|
||||
# it will apply cleanly to the V8 repository (i.e. with `deps/v8`
|
||||
# stripped off the path and excluding the v8/gypfiles directory, which
|
||||
# isn't present in V8.
|
||||
$ git format-patch \
|
||||
--relative=deps/v8 \
|
||||
$LAST_V8_UPDATE..$CURRENT_NODE_VERSION \
|
||||
deps/v8 \
|
||||
':(exclude)deps/v8/gypfiles' \
|
||||
--stdout \
|
||||
> ../../electron/common/patches/v8/node_v8_patches.patch
|
||||
```
|
||||
|
||||
This list of patches will probably include one that claims to
|
||||
make the V8 API backwards-compatible with a previous version of
|
||||
V8. Unfortunately, those patches almost always change the V8 API
|
||||
in a way that is incompatible with Chromium.
|
||||
|
||||
It's usually easier to update Node to work without the
|
||||
compatibility patch than to update Chromium to work with the
|
||||
compatibility patch, so it's recommended to revert the
|
||||
compatibility patch and fix any errors that arise when compiling
|
||||
Node.
|
||||
|
||||
## Update Electron's `DEPS` file
|
||||
|
||||
Update the `DEPS` file in the root of
|
||||
[electron/electron](https://github.com/electron/electron) to
|
||||
point to the git hash of the updated Node.
|
||||
|
||||
## Notes
|
||||
|
||||
- Node maintains its own fork of V8
|
||||
- They backport a small amount of things as needed
|
||||
- Documentation in Node about how [they work with V8](https://nodejs.org/api/v8.html)
|
||||
- We update code such that we only use one copy of V8 across all of Electron
|
||||
- E.g Electron, Chromium, and Node.js
|
||||
- We don’t track upstream closely due to logistics:
|
||||
- Upstream uses multiple repos and so merging into a single repo
|
||||
would result in lost history. So we only update when we’re planning
|
||||
a Node version bump in Electron.
|
||||
- Chromium is large and time-consuming to update, so we typically
|
||||
choose the Node version based on which of its releases has a version
|
||||
of V8 that’s closest to the version in Chromium that we’re using.
|
||||
- We sometimes have to wait for the next periodic Node release
|
||||
because it will sync more closely with the version of V8 in the new Chromium
|
||||
- Electron keeps all its patches in the repo because it’s simpler than
|
||||
maintaining different repos for patches for each upstream project.
|
||||
- Crashpad, Node.js, Chromium, Skia etc. patches are all kept in the same place
|
||||
- Building Node:
|
||||
- We maintain our own GN build files for Node.js to make it easier to ensure
|
||||
that eevrything is built with the same compiler flags.
|
||||
This means that every time we upgrade Node.js we have to do a modest amount of
|
||||
work to synchronize the GN files with the upstream GYP files.
|
||||
@@ -107,7 +107,7 @@ To solve this, you can turn off node integration in Electron:
|
||||
```javascript
|
||||
// In the main process.
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow({
|
||||
const win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
nodeIntegration: false
|
||||
}
|
||||
@@ -155,7 +155,7 @@ To achieve this goal, set the background in the constructor for [BrowserWindow][
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
let win = new BrowserWindow({
|
||||
const win = new BrowserWindow({
|
||||
backgroundColor: '#fff'
|
||||
})
|
||||
```
|
||||
|
||||
@@ -1,95 +1,95 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('open-error-dialog', event => {
|
||||
dialog.showErrorBox('An Error Message', 'Demonstrating an error message.')
|
||||
})
|
||||
|
||||
ipcMain.on('open-information-dialog', event => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, index => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('open-file-dialog', event => {
|
||||
dialog.showOpenDialog(
|
||||
{
|
||||
properties: ['openFile', 'openDirectory']
|
||||
},
|
||||
files => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
ipcMain.on('save-dialog', event => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
|
||||
}
|
||||
dialog.showSaveDialog(options, filename => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('open-error-dialog', event => {
|
||||
dialog.showErrorBox('An Error Message', 'Demonstrating an error message.')
|
||||
})
|
||||
|
||||
ipcMain.on('open-information-dialog', event => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, index => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
|
||||
ipcMain.on('open-file-dialog', event => {
|
||||
dialog.showOpenDialog(
|
||||
{
|
||||
properties: ['openFile', 'openDirectory']
|
||||
},
|
||||
files => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
ipcMain.on('save-dialog', event => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
|
||||
}
|
||||
dialog.showSaveDialog(options, filename => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
const errorBtn = document.getElementById('error-dialog')
|
||||
|
||||
errorBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-error-dialog')
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
const errorBtn = document.getElementById('error-dialog')
|
||||
|
||||
errorBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-error-dialog')
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,70 +1,70 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('open-information-dialog', event => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, index => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('open-information-dialog', event => {
|
||||
const options = {
|
||||
type: 'info',
|
||||
title: 'Information',
|
||||
message: "This is an information dialog. Isn't it nice?",
|
||||
buttons: ['Yes', 'No']
|
||||
}
|
||||
dialog.showMessageBox(options, index => {
|
||||
event.sender.send('information-dialog-selection', index)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const informationBtn = document.getElementById('information-dialog')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
informationBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-information-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('information-dialog-selection', (event, index) => {
|
||||
let message = 'You selected '
|
||||
if (index === 0) message += 'yes.'
|
||||
else message += 'no.'
|
||||
document.getElementById('info-selection').innerHTML = message
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const informationBtn = document.getElementById('information-dialog')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
informationBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-information-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('information-dialog-selection', (event, index) => {
|
||||
let message = 'You selected '
|
||||
if (index === 0) message += 'yes.'
|
||||
else message += 'no.'
|
||||
document.getElementById('info-selection').innerHTML = message
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,70 +1,70 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('open-file-dialog', event => {
|
||||
dialog.showOpenDialog(
|
||||
{
|
||||
properties: ['openFile', 'openDirectory']
|
||||
},
|
||||
files => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('open-file-dialog', event => {
|
||||
dialog.showOpenDialog(
|
||||
{
|
||||
properties: ['openFile', 'openDirectory']
|
||||
},
|
||||
files => {
|
||||
if (files) {
|
||||
event.sender.send('selected-directory', files)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const selectDirBtn = document.getElementById('select-directory')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
selectDirBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-file-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('selected-directory', (event, path) => {
|
||||
document.getElementById('selected-file').innerHTML = `You selected: ${path}`
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const selectDirBtn = document.getElementById('select-directory')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
selectDirBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('open-file-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('selected-directory', (event, path) => {
|
||||
document.getElementById('selected-file').innerHTML = `You selected: ${path}`
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('save-dialog', event => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
|
||||
}
|
||||
dialog.showSaveDialog(options, filename => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('save-dialog', event => {
|
||||
const options = {
|
||||
title: 'Save an Image',
|
||||
filters: [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]
|
||||
}
|
||||
dialog.showSaveDialog(options, filename => {
|
||||
event.sender.send('saved-file', filename)
|
||||
})
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const saveBtn = document.getElementById('save-dialog')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
saveBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('save-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('saved-file', (event, path) => {
|
||||
if (!path) path = 'No path'
|
||||
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const saveBtn = document.getElementById('save-dialog')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
saveBtn.addEventListener('click', event => {
|
||||
ipcRenderer.send('save-dialog')
|
||||
})
|
||||
|
||||
ipcRenderer.on('saved-file', (event, path) => {
|
||||
if (!path) path = 'No path'
|
||||
document.getElementById('file-saved').innerHTML = `Path selected: ${path}`
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,56 +1,56 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
const { shell } = require('electron')
|
||||
const os = require('os')
|
||||
|
||||
const exLinksBtn = document.getElementById('open-ex-links')
|
||||
const fileManagerBtn = document.getElementById('open-file-manager')
|
||||
|
||||
fileManagerBtn.addEventListener('click', (event) => {
|
||||
shell.showItemInFolder(os.homedir())
|
||||
})
|
||||
|
||||
exLinksBtn.addEventListener('click', (event) => {
|
||||
shell.openExternal('https://electronjs.org')
|
||||
const { shell } = require('electron')
|
||||
const os = require('os')
|
||||
|
||||
const exLinksBtn = document.getElementById('open-ex-links')
|
||||
const fileManagerBtn = document.getElementById('open-file-manager')
|
||||
|
||||
fileManagerBtn.addEventListener('click', (event) => {
|
||||
shell.showItemInFolder(os.homedir())
|
||||
})
|
||||
|
||||
exLinksBtn.addEventListener('click', (event) => {
|
||||
shell.openExternal('https://electronjs.org')
|
||||
})
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
const basicNotification = {
|
||||
title: 'Basic Notification',
|
||||
body: 'Short message part'
|
||||
}
|
||||
|
||||
const notification = {
|
||||
title: 'Notification with image',
|
||||
body: 'Short message plus a custom image',
|
||||
icon: 'https://via.placeholder.com/150'
|
||||
}
|
||||
|
||||
const basicNotificationButton = document.getElementById('basic-noti')
|
||||
const notificationButton = document.getElementById('advanced-noti')
|
||||
|
||||
notificationButton.addEventListener('click', () => {
|
||||
const myNotification = new window.Notification(notification.title, notification)
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
})
|
||||
|
||||
basicNotificationButton.addEventListener('click', () => {
|
||||
const myNotification = new window.Notification(basicNotification.title, basicNotification)
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
})
|
||||
const basicNotification = {
|
||||
title: 'Basic Notification',
|
||||
body: 'Short message part'
|
||||
}
|
||||
|
||||
const notification = {
|
||||
title: 'Notification with image',
|
||||
body: 'Short message plus a custom image',
|
||||
icon: 'https://via.placeholder.com/150'
|
||||
}
|
||||
|
||||
const basicNotificationButton = document.getElementById('basic-noti')
|
||||
const notificationButton = document.getElementById('advanced-noti')
|
||||
|
||||
notificationButton.addEventListener('click', () => {
|
||||
const myNotification = new window.Notification(notification.title, notification)
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
})
|
||||
|
||||
basicNotificationButton.addEventListener('click', () => {
|
||||
const myNotification = new window.Notification(basicNotification.title, basicNotification)
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
})
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,35 +1,35 @@
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const trayBtn = document.getElementById('put-in-tray')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let trayOn = false
|
||||
|
||||
trayBtn.addEventListener('click', function (event) {
|
||||
if (trayOn) {
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
ipcRenderer.send('remove-tray')
|
||||
} else {
|
||||
trayOn = true
|
||||
const message = 'Click demo again to remove.'
|
||||
document.getElementById('tray-countdown').innerHTML = message
|
||||
ipcRenderer.send('put-in-tray')
|
||||
}
|
||||
})
|
||||
// Tray removed from context menu on icon
|
||||
ipcRenderer.on('tray-removed', function () {
|
||||
ipcRenderer.send('remove-tray')
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
const { ipcRenderer, shell } = require('electron')
|
||||
|
||||
const trayBtn = document.getElementById('put-in-tray')
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let trayOn = false
|
||||
|
||||
trayBtn.addEventListener('click', function (event) {
|
||||
if (trayOn) {
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
ipcRenderer.send('remove-tray')
|
||||
} else {
|
||||
trayOn = true
|
||||
const message = 'Click demo again to remove.'
|
||||
document.getElementById('tray-countdown').innerHTML = message
|
||||
ipcRenderer.send('put-in-tray')
|
||||
}
|
||||
})
|
||||
// Tray removed from context menu on icon
|
||||
ipcRenderer.on('tray-removed', function () {
|
||||
ipcRenderer.send('remove-tray')
|
||||
trayOn = false
|
||||
document.getElementById('tray-countdown').innerHTML = ''
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,56 +1,56 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
|
||||
const framelessWindowBtn = document.getElementById('frameless-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
framelessWindowBtn.addEventListener('click', (event) => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
let win = new BrowserWindow({ frame: false })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
|
||||
const framelessWindowBtn = document.getElementById('frameless-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
framelessWindowBtn.addEventListener('click', (event) => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
let win = new BrowserWindow({ frame: false })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
|
||||
const manageWindowBtn = document.getElementById('manage-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let win
|
||||
|
||||
manageWindowBtn.addEventListener('click', (event) => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
win = new BrowserWindow({ width: 400, height: 275 })
|
||||
|
||||
win.on('resize', updateReply)
|
||||
win.on('move', updateReply)
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
|
||||
function updateReply () {
|
||||
const manageWindowReply = document.getElementById('manage-window-reply')
|
||||
const message = `Size: ${win.getSize()} Position: ${win.getPosition()}`
|
||||
manageWindowReply.innerText = message
|
||||
}
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
|
||||
const manageWindowBtn = document.getElementById('manage-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let win
|
||||
|
||||
manageWindowBtn.addEventListener('click', (event) => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
win = new BrowserWindow({ width: 400, height: 275 })
|
||||
|
||||
win.on('resize', updateReply)
|
||||
win.on('move', updateReply)
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
|
||||
function updateReply () {
|
||||
const manageWindowReply = document.getElementById('manage-window-reply')
|
||||
const message = `Size: ${win.getSize()} Position: ${win.getPosition()}`
|
||||
manageWindowReply.innerText = message
|
||||
}
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', function () {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
// On macOS it is common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
|
||||
const listenToWindowBtn = document.getElementById('listen-to-window')
|
||||
const focusModalBtn = document.getElementById('focus-on-modal-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let win
|
||||
|
||||
listenToWindowBtn.addEventListener('click', () => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
win = new BrowserWindow({ width: 600, height: 400 })
|
||||
|
||||
const hideFocusBtn = () => {
|
||||
focusModalBtn.classList.add('disappear')
|
||||
focusModalBtn.classList.remove('smooth-appear')
|
||||
focusModalBtn.removeEventListener('click', clickHandler)
|
||||
}
|
||||
|
||||
const showFocusBtn = (btn) => {
|
||||
if (!win) return
|
||||
focusModalBtn.classList.add('smooth-appear')
|
||||
focusModalBtn.classList.remove('disappear')
|
||||
focusModalBtn.addEventListener('click', clickHandler)
|
||||
}
|
||||
|
||||
win.on('focus', hideFocusBtn)
|
||||
win.on('blur', showFocusBtn)
|
||||
win.on('close', () => {
|
||||
hideFocusBtn()
|
||||
win = null
|
||||
})
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
|
||||
const clickHandler = () => { win.focus() }
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
|
||||
const listenToWindowBtn = document.getElementById('listen-to-window')
|
||||
const focusModalBtn = document.getElementById('focus-on-modal-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let win
|
||||
|
||||
listenToWindowBtn.addEventListener('click', () => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
win = new BrowserWindow({ width: 600, height: 400 })
|
||||
|
||||
const hideFocusBtn = () => {
|
||||
focusModalBtn.classList.add('disappear')
|
||||
focusModalBtn.classList.remove('smooth-appear')
|
||||
focusModalBtn.removeEventListener('click', clickHandler)
|
||||
}
|
||||
|
||||
const showFocusBtn = (btn) => {
|
||||
if (!win) return
|
||||
focusModalBtn.classList.add('smooth-appear')
|
||||
focusModalBtn.classList.remove('disappear')
|
||||
focusModalBtn.addEventListener('click', clickHandler)
|
||||
}
|
||||
|
||||
win.on('focus', hideFocusBtn)
|
||||
win.on('blur', showFocusBtn)
|
||||
win.on('close', () => {
|
||||
hideFocusBtn()
|
||||
win = null
|
||||
})
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
|
||||
const clickHandler = () => { win.focus() }
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# Electron App Feedback Program
|
||||
|
||||
Electron is working on building a streamlined release process and having faster releases. To help with that, we have the App Feedback Program for large-scale Electron apps to test our beta releases and report app-specific issues to the Electron team. We use this program to help us prioritize work and get applications upgraded to the next stable release as soon as possible. There are a few requirements we expect from participants, such as attending short, online weekly check-ins. Please visit the [blog post](https://electronjs.org/blog/app-feedback-program) for details and sign-up.
|
||||
@@ -15,7 +15,7 @@ can open them programmatically by calling the `openDevTools()` API on the
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
let win = new BrowserWindow()
|
||||
const win = new BrowserWindow()
|
||||
win.webContents.openDevTools()
|
||||
```
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ fs.readdirSync('/path/to/example.asar')
|
||||
Use a module from the archive:
|
||||
|
||||
```javascript
|
||||
require('/path/to/example.asar/dir/module.js')
|
||||
require('./path/to/example.asar/dir/module.js')
|
||||
```
|
||||
|
||||
You can also display a web page in an `asar` archive with `BrowserWindow`:
|
||||
|
||||
@@ -9,9 +9,9 @@ const childProcess = require('child_process')
|
||||
const electronPath = require('electron')
|
||||
|
||||
// spawn the process
|
||||
let env = { /* ... */ }
|
||||
let stdio = ['inherit', 'inherit', 'inherit', 'ipc']
|
||||
let appProcess = childProcess.spawn(electronPath, ['./app'], { stdio, env })
|
||||
const env = { /* ... */ }
|
||||
const stdio = ['inherit', 'inherit', 'inherit', 'ipc']
|
||||
const appProcess = childProcess.spawn(electronPath, ['./app'], { stdio, env })
|
||||
|
||||
// listen for IPC messages from the app
|
||||
appProcess.on('message', (msg) => {
|
||||
@@ -50,7 +50,7 @@ class TestDriver {
|
||||
// handle rpc responses
|
||||
this.process.on('message', (message) => {
|
||||
// pop the handler
|
||||
let rpcCall = this.rpcCalls[message.msgId]
|
||||
const rpcCall = this.rpcCalls[message.msgId]
|
||||
if (!rpcCall) return
|
||||
this.rpcCalls[message.msgId] = null
|
||||
// reject/resolve
|
||||
@@ -70,7 +70,7 @@ class TestDriver {
|
||||
// to use: driver.rpc('method', 1, 2, 3).then(...)
|
||||
async rpc (cmd, ...args) {
|
||||
// send rpc request
|
||||
let msgId = this.rpcCalls.length
|
||||
const msgId = this.rpcCalls.length
|
||||
this.process.send({ msgId, cmd, args })
|
||||
return new Promise((resolve, reject) => this.rpcCalls.push({ resolve, reject }))
|
||||
}
|
||||
@@ -92,10 +92,10 @@ async function onMessage ({ msgId, cmd, args }) {
|
||||
let method = METHODS[cmd]
|
||||
if (!method) method = () => new Error('Invalid method: ' + cmd)
|
||||
try {
|
||||
let resolve = await method(...args)
|
||||
const resolve = await method(...args)
|
||||
process.send({ msgId, resolve })
|
||||
} catch (err) {
|
||||
let reject = {
|
||||
const reject = {
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
name: err.name
|
||||
@@ -119,7 +119,7 @@ Then, in your test suite, you can use your test-driver as follows:
|
||||
const test = require('ava')
|
||||
const electronPath = require('electron')
|
||||
|
||||
let app = new TestDriver({
|
||||
const app = new TestDriver({
|
||||
path: electronPath,
|
||||
args: ['./app'],
|
||||
env: {
|
||||
|
||||
@@ -100,6 +100,25 @@ To see all of this in action, check out Electron Fiddle's source code,
|
||||
[especially its `electron-forge` configuration
|
||||
file](https://github.com/electron/fiddle/blob/master/forge.config.js).
|
||||
|
||||
If you plan to access the microphone or camera within your app using Electron's APIs, you'll also
|
||||
need to add the following entitlements:
|
||||
|
||||
```xml
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
```
|
||||
|
||||
If these are not present in your app's entitlements when you invoke, for example:
|
||||
|
||||
```js
|
||||
const { systemPreferences } = require('electron')
|
||||
|
||||
const microphone = systemPreferences.askForMediaAccess('microphone')
|
||||
```
|
||||
|
||||
Your app may crash. See the Resource Access section in [Hardened Runtime](https://developer.apple.com/documentation/security/hardened_runtime) for more information and entitlements you may need.
|
||||
|
||||
## `electron-builder`
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ e.g. `2.0.1`.
|
||||
|
||||
Specifically, the above means:
|
||||
|
||||
1. Admitting non-breaking-API changes before Week 3 in the beta cycle is okay, even if those changes have the potential to cause moderate side-affects
|
||||
1. Admitting non-breaking-API changes before Week 3 in the beta cycle is okay, even if those changes have the potential to cause moderate side-effects
|
||||
2. Admitting feature-flagged changes, that do not otherwise alter existing code paths, at most points in the beta cycle is okay. Users can explicitly enable those flags in their apps.
|
||||
3. Admitting features of any sort after Week 3 in the beta cycle is 👎 without a very good reason.
|
||||
|
||||
@@ -139,7 +139,7 @@ We seek to increase clarity at all levels of the update and releases process. St
|
||||
* Commits that would result in a semver **minor** bump must start with `feat:`.
|
||||
* Commits that would result in a semver **patch** bump must start with `fix:`.
|
||||
|
||||
* We allow squashing of commits, provided that the squashed message adheres the the above message format.
|
||||
* We allow squashing of commits, provided that the squashed message adheres to the above message format.
|
||||
* It is acceptable for some commits in a pull request to not include a semantic prefix, as long as the pull request title contains a meaningful encompassing semantic message.
|
||||
|
||||
# Versioned `master`
|
||||
|
||||
@@ -44,23 +44,10 @@ run the main process. An example of your `package.json` might look like this:
|
||||
```
|
||||
|
||||
__Note__: If the `main` field is not present in `package.json`, Electron will
|
||||
attempt to load an `index.js` (as Node.js does). If this was actually
|
||||
a simple Node application, you would add a `start` script that instructs `node`
|
||||
to execute the current package:
|
||||
attempt to load an `index.js` (as Node.js does).
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "your-app",
|
||||
"version": "0.1.0",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"start": "node ."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Turning this Node application into an Electron application is quite simple - we
|
||||
merely replace the `node` runtime with the `electron` runtime.
|
||||
By default, `npm start` would run the main script with Node.js. in order to make
|
||||
it run with Electron, you can add a `start` script:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -109,7 +96,7 @@ const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
let win = new BrowserWindow({
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
@@ -154,10 +141,10 @@ function createWindow () {
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
// Quit when all windows are closed.
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
app.on('window-all-closed', () => {
|
||||
// On macOS it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
|
||||
@@ -37,18 +37,18 @@ inAppPurchase.on('transactions-updated', (event, transactions) => {
|
||||
|
||||
// Check each transaction.
|
||||
transactions.forEach(function (transaction) {
|
||||
let payment = transaction.payment
|
||||
const payment = transaction.payment
|
||||
|
||||
switch (transaction.transactionState) {
|
||||
case 'purchasing':
|
||||
console.log(`Purchasing ${payment.productIdentifier}...`)
|
||||
break
|
||||
case 'purchased':
|
||||
|
||||
case 'purchased': {
|
||||
console.log(`${payment.productIdentifier} purchased.`)
|
||||
|
||||
// Get the receipt url.
|
||||
let receiptURL = inAppPurchase.getReceiptURL()
|
||||
const receiptURL = inAppPurchase.getReceiptURL()
|
||||
|
||||
console.log(`Receipt URL: ${receiptURL}`)
|
||||
|
||||
@@ -62,6 +62,8 @@ inAppPurchase.on('transactions-updated', (event, transactions) => {
|
||||
inAppPurchase.finishTransactionByDate(transaction.transactionDate)
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'failed':
|
||||
|
||||
console.log(`Failed to purchase ${payment.productIdentifier}.`)
|
||||
@@ -105,8 +107,8 @@ inAppPurchase.getProducts(PRODUCT_IDS).then(products => {
|
||||
})
|
||||
|
||||
// Ask the user which product he/she wants to purchase.
|
||||
let selectedProduct = products[0]
|
||||
let selectedQuantity = 1
|
||||
const selectedProduct = products[0]
|
||||
const selectedQuantity = 1
|
||||
|
||||
// Purchase the selected product.
|
||||
inAppPurchase.purchaseProduct(selectedProduct.productIdentifier, selectedQuantity).then(isProductValid => {
|
||||
|
||||
@@ -10,7 +10,7 @@ so the `nodeIntegrationInWorker` option should be set to `true` in
|
||||
`webPreferences`.
|
||||
|
||||
```javascript
|
||||
let win = new BrowserWindow({
|
||||
const win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
nodeIntegrationInWorker: true
|
||||
}
|
||||
@@ -44,7 +44,7 @@ loads no native modules after the Web Workers get started.
|
||||
process.dlopen = () => {
|
||||
throw new Error('Load native module is not safe')
|
||||
}
|
||||
let worker = new Worker('script.js')
|
||||
const worker = new Worker('script.js')
|
||||
```
|
||||
|
||||
[web-workers]: https://developer.mozilla.org/en/docs/Web/API/Web_Workers_API/Using_web_workers
|
||||
|
||||
@@ -10,7 +10,7 @@ you want to show Notifications in the main process please check out the
|
||||
[Notification](../api/notification.md) module.
|
||||
|
||||
```javascript
|
||||
let myNotification = new Notification('Title', {
|
||||
const myNotification = new Notification('Title', {
|
||||
body: 'Lorem Ipsum Dolor Sit Amet'
|
||||
})
|
||||
|
||||
|
||||
@@ -39,6 +39,29 @@ will be started with the path of the file added as a command line argument.
|
||||
|
||||
## macOS Notes
|
||||
|
||||
### Adding the Recent Documents list to the application menu:
|
||||
|
||||
![macOS Recent Documents menu item][menu-item-image]
|
||||
|
||||
You can add menu items to access and clear recent documents by adding the following code snippet to your menu's template.
|
||||
|
||||
```json
|
||||
{
|
||||
"submenu":[
|
||||
{
|
||||
"label":"Open Recent",
|
||||
"role":"recentdocuments",
|
||||
"submenu":[
|
||||
{
|
||||
"label":"Clear Recent",
|
||||
"role":"clearrecentdocuments"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
When a file is requested from the recent documents menu, the `open-file` event
|
||||
of `app` module will be emitted for it.
|
||||
|
||||
@@ -47,3 +70,4 @@ of `app` module will be emitted for it.
|
||||
[addrecentdocument]: ../api/app.md#appaddrecentdocumentpath-macos-windows
|
||||
[clearrecentdocuments]: ../api/app.md#appclearrecentdocuments-macos-windows
|
||||
[app-registration]: https://msdn.microsoft.com/en-us/library/cc144104(VS.85).aspx
|
||||
[menu-item-image]: https://user-images.githubusercontent.com/3168941/33003655-ea601c3a-cd70-11e7-97fa-7c062149cfb1.png
|
||||
|
||||
@@ -9,12 +9,8 @@ If you're looking for programming help,
|
||||
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
|
||||
- [`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)*
|
||||
|
||||
@@ -42,7 +42,7 @@ app.commandLine.appendSwitch('ppapi-flash-path', path.join(__dirname, pluginName
|
||||
app.commandLine.appendSwitch('ppapi-flash-version', '17.0.0.169')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
let win = new BrowserWindow({
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user