Compare commits

..

15 Commits

Author SHA1 Message Date
Electron Bot
0bdb7b164c Bump v7.0.0-beta.2 2019-08-07 09:03:21 -07:00
trop[bot]
ea9cfc127c fix: crash on print cancellation and silent print settings (#19668)
* fix: crash on print cancellation

* fix: update printing patch for new options

* refactor: use DictionaryValue for printBackground
2019-08-07 08:44:48 -07:00
trop[bot]
0afb1a8188 fix: handle edge behavior for about panel on Linux (#19625)
* fix: graceful About dialog fail/exit (Linux)

* Allow current to travel along path with no electrical impedance
2019-08-05 20:57:04 -07:00
trop[bot]
f154dbda40 docs: remove implicit 'any' and 'Object' types from the docs (#19630)
* docs: remove implicit 'any' and 'Object' types from the docs

* docs: more docs improvements, remove all remaining empty interfaces

* chore: update tests for better types
2019-08-05 20:56:42 -07:00
trop[bot]
c3013d2e9f fix: clearRecentDocuments role on Windows (#19638)
* fix: clear recent documents on windows

* chore: don't check for version < win 7
2019-08-05 17:16:20 -07:00
trop[bot]
3272564eac fix: make child windows not crash when ipc messages are received (#19632)
* fix: make child windows not crash when ipc messages are received

This also adds a path forward for apps using child windows with
nodeIntegration to migrate into a non-leaky way of doing it.

1. Ensure that if ipcNative is missing we don't crash rather log that it
is missing
2. Add a hidden option `--enable-node-leakage-in-renderers` (temporary
measure) to allow app devs to opt in to leaking node in child windows
3. Bypasses the Opener() check if renderer process reuse is enabled
(which would prevent the leak anyway)

So the path forward is: it no longer crashes --> folks use the hidden
option --> folks opt in to renderer process reuse.

* Apply suggestions from code review

Co-Authored-By: Jeremy Apthorp <jeremya@chromium.org>

* Update shell/renderer/atom_renderer_client.cc

Co-Authored-By: Jeremy Apthorp <jeremya@chromium.org>
2019-08-05 15:11:01 -07:00
trop[bot]
a0f4632461 fix: crash on window.print() (#19623) 2019-08-05 07:52:08 -07:00
trop[bot]
8ddf837d49 fix: expose setMenuBarVisibility again (#19579) 2019-08-02 19:06:47 -07:00
Samuel Attard
9822953d31 build: lock chromium major to 78 on 7-0-x (#19552)
* build: lock chromium major to 78 on 7-0-x

* chore: update patches

* fix geometry.mojom

* Adopt more inclusive language in //net

https://chromium-review.googlesource.com/c/chromium/src/+/1718348

* [mojo] Introduce ServiceFactory API

https://chromium-review.googlesource.com/c/chromium/src/+/1717474
2019-08-02 15:41:41 -04:00
trop[bot]
c6061cce41 doc: add missing MenuItem roles (#19555) 2019-07-31 19:12:52 -07:00
trop[bot]
a9602682c5 fix: use WeakPtr to detect deletion (#19558) 2019-07-31 19:12:32 -07:00
Electron Bot
b7e5213afc Bump v7.0.0-beta.1 2019-07-31 13:36:10 -07:00
Samuel Attard
9b70d9aa68 Revert "Bump v7.0.0-beta.1"
This reverts commit d9bfac32e3.
2019-07-31 13:30:47 -07:00
Electron Bot
d9bfac32e3 Bump v7.0.0-beta.1 2019-07-31 11:07:14 -07:00
Samuel Attard
9e815afc02 build: fix first beta version choosing logic 2019-07-31 11:01:25 -07:00
550 changed files with 13136 additions and 10234 deletions

View File

@@ -91,19 +91,13 @@ env-linux-medium: &env-linux-medium
NUMBER_OF_NINJA_PROCESSES: 3
env-linux-2xlarge: &env-linux-2xlarge
NUMBER_OF_NINJA_PROCESSES: 34
env-linux-2xlarge-release: &env-linux-2xlarge-release
NUMBER_OF_NINJA_PROCESSES: 16
NUMBER_OF_NINJA_PROCESSES: 18
env-machine-mac: &env-machine-mac
NUMBER_OF_NINJA_PROCESSES: 6
env-mac-large: &env-mac-large
NUMBER_OF_NINJA_PROCESSES: 18
env-mac-large-release: &env-mac-large-release
NUMBER_OF_NINJA_PROCESSES: 8
NUMBER_OF_NINJA_PROCESSES: 10
env-disable-crash-reporter-tests: &env-disable-crash-reporter-tests
DISABLE_CRASH_REPORTER_TESTS: true
@@ -192,13 +186,6 @@ step-restore-brew-cache: &step-restore-brew-cache
keys:
- v1-brew-cache-{{ arch }}
step-save-brew-cache: &step-save-brew-cache
save_cache:
paths:
- /usr/local/Homebrew
key: v1-brew-cache-{{ arch }}
name: Persisting brew cache
step-get-more-space-on-mac: &step-get-more-space-on-mac
run:
name: Free up space on MacOS
@@ -548,93 +535,6 @@ step-ninja-summary: &step-ninja-summary
command: |
python depot_tools/post_build_ninja_summary.py -C src/out/Default
# Checkout Steps
step-generate-deps-hash: &step-generate-deps-hash
run:
name: Generate DEPS Hash
command: node src/electron/script/generate-deps-hash.js
step-touch-sync-done: &step-touch-sync-done
run:
name: Touch Sync Done
command: touch src/electron/.circle-sync-done
# Restore exact src cache based on the hash of DEPS and patches/*
# If no cache is matched EXACTLY then the .circle-sync-done file is empty
# If a cache is matched EXACTLY then the .circle-sync-done file contains "done"
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
restore_cache:
paths:
- ./src
keys:
- v5-src-cache-{{ arch }}-{{ checksum "src/electron/.depshash" }}
name: Restoring src cache
# 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
# If the src cache was not restored above then this will match a close git cache
step-maybe-restore-git-cache: &step-maybe-restore-git-cache
restore_cache:
paths:
- ~/.gclient-cache
keys:
- v2-gclient-cache-{{ arch }}-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
- v2-gclient-cache-{{ arch }}-{{ checksum "src/electron/.circle-sync-done" }}
name: Conditionally restoring git cache
step-set-git-cache-path: &step-set-git-cache-path
run:
name: Set GIT_CACHE_PATH to make gclient to use the cache
command: |
# CircleCI does not support interpolation when setting environment variables.
# https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-shell-command
echo 'export GIT_CACHE_PATH="$HOME/.gclient-cache"' >> $BASH_ENV
# Persist the git cache based on the hash of DEPS and .circle-sync-done
# If the src cache was restored above then this will persist an empty cache
step-save-git-cache: &step-save-git-cache
save_cache:
paths:
- ~/.gclient-cache
key: v2-gclient-cache-{{ arch }}-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
name: Persisting git cache
step-run-electron-only-hooks: &step-run-electron-only-hooks
run:
name: Run Electron Only Hooks
command: gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
step-generate-deps-hash-cleanly: &step-generate-deps-hash-cleanly
run:
name: Generate DEPS Hash
command: (cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js
# Mark the sync as done for future cache saving
step-mark-sync-done: &step-mark-sync-done
run:
name: Mark Sync Done
command: echo DONE > src/electron/.circle-sync-done
# Minimize the size of the cache
step-minimize-workspace-size-from-checkout: &step-minimize-workspace-size-from-checkout
run:
name: Remove some unused data to avoid storing it in the workspace/cache
command: |
rm -rf src/android_webview
rm -rf src/ios
rm -rf src/third_party/blink/web_tests
rm -rf src/third_party/blink/perf_tests
rm -rf src/third_party/hunspell_dictionaries
rm -rf src/third_party/WebKit/LayoutTests
# Save the src cache based on the deps hash
step-save-src-cache: &step-save-src-cache
save_cache:
paths:
- ./src
key: v5-src-cache-{{ arch }}-{{ checksum "src/electron/.depshash" }}
name: Persisting src cache
# Lists of steps.
steps-lint: &steps-lint
steps:
@@ -680,7 +580,7 @@ steps-lint: &steps-lint
node script/yarn install --frozen-lockfile
node script/yarn lint
steps-checkout-fast: &steps-checkout-fast
steps-checkout: &steps-checkout
steps:
- *step-checkout-electron
- *step-depot-tools-get
@@ -689,57 +589,88 @@ steps-checkout-fast: &steps-checkout-fast
- *step-get-more-space-on-mac
- *step-install-gnutar-on-mac
- *step-generate-deps-hash
- *step-touch-sync-done
- *step-maybe-restore-src-cache
- *step-maybe-restore-git-cache
- *step-set-git-cache-path
- run:
name: Generate DEPS Hash
command: node src/electron/script/generate-deps-hash.js
- run:
name: Touch Sync Done
command: touch src/electron/.circle-sync-done
# Restore exact src cache based on the hash of DEPS and patches/*
# If no cache is matched EXACTLY then the .circle-sync-done file is empty
# If a cache is matched EXACTLY then the .circle-sync-done file contains "done"
- restore_cache:
paths:
- ./src
keys:
- v5-src-cache-{{ arch }}-{{ checksum "src/electron/.depshash" }}
name: Restoring src cache
# 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
# If the src cache was not restored above then this will match a close git cache
- restore_cache:
paths:
- ~/.gclient-cache
keys:
- v2-gclient-cache-{{ arch }}-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
- v2-gclient-cache-{{ arch }}-{{ checksum "src/electron/.circle-sync-done" }}
name: Conditionally restoring git cache
- run:
name: Set GIT_CACHE_PATH to make gclient to use the cache
command: |
# CircleCI does not support interpolation when setting environment variables.
# https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-shell-command
echo 'export GIT_CACHE_PATH="$HOME/.gclient-cache"' >> $BASH_ENV
# This sync call only runs if .circle-sync-done is an EMPTY file
- *step-gclient-sync
# Persist the git cache based on the hash of DEPS and .circle-sync-done
# If the src cache was restored above then this will persist an empty cache
- save_cache:
paths:
- ~/.gclient-cache
key: v2-gclient-cache-{{ arch }}-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
name: Persisting git cache
# These next few steps reset Electron to the correct commit regardless of which cache was restored
- run:
name: Wipe Electron
command: rm -rf src/electron
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
- *step-mark-sync-done
- *step-minimize-workspace-size-from-checkout
- run:
name: Run Electron Only Hooks
command: gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
- run:
name: Generate DEPS Hash
command: (cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js
# Mark the sync as done for future cache saving
- run:
name: Mark Sync Done
command: echo DONE > src/electron/.circle-sync-done
# Minimize the size of the cache
- run:
name: Remove some unused data to avoid storing it in the workspace/cache
command: |
rm -rf src/android_webview
rm -rf src/ios
rm -rf src/third_party/blink/web_tests
rm -rf src/third_party/blink/perf_tests
rm -rf src/third_party/hunspell_dictionaries
rm -rf src/third_party/WebKit/LayoutTests
# Save the src cache based on the deps hash
- save_cache:
paths:
- ./src
key: v5-src-cache-{{ arch }}-{{ checksum "src/electron/.depshash" }}
name: Persisting src cache
- save_cache:
paths:
- /usr/local/Homebrew
key: v1-brew-cache-{{ arch }}
name: Persisting brew cache
- persist_to_workspace:
root: .
paths:
- depot_tools
- src
steps-checkout-and-save-cache: &steps-checkout-and-save-cache
steps:
- *step-checkout-electron
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-restore-brew-cache
- *step-get-more-space-on-mac
- *step-install-gnutar-on-mac
- *step-generate-deps-hash
- *step-touch-sync-done
- *step-maybe-restore-src-cache
- *step-maybe-restore-git-cache
- *step-set-git-cache-path
# This sync call only runs if .circle-sync-done is an EMPTY file
- *step-gclient-sync
- *step-save-git-cache
# These next few steps reset Electron to the correct commit regardless of which cache was restored
- run:
name: Wipe Electron
command: rm -rf src/electron
- *step-checkout-electron
- *step-run-electron-only-hooks
- *step-generate-deps-hash-cleanly
- *step-mark-sync-done
- *step-minimize-workspace-size-from-checkout
- *step-save-src-cache
- *step-save-brew-cache
steps-electron-gn-check: &steps-electron-gn-check
steps:
- attach_workspace:
@@ -776,11 +707,9 @@ steps-electron-build-for-tests: &steps-electron-build-for-tests
- *step-depot-tools-add-to-path
- *step-setup-env-for-build
- *step-restore-brew-cache
- *step-get-more-space-on-mac
- *step-install-npm-deps-on-mac
- *step-fix-sync-on-mac
- *step-gn-gen-default
- *step-delete-git-directories
# Electron app
- *step-electron-build
@@ -1018,47 +947,33 @@ jobs:
<<: *steps-lint
# Layer 1: Checkout.
linux-checkout-fast:
linux-checkout:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-checkout-fast
linux-checkout-and-save-cache:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-checkout-and-save-cache
<<: *steps-checkout
linux-checkout-for-native-tests:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_pyyaml=True'
<<: *steps-checkout-fast
<<: *steps-checkout
linux-checkout-for-native-tests-with-no-patches:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=apply_patches=False --custom-var=checkout_pyyaml=True'
<<: *steps-checkout-fast
<<: *steps-checkout
mac-checkout-fast:
mac-checkout:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
<<: *steps-checkout-fast
mac-checkout-and-save-cache:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
<<: *steps-checkout-and-save-cache
<<: *steps-checkout
# Layer 2: Builds.
linux-x64-debug:
@@ -1125,7 +1040,7 @@ jobs:
linux-x64-publish:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge-release
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
<<: *env-release-build
<<: *steps-electron-build-for-publish
@@ -1174,7 +1089,7 @@ jobs:
linux-ia32-publish:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge-release
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
<<: *env-ia32
<<: *env-release-build
@@ -1225,7 +1140,7 @@ jobs:
linux-arm-publish:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge-release
<<: *env-linux-2xlarge
<<: *env-arm
<<: *env-release-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
@@ -1292,7 +1207,7 @@ jobs:
linux-arm64-publish:
<<: *machine-linux-2xlarge
environment:
<<: *env-linux-2xlarge-release
<<: *env-linux-2xlarge
<<: *env-arm64
<<: *env-release-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm64=True --custom-var=checkout_boto=True --custom-var=checkout_requests=True'
@@ -1307,15 +1222,6 @@ jobs:
<<: *env-ninja-status
<<: *steps-electron-build-for-tests
osx-debug:
<<: *machine-mac-large
environment:
<<: *env-mac-large
<<: *env-debug-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build-for-tests
osx-debug-gn-check:
<<: *machine-mac
environment:
@@ -1351,7 +1257,7 @@ jobs:
osx-publish:
<<: *machine-mac-large
environment:
<<: *env-mac-large-release
<<: *env-mac-large
<<: *env-release-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
<<: *steps-electron-build-for-publish
@@ -1366,16 +1272,6 @@ jobs:
<<: *env-ninja-status
<<: *steps-electron-build-for-tests
mas-debug:
<<: *machine-mac-large
environment:
<<: *env-mac-large
<<: *env-mas
<<: *env-debug-build
<<: *env-enable-sccache
<<: *env-ninja-status
<<: *steps-electron-build-for-tests
mas-debug-gn-check:
<<: *machine-mac
environment:
@@ -1414,7 +1310,7 @@ jobs:
mas-publish:
<<: *machine-mac-large
environment:
<<: *env-mac-large-release
<<: *env-mac-large
<<: *env-mas
<<: *env-release-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_boto=True --custom-var=checkout_requests=True'
@@ -1679,24 +1575,23 @@ workflows:
build-linux:
jobs:
- linux-checkout-fast
- linux-checkout-and-save-cache
- linux-checkout
- linux-x64-debug:
requires:
- linux-checkout-fast
- linux-checkout
- linux-x64-debug-gn-check:
requires:
- linux-checkout-fast
- linux-checkout
- linux-x64-testing:
requires:
- linux-checkout-fast
- linux-checkout
- linux-x64-testing-no-run-as-node:
requires:
- linux-checkout-fast
- linux-checkout
- linux-x64-testing-gn-check:
requires:
- linux-checkout-fast
- linux-checkout
- linux-x64-testing-tests:
requires:
- linux-x64-testing
@@ -1709,10 +1604,10 @@ workflows:
- linux-ia32-debug:
requires:
- linux-checkout-fast
- linux-checkout
- linux-ia32-testing:
requires:
- linux-checkout-fast
- linux-checkout
- linux-ia32-testing-tests:
requires:
- linux-ia32-testing
@@ -1725,44 +1620,37 @@ workflows:
- linux-arm-debug:
requires:
- linux-checkout-fast
- linux-checkout
- linux-arm-testing:
requires:
- linux-checkout-fast
- linux-checkout
- linux-arm64-debug:
requires:
- linux-checkout-fast
- linux-checkout
- linux-arm64-debug-gn-check:
requires:
- linux-checkout-fast
- linux-checkout
- linux-arm64-testing:
requires:
- linux-checkout-fast
- linux-checkout
- linux-arm64-testing-gn-check:
requires:
- linux-checkout-fast
- linux-checkout
build-mac:
jobs:
- mac-checkout-fast
- mac-checkout-and-save-cache
- mac-checkout
- osx-testing:
requires:
- mac-checkout-fast
- osx-debug:
requires:
- mac-checkout-fast
- mac-checkout
- osx-debug-gn-check:
requires:
- mac-checkout-fast
- mac-checkout
- osx-testing-gn-check:
requires:
- mac-checkout-fast
- mac-checkout
- osx-testing-tests:
requires:
@@ -1770,19 +1658,14 @@ workflows:
- mas-testing:
requires:
- mac-checkout-fast
- mas-debug:
requires:
- mac-checkout-fast
- mac-checkout
- mas-debug-gn-check:
requires:
- mac-checkout-fast
- mac-checkout
- mas-testing-gn-check:
requires:
- mac-checkout-fast
- mac-checkout
- mas-testing-tests:
requires:

1
.github/CODEOWNERS vendored
View File

@@ -11,7 +11,6 @@
# Upgrades WG
/patches/ @electron/wg-upgrades
DEPS @electron/wg-upgrades
# Docs & Tooling WG
/default_app/ @electron/wg-docs-tools

10
.github/main.workflow vendored Normal file
View File

@@ -0,0 +1,10 @@
workflow "Clerk" {
#TODO(codebytere): make this work properly on pull_request
on = "repository_dispatch"
resolves = "Check release notes"
}
action "Check release notes" {
uses = "electron/clerk@master"
secrets = [ "GITHUB_TOKEN" ]
}

25
.github/stale.yml vendored Normal file
View File

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

View File

@@ -300,6 +300,14 @@ source_set("manifests") {
"//printing/buildflags",
"//services/service_manager/public/cpp",
]
if (enable_basic_printing) {
deps += [ "//components/services/pdf_compositor/public/cpp:manifest" ]
}
if (enable_print_preview) {
deps += [ "//chrome/services/printing/public/cpp:manifest" ]
}
}
npm_action("electron_version_args") {
@@ -346,11 +354,8 @@ source_set("electron_lib") {
"//base:base_static",
"//base/allocator:buildflags",
"//chrome/app/resources:platform_locale_settings",
"//chrome/services/printing/public/mojom",
"//components/certificate_transparency",
"//components/net_log",
"//components/network_hints/common",
"//components/network_hints/renderer",
"//components/network_session_configurator/common",
"//components/prefs",
"//components/spellcheck/renderer",
@@ -366,7 +371,7 @@ source_set("electron_lib") {
"//device/bluetooth/public/cpp",
"//gin",
"//media/capture/mojom:video_capture",
"//media/mojo/mojom",
"//media/mojo/interfaces",
"//net:extras",
"//net:net_resources",
"//net:net_with_v8",
@@ -379,7 +384,7 @@ source_set("electron_lib") {
"//services/device/public/mojom",
"//services/proxy_resolver:lib",
"//services/video_capture/public/mojom:constants",
"//services/viz/privileged/mojom/compositing",
"//services/viz/privileged/interfaces/compositing",
"//skia",
"//third_party/blink/public:blink",
"//third_party/boringssl",
@@ -574,16 +579,15 @@ source_set("electron_lib") {
]
deps += [
"//components/viz/service",
"//services/viz/public/mojom",
"//services/viz/public/interfaces",
"//ui/compositor",
]
}
if (enable_desktop_capturer) {
if (is_component_build && !is_linux) {
if (is_component_build && is_win) {
# On windows the implementation relies on unexported
# DxgiDuplicatorController class. On macOS the implementation
# relies on unexported webrtc::GetWindowOwnerPid method.
# DxgiDuplicatorController class.
deps += [ "//third_party/webrtc/modules/desktop_capture" ]
}
sources += [

4
DEPS
View File

@@ -10,9 +10,9 @@ gclient_gn_args = [
vars = {
'chromium_version':
'62327c655093c821aa0fcfc6db53f5fd943e08c7',
'78.0.3866.0',
'node_version':
'v12.9.1',
'v12.6.0',
'nan_version':
'2ee313aaca52e2b478965ac50eb5082520380d1b',

View File

@@ -1 +1 @@
8.0.0-nightly.20190904
7.0.0-beta.2

View File

@@ -60,7 +60,7 @@ build_script:
- ps: $env:SCCACHE_PATH="$pwd\src\electron\external_binaries\sccache.exe"
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
$env:GCLIENT_EXTRA_ARGS="$env:GCLIENT_EXTRA_ARGS --custom-var=checkout_boto=True --custom-var=checkout_requests=True"
$env:GCLIENT_EXTRA_ARGS="--custom-var=checkout_boto=True --custom-var=checkout_requests=True"
} else {
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
}
@@ -89,10 +89,6 @@ build_script:
- appveyor PushArtifact out/Default/dist.zip
- appveyor PushArtifact out/Default/chromedriver.zip
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
- 7z a node_headers.zip out\Default\gen\node_headers
- appveyor PushArtifact node_headers.zip
- appveyor PushArtifact out/Default/mksnapshot.zip
- appveyor PushArtifact out/Default/electron.lib
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
# Needed for msdia140.dll on 64-bit windows
@@ -109,7 +105,7 @@ test_script:
# Workaround for https://github.com/appveyor/ci/issues/2420
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
- ps: >-
if ((-Not (Test-Path Env:\TEST_WOA)) -And (-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
if ((-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
$env:RUN_TESTS="true"
}
- ps: >-
@@ -137,6 +133,4 @@ deploy_script:
Write-Output "Uploading Electron release distribution to github releases"
& python script\release\uploaders\upload.py
}
} elseif (Test-Path Env:\TEST_WOA) {
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
}

View File

@@ -1,84 +0,0 @@
steps:
- task: CopyFiles@2
displayName: 'Copy Files to: src\electron'
inputs:
TargetFolder: src\electron
- script: |
cd src\electron
node script/yarn.js install --frozen-lockfile
displayName: 'Yarn install'
- powershell: |
$localArtifactPath = "$pwd\dist.zip"
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/dist.zip"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\Default -y $localArtifactPath
displayName: 'Download and extract dist.zip for test'
env:
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
- powershell: |
$localArtifactPath = "$pwd\ffmpeg.zip"
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/ffmpeg.zip"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -osrc\out\ffmpeg $localArtifactPath
displayName: 'Download and extract ffmpeg.zip for test'
env:
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
- powershell: |
$localArtifactPath = "$pwd\src\node_headers.zip"
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/node_headers.zip"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
cd src
& "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y node_headers.zip
displayName: 'Download node headers for test'
env:
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
- powershell: |
$localArtifactPath = "$pwd\src\out\Default\electron.lib"
$serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/electron.lib"
Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" }
displayName: 'Download electron.lib for test'
env:
APPVEYOR_TOKEN: $(APPVEYOR_TOKEN)
- powershell: |
New-Item src\out\Default\gen\node_headers\Release -Type directory
Copy-Item -path src\out\Default\electron.lib -destination src\out\Default\gen\node_headers\Release\node.lib
displayName: 'Setup node headers'
- script: |
cd src
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
set npm_config_arch=arm64
cd electron
node script/yarn test -- --ci --enable-logging --verbose
displayName: 'Run Electron tests'
env:
ELECTRON_OUT_DIR: Default
IGNORE_YARN_INSTALL_ERROR: 1
ELECTRON_TEST_RESULTS_DIR: junit
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
MOCHA_REPORTER: mocha-multi-reporters
- task: PublishTestResults@2
displayName: 'Publish Test Results'
inputs:
testResultsFiles: '*.xml'
searchFolder: '$(System.DefaultWorkingDirectory)/src/junit/'
condition: always()
- script: |
cd src
echo "Verifying non proprietary ffmpeg"
python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
displayName: 'Verify ffmpeg'
- script: |
taskkill /F /IM electron.exe
taskkill /F /IM MicrosoftEdge.exe
displayName: 'Kill processes left running from last test run'
condition: always()

View File

@@ -3,7 +3,7 @@ use_jumbo_build = true
root_extra_deps = [ "//electron" ]
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
node_module_version = 76
node_module_version = 75
v8_promise_internal_field_count = 1
v8_typed_array_max_size_in_heap = 0

View File

@@ -42,7 +42,7 @@ module.exports = ({
resolve: {
alias: {
'@electron/internal': path.resolve(electronRoot, 'lib'),
'electron': path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts'),
'electron': path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.js'),
// Force timers to resolve to our dependency that doens't use window.postMessage
'timers': path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
},

View File

@@ -18,7 +18,6 @@ buildflag_header("buildflags") {
"ENABLE_TTS=$enable_tts",
"ENABLE_COLOR_CHOOSER=$enable_color_chooser",
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
"ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
]
}

View File

@@ -18,8 +18,6 @@ declare_args() {
enable_color_chooser = true
enable_picture_in_picture = true
# Provide a fake location provider for mocking
# the geolocation responses. Disable it if you
# need to test with chromium's location provider.

View File

@@ -37,14 +37,6 @@ static_library("chrome") {
"//chrome/browser/net/proxy_config_monitor.h",
"//chrome/browser/net/proxy_service_factory.cc",
"//chrome/browser/net/proxy_service_factory.h",
"//chrome/browser/predictors/preconnect_manager.cc",
"//chrome/browser/predictors/preconnect_manager.h",
"//chrome/browser/predictors/proxy_lookup_client_impl.cc",
"//chrome/browser/predictors/proxy_lookup_client_impl.h",
"//chrome/browser/predictors/resolve_host_client_impl.cc",
"//chrome/browser/predictors/resolve_host_client_impl.h",
"//chrome/browser/printing/printing_service.cc",
"//chrome/browser/printing/printing_service.h",
"//chrome/browser/ssl/security_state_tab_helper.cc",
"//chrome/browser/ssl/security_state_tab_helper.h",
"//chrome/browser/ui/autofill/popup_view_common.cc",
@@ -63,7 +55,6 @@ static_library("chrome") {
"//content/public/browser",
]
deps = [
"//chrome/browser:resource_prefetch_predictor_proto",
"//components/feature_engagement:buildflags",
]
@@ -169,18 +160,16 @@ static_library("chrome") {
"//chrome/browser/printing/printing_message_filter.cc",
"//chrome/browser/printing/printing_message_filter.h",
]
public_deps += [
"//chrome/services/printing:lib",
"//components/printing/browser",
"//components/printing/renderer",
"//components/services/pdf_compositor",
"//components/services/pdf_compositor/public/cpp",
"//components/services/pdf_compositor/public/cpp:factory",
"//components/services/pdf_compositor/public/mojom",
]
deps += [
"//components/printing/common",
"//components/services/pdf_compositor",
"//printing",
]
@@ -193,32 +182,4 @@ static_library("chrome") {
]
}
}
if (enable_picture_in_picture) {
sources += [
"//chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc",
"//chrome/browser/picture_in_picture/picture_in_picture_window_manager.h",
"//chrome/browser/ui/views/overlay/back_to_tab_image_button.cc",
"//chrome/browser/ui/views/overlay/back_to_tab_image_button.h",
"//chrome/browser/ui/views/overlay/close_image_button.cc",
"//chrome/browser/ui/views/overlay/close_image_button.h",
"//chrome/browser/ui/views/overlay/mute_image_button.cc",
"//chrome/browser/ui/views/overlay/mute_image_button.h",
"//chrome/browser/ui/views/overlay/overlay_window_views.cc",
"//chrome/browser/ui/views/overlay/overlay_window_views.h",
"//chrome/browser/ui/views/overlay/playback_image_button.cc",
"//chrome/browser/ui/views/overlay/playback_image_button.h",
"//chrome/browser/ui/views/overlay/resize_handle_button.cc",
"//chrome/browser/ui/views/overlay/resize_handle_button.h",
"//chrome/browser/ui/views/overlay/skip_ad_label_button.cc",
"//chrome/browser/ui/views/overlay/skip_ad_label_button.h",
"//chrome/browser/ui/views/overlay/track_image_button.cc",
"//chrome/browser/ui/views/overlay/track_image_button.h",
]
deps += [
"//chrome/app/vector_icons",
"//components/vector_icons:vector_icons",
]
}
}

View File

@@ -390,7 +390,7 @@ Emitted when Electron has created a new `session`.
```javascript
const { app } = require('electron')
app.on('session-created', (session) => {
app.on('session-created', (event, session) => {
console.log(session)
})
```
@@ -582,7 +582,7 @@ them.
Sets or creates a directory your app's logs which can then be manipulated with `app.getPath()` or `app.setPath(pathName, newPath)`.
Calling `app.setAppLogsPath()` without a `path` parameter will result in this directory being set to `~/Library/Logs/YourAppName` on _macOS_, and inside the `userData` directory on _Linux_ and _Windows_.
Calling `app.setAppLogsPath()` without a `path` parameter will result in this directory being set to `/Library/Logs/YourAppName` on _macOS_, and inside the `userData` directory on _Linux_ and _Windows_.
### `app.getAppPath()`
@@ -614,8 +614,6 @@ Returns `String` - The current application directory.
Returns `String` - A path to a special directory or file associated with `name`. On
failure, an `Error` is thrown.
If `app.getPath('logs')` is called without called `app.setAppLogsPath()` being called first, a default log directory will be created equivalent to calling `app.setAppLogsPath()` without a `path` parameter.
### `app.getFileIcon(path[, options])`
* `path` String
@@ -675,8 +673,6 @@ preferred over `name` by Electron.
Overrides the current application's name.
**Note:** This function overrides the name used internally by Electron; it does not affect the name that the OS uses.
**[Deprecated](modernization/property-updates.md)**
### `app.getLocale()`
@@ -1170,21 +1166,21 @@ This API must be called after the `ready` event is emitted.
**[Deprecated](modernization/property-updates.md)**
### `app.showAboutPanel()`
### `app.showAboutPanel()` _macOS_ _Linux_
Show the app's about panel options. These options can be overridden with `app.setAboutPanelOptions(options)`.
### `app.setAboutPanelOptions(options)`
### `app.setAboutPanelOptions(options)` _macOS_ _Linux_
* `options` Object
* `applicationName` String (optional) - The app's name.
* `applicationVersion` String (optional) - The app's version.
* `copyright` String (optional) - Copyright information.
* `version` String (optional) _macOS_ - The app's build version number.
* `credits` String (optional) _macOS_ _Windows_ - Credit information.
* `credits` String (optional) _macOS_ - 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_ - Path to the app's icon. 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.

View File

@@ -379,9 +379,6 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `disableHtmlFullscreenWindowResize` Boolean (optional) - Whether to
prevent the window from resizing when entering HTML Fullscreen. Default
is `false`.
* `accessibleTitle` String (optional) - An alternative title string provided only
to accessibility tools such as screen readers. This string is not directly
visible to users.
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
@@ -519,14 +516,14 @@ Note that this is only emitted when the window is being resized manually. Resizi
Emitted after the window has been resized.
#### Event: 'will-move' _macOS_ _Windows_
#### Event: 'will-move' _Windows_
Returns:
* `event` Event
* `newBounds` [`Rectangle`](structures/rectangle.md) - Location the window is being moved to.
Emitted before the window is moved. On Windows, calling `event.preventDefault()` will prevent the window from being moved.
Emitted before the window is moved. Calling `event.preventDefault()` will prevent the window from being moved.
Note that this is only emitted when the window is being resized manually. Resizing the window with `setBounds`/`setSize` will not emit this event.
@@ -824,12 +821,6 @@ const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
```
#### `win.accessibleTitle`
A `String` property that defines an alternative title provided only to
accessibility tools such as screen readers. This string is not directly
visible to users.
### Instance Methods
Objects created with `new BrowserWindow` have the following instance methods:
@@ -1203,14 +1194,6 @@ can not be focused on.
Returns `Boolean` - Whether the window is always on top of other windows.
#### `win.moveAbove(mediaSourceId)`
* `mediaSourceId` String - Window id in the format of DesktopCapturerSource's id. For example "window:1869:0".
Moves window above the source window in the sense of z-order. If the
`mediaSourceId` is not of type window or if the window does not exist then
this method throws an error.
#### `win.moveTop()`
Moves window to top(z-order) regardless of focus
@@ -1283,15 +1266,6 @@ Enters or leaves the kiosk mode.
Returns `Boolean` - Whether the window is in kiosk mode.
#### `win.getMediaSourceId()`
Returns `String` - Window id in the format of DesktopCapturerSource's id. For example "window:1234:0".
More precisely the format is `window:id:other_id` where `id` is `HWND` on
Windows, `CGWindowID` (`uint64_t`) on macOS and `Window` (`unsigned long`) on
Linux. `other_id` is used to identify web contents (tabs) so within the same
top level window.
#### `win.getNativeWindowHandle()`
Returns `Buffer` - The platform-specific handle of the window.
@@ -1463,27 +1437,29 @@ screen readers
Sets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to
convey some sort of application status or to passively notify the user.
#### `win.setHasShadow(hasShadow)`
#### `win.setHasShadow(hasShadow)` _macOS_
* `hasShadow` Boolean
Sets whether the window should have a shadow.
Sets whether the window should have a shadow. On Windows and Linux does
nothing.
#### `win.hasShadow()`
#### `win.hasShadow()` _macOS_
Returns `Boolean` - Whether the window has a shadow.
On Windows and Linux always returns
`true`.
#### `win.setOpacity(opacity)` _Windows_ _macOS_
* `opacity` Number - between 0.0 (fully transparent) and 1.0 (fully opaque)
Sets the opacity of the window. On Linux, does nothing. Out of bound number
values are clamped to the [0, 1] range.
Sets the opacity of the window. On Linux does nothing.
#### `win.getOpacity()`
#### `win.getOpacity()` _Windows_ _macOS_
Returns `Number` - between 0.0 (fully transparent) and 1.0 (fully opaque). On
Linux, always returns 1.
Returns `Number` - between 0.0 (fully transparent) and 1.0 (fully opaque)
#### `win.setShape(rects)` _Windows_ _Linux_ _Experimental_

View File

@@ -48,13 +48,10 @@ The `dialog` module has the following methods:
their target path.
* `treatPackageAsDirectory` _macOS_ - Treat packages, such as `.app` folders,
as a directory instead of a file.
* `dontAddToRecent` _Windows_ - Do not add the item being opened to the recent documents list.
* `message` String (optional) _macOS_ - Message to display above input
boxes.
* `securityScopedBookmarks` Boolean (optional) _macOS_ _mas_ - Create [security scoped bookmarks](https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16) when packaged for the Mac App Store.
Returns `String[] | undefined`, the file paths chosen by the user; if the dialog is cancelled it returns `undefined`.
The `browserWindow` argument allows the dialog to attach itself to a parent window, making it modal.
The `filters` specifies an array of file types that can be displayed or
@@ -111,7 +108,6 @@ dialog.showOpenDialogSync(mainWindow, {
their target path.
* `treatPackageAsDirectory` _macOS_ - Treat packages, such as `.app` folders,
as a directory instead of a file.
* `dontAddToRecent` _Windows_ - Do not add the item being opened to the recent documents list.
* `message` String (optional) _macOS_ - Message to display above input
boxes.
* `securityScopedBookmarks` Boolean (optional) _macOS_ _mas_ - Create [security scoped bookmarks](https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16) when packaged for the Mac App Store.
@@ -173,13 +169,6 @@ dialog.showOpenDialog(mainWindow, {
displayed in front of the filename text field.
* `showsTagField` Boolean (optional) _macOS_ - Show the tags input box,
defaults to `true`.
* `properties` String[] (optional)
* `showHiddenFiles` - Show hidden files in dialog.
* `createDirectory` _macOS_ - Allow creating new directories from dialog.
* `treatPackageAsDirectory` _macOS_ - Treat packages, such as `.app` folders,
as a directory instead of a file.
* `showOverwriteConfirmation` _Linux_ - Sets whether the user will be presented a confirmation dialog if the user types a file name that already exists.
* `dontAddToRecent` _Windows_ - Do not add the item being saved to the recent documents list.
* `securityScopedBookmarks` Boolean (optional) _macOS_ _mas_ - Create a [security scoped bookmark](https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16) when packaged for the Mac App Store. If this option is enabled and the file doesn't already exist a blank file will be created at the chosen path.
Returns `String | undefined`, the path of the file chosen by the user; if the dialog is cancelled it returns `undefined`.
@@ -202,14 +191,8 @@ The `filters` specifies an array of file types that can be displayed, see
* `message` String (optional) _macOS_ - Message to display above text fields.
* `nameFieldLabel` String (optional) _macOS_ - Custom label for the text
displayed in front of the filename text field.
* `showsTagField` Boolean (optional) _macOS_ - Show the tags input box, defaults to `true`.
* `properties` String[] (optional)
* `showHiddenFiles` - Show hidden files in dialog.
* `createDirectory` _macOS_ - Allow creating new directories from dialog.
* `treatPackageAsDirectory` _macOS_ - Treat packages, such as `.app` folders,
as a directory instead of a file.
* `showOverwriteConfirmation` _Linux_ - Sets whether the user will be presented a confirmation dialog if the user types a file name that already exists.
* `dontAddToRecent` _Windows_ - Do not add the item being saved to the recent documents list.
* `showsTagField` Boolean (optional) _macOS_ - Show the tags input box,
defaults to `true`.
* `securityScopedBookmarks` Boolean (optional) _macOS_ _mas_ - Create a [security scoped bookmark](https://developer.apple.com/library/content/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW16) when packaged for the Mac App Store. If this option is enabled and the file doesn't already exist a blank file will be created at the chosen path.
Returns `Promise<Object>` - Resolve with an object containing the following:
@@ -244,7 +227,7 @@ expanding and collapsing the dialog.
include a checkbox with the given label.
* `checkboxChecked` Boolean (optional) - Initial checked state of the
checkbox. `false` by default.
* `icon` ([NativeImage](native-image.md) | String) (optional)
* `icon` [NativeImage](native-image.md) (optional)
* `cancelId` Integer (optional) - The index of the button to be used to cancel the dialog, via
the `Esc` key. By default this is assigned to the first button with "cancel" or "no" as the
label. If no such labeled buttons exist and this option is not set, `0` will be used as the

View File

@@ -18,8 +18,6 @@ app.dock.bounce()
* `type` String (optional) - Can be `critical` or `informational`. The default is
`informational`
Returns `Integer` - an ID representing the request.
When `critical` is passed, the dock icon will bounce until either the
application becomes active or the request is canceled.
@@ -27,7 +25,7 @@ When `informational` is passed, the dock icon will bounce for one second.
However, the request remains active until either the application becomes active
or the request is canceled.
**Nota Bene:** This method can only be used while the app is not focused; when the app is focused it will return -1.
Returns `Integer` an ID representing the request.
#### `dock.cancelBounce(id)` _macOS_

View File

@@ -147,4 +147,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

View File

@@ -2,7 +2,7 @@
The Electron team is currently undergoing an initiative to convert callback-based functions in Electron to return Promises. During this transition period, both the callback and Promise-based versions of these functions will work correctly, and will both be documented.
To enable deprecation warnings for these updated functions, use the [`process.enablePromiseAPIs` runtime flag](../process.md#processenablepromiseapis).
To enable deprecation warnings for these updated functions, use the `process.enablePromiseAPI` runtime flag.
When a majority of affected functions are migrated, this flag will be enabled by default and all developers will be able to see these deprecation warnings. At that time, the callback-based versions will also be removed from documentation. This document will be continuously updated as more functions are converted.

View File

@@ -14,11 +14,11 @@ image file path as a `String`:
const { BrowserWindow, Tray } = require('electron')
const appIcon = new Tray('/Users/somebody/images/icon.png')
const win = new BrowserWindow({ icon: '/Users/somebody/images/window.png' })
let win = new BrowserWindow({ icon: '/Users/somebody/images/window.png' })
console.log(appIcon, win)
```
Or read the image from the clipboard, which returns a `NativeImage`:
Or read the image from the clipboard which returns a `NativeImage`:
```javascript
const { clipboard, Tray } = require('electron')
@@ -33,19 +33,19 @@ Currently `PNG` and `JPEG` image formats are supported. `PNG` is recommended
because of its support for transparency and lossless compression.
On Windows, you can also load `ICO` icons from file paths. For best visual
quality, it is recommended to include at least the following sizes in the:
quality it is recommended to include at least the following sizes in the:
* Small icon
* 16x16 (100% DPI scale)
* 20x20 (125% DPI scale)
* 24x24 (150% DPI scale)
* 32x32 (200% DPI scale)
* 16x16 (100% DPI scale)
* 20x20 (125% DPI scale)
* 24x24 (150% DPI scale)
* 32x32 (200% DPI scale)
* Large icon
* 32x32 (100% DPI scale)
* 40x40 (125% DPI scale)
* 48x48 (150% DPI scale)
* 64x64 (200% DPI scale)
* 256x256
* 32x32 (100% DPI scale)
* 40x40 (125% DPI scale)
* 48x48 (150% DPI scale)
* 64x64 (200% DPI scale)
* 256x256
Check the *Size requirements* section in [this article][icons].
@@ -56,7 +56,7 @@ Check the *Size requirements* section in [this article][icons].
On platforms that have high-DPI support such as Apple Retina displays, you can
append `@2x` after image's base filename to mark it as a high resolution image.
For example, if `icon.png` is a normal image that has standard resolution, then
For example if `icon.png` is a normal image that has standard resolution, then
`icon@2x.png` will be treated as a high resolution image that has double DPI
density.
@@ -73,11 +73,11 @@ images/
```javascript
const { Tray } = require('electron')
const appIcon = new Tray('/Users/somebody/images/icon.png')
let appIcon = new Tray('/Users/somebody/images/icon.png')
console.log(appIcon)
```
The following suffixes for DPI are also supported:
Following suffixes for DPI are also supported:
* `@1x`
* `@1.25x`
@@ -97,7 +97,7 @@ Template images consist of black and an alpha channel.
Template images are not intended to be used as standalone images and are usually
mixed with other content to create the desired final appearance.
The most common case is to use template images for a menu bar icon, so it can
The most common case is to use template images for a menu bar icon so it can
adapt to both light and dark menu bars.
**Note:** Template image is only supported on macOS.
@@ -132,7 +132,7 @@ a valid image.
```javascript
const nativeImage = require('electron').nativeImage
const image = nativeImage.createFromPath('/Users/somebody/images/icon.png')
let image = nativeImage.createFromPath('/Users/somebody/images/icon.png')
console.log(image)
```
@@ -180,8 +180,7 @@ Creates a new `NativeImage` instance from the NSImage that maps to the
given image name. See [`System Icons`](https://developer.apple.com/design/human-interface-guidelines/macos/icons-and-images/system-icons/)
for a list of possible values.
The `hslShift` is applied to the image with the following rules:
The `hslShift` is applied to the image with the following rules
* `hsl_shift[0]` (hue): The absolute hue value for the image - 0 and 1 map
to 0 and 360 on the hue color wheel (red).
* `hsl_shift[1]` (saturation): A saturation shift for the image, with the
@@ -249,9 +248,9 @@ Returns `String` - The data URL of the image.
Returns `Buffer` - A [Buffer][buffer] that contains the image's raw bitmap pixel data.
The difference between `getBitmap()` and `toBitmap()` is that `getBitmap()` does not
The difference between `getBitmap()` and `toBitmap()` is, `getBitmap()` does not
copy the bitmap data, so you have to use the returned Buffer immediately in
current event loop tick; otherwise the data might be changed or destroyed.
current event loop tick, otherwise the data might be changed or destroyed.
#### `image.getNativeHandle()` _macOS_
@@ -296,7 +295,7 @@ Returns `NativeImage` - The cropped image.
* `width` Integer (optional) - Defaults to the image's width.
* `height` Integer (optional) - Defaults to the image's height.
* `quality` String (optional) - The desired quality of the resize image.
Possible values are `good`, `better`, or `best`. The default is `best`.
Possible values are `good`, `better` or `best`. The default is `best`.
These values express a desired quality/speed tradeoff. They are translated
into an algorithm-specific method that depends on the capabilities
(CPU, GPU) of the underlying platform. It is possible for all three methods

View File

@@ -1,35 +0,0 @@
# nativeTheme
> Read and respond to changes in Chromium's native color theme.
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)
## Events
The `nativeTheme` module emits the following events:
### Event: 'updated'
Emitted when something in the underlying NativeTheme has changed. This normally
means that either the value of `shouldUseDarkColors`,
`shouldUseHighContrastColors` or `shouldUseInvertedColorScheme` has changed.
You will have to check them to determine which one has changed.
## Properties
The `nativeTheme` module has the following properties:
### `nativeTheme.shouldUseDarkColors` _Readonly_
A `Boolean` for if the OS / Chromium currently has a dark mode enabled or is
being instructed to show a dark-style UI.
### `nativeTheme.shouldUseHighContrastColors` _macOS_ _Windows_ _Readonly_
A `Boolean` for if the OS / Chromium currently has high-contrast mode enabled
or is being instructed to show a high-constrast UI.
### `nativeTheme.shouldUseInvertedColorScheme` _macOS_ _Windows_ _Readonly_
A `Boolean` for if the OS / Chromium currently has an inverted color scheme
or is being instructed to use an inverted color scheme.

View File

@@ -14,7 +14,7 @@ property, so writing `let { screen } = require('electron')` will not work.
An example of creating a window that fills the whole screen:
```javascript fiddle='docs/fiddles/screen/fit-screen'
```javascript
const { app, BrowserWindow, screen } = require('electron')
let win

View File

@@ -91,20 +91,6 @@ session.defaultSession.on('will-download', (event, item, webContents) => {
})
```
#### Event: 'preconnect'
Returns:
* `event` Event
* `preconnectUrl` String - The URL being requested for preconnection by the
renderer.
* `allowCredentials` Boolean - True if the renderer is requesting that the
connection include credentials (see the
[spec](https://w3c.github.io/resource-hints/#preconnect) for more details.)
Emitted when a render process requests preconnection to a URL, generally due to
a [resource hint](https://w3c.github.io/resource-hints/).
### Instance Methods
The following methods are available on instances of `Session`:
@@ -139,9 +125,9 @@ Writes any unwritten DOMStorage data to disk.
#### `ses.setProxy(config)`
* `config` Object
* `pacScript` String (optional) - The URL associated with the PAC file.
* `proxyRules` String (optional) - Rules indicating which proxies to use.
* `proxyBypassRules` String (optional) - Rules indicating which URLs should
* `pacScript` String - The URL associated with the PAC file.
* `proxyRules` String - Rules indicating which proxies to use.
* `proxyBypassRules` String - Rules indicating which URLs should
bypass the proxy settings.
Returns `Promise<void>` - Resolves when the proxy setting process is complete.
@@ -252,14 +238,6 @@ window.webContents.session.enableNetworkEmulation({
window.webContents.session.enableNetworkEmulation({ offline: true })
```
#### `ses.preconnect(options)`
* `options` Object
* `url` String - URL for preconnect. Only the origin is relevant for opening the socket.
* `numSockets` Number (optional) - number of sockets to preconnect. Must be between 1 and 6. Defaults to 1.
Preconnects the given number of sockets to an origin.
#### `ses.disableNetworkEmulation()`
Disables any network emulation already active for the `session`. Resets to
@@ -267,7 +245,7 @@ the original network configuration.
#### `ses.setCertificateVerifyProc(proc)`
* `proc` Function | null
* `proc` Function
* `request` Object
* `hostname` String
* `certificate` [Certificate](structures/certificate.md)
@@ -408,17 +386,6 @@ Returns `String` - The user agent for this session.
Returns `Promise<Buffer>` - resolves with blob data.
#### `ses.downloadURL(url)`
* `url` String
Initiates a download of the resource at `url`.
The API will generate a [DownloadItem](download-item.md) that can be accessed
with the [will-download](#event-will-download) event.
**Note:** This does not perform any security checks that relate to a page's origin,
unlike [`webContents.downloadURL`](web-contents.md#contentsdownloadurlurl).
#### `ses.createInterruptedDownload(options)`
* `options` Object
@@ -427,8 +394,8 @@ unlike [`webContents.downloadURL`](web-contents.md#contentsdownloadurlurl).
* `mimeType` String (optional)
* `offset` Integer - Start range for the download.
* `length` Integer - Total length of the download.
* `lastModified` String (optional) - Last-Modified header value.
* `eTag` String (optional) - ETag header value.
* `lastModified` String - Last-Modified header value.
* `eTag` String - ETag header value.
* `startTime` Double (optional) - Time when download was started in
number of seconds since UNIX epoch.

View File

@@ -43,12 +43,11 @@ Returns `Promise<void>`
Open the given external protocol URL in the desktop's default manner. (For example, mailto: URLs in the user's default mail agent).
### `shell.moveItemToTrash(fullPath[, deleteOnFail])`
### `shell.moveItemToTrash(fullPath)`
* `fullPath` String
* `deleteOnFail` Boolean (optional) - Whether or not to unilaterally remove the item if the Trash is disabled or unsupported on the volume. _macOS_
Returns `Boolean` - Whether the item was successfully moved to the trash or otherwise deleted.
Returns `Boolean` - Whether the item was successfully moved to the trash.
Move the given file to trash and returns a boolean status for the operation.

View File

@@ -1,6 +1,6 @@
# InputEvent Object
* `modifiers` String[] (optional) - An array of modifiers of the event, can
be `shift`, `control`, `ctrl`, `alt`, `meta`, `command`, `cmd`, `isKeypad`,
`isAutoRepeat`, `leftButtonDown`, `middleButtonDown`, `rightButtonDown`,
`capsLock`, `numLock`, `left`, `right`.
* `modifiers` String[] - An array of modifiers of the event, can
be `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`,
`leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`,
`numLock`, `left`, `right`.

View File

@@ -27,34 +27,28 @@ Returns:
* `event` Event
### Event: 'inverted-color-scheme-changed' _Windows_ _Deprecated_
### Event: 'inverted-color-scheme-changed' _Windows_
Returns:
* `event` Event
* `invertedColorScheme` Boolean - `true` if an inverted color scheme (a high contrast color scheme with light text and dark backgrounds) is being used, `false` otherwise.
**Deprecated:** Should use the new [`updated`](native-theme.md#event-updated) event on the `nativeTheme` module.
### Event: 'high-contrast-color-scheme-changed' _Windows_ _Deprecated_
### Event: 'high-contrast-color-scheme-changed' _Windows_
Returns:
* `event` Event
* `highContrastColorScheme` Boolean - `true` if a high contrast theme is being used, `false` otherwise.
**Deprecated:** Should use the new [`updated`](native-theme.md#event-updated) event on the `nativeTheme` module.
## Methods
### `systemPreferences.isDarkMode()` _macOS_ _Windows_ _Deprecated_
### `systemPreferences.isDarkMode()` _macOS_ _Windows_
Returns `Boolean` - Whether the system is in Dark Mode.
**Note:** On macOS 10.15 Catalina in order for this API to return the correct value when in the "automatic" dark mode setting you must either have `NSRequiresAquaSystemAppearance=false` in your `Info.plist` or be on Electron `>=7.0.0`. See the [dark mode guide](../tutorial/mojave-dark-mode-guide.md) for more information.
**Deprecated:** Should use the new [`nativeTheme.shouldUseDarkColors`](native-theme.md#nativethemeshouldusedarkcolors-readonly) API.
### `systemPreferences.isSwipeTrackingFromScrollEventsEnabled()` _macOS_
Returns `Boolean` - Whether the Swipe between pages setting is on.
@@ -348,18 +342,14 @@ Returns `String` - The standard system color formatted as `#RRGGBBAA`.
Returns one of several standard system colors that automatically adapt to vibrancy and changes in accessibility settings like 'Increase contrast' and 'Reduce transparency'. See [Apple Documentation](https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/color#system-colors) for more details.
### `systemPreferences.isInvertedColorScheme()` _Windows_ _Deprecated_
### `systemPreferences.isInvertedColorScheme()` _Windows_
Returns `Boolean` - `true` if an inverted color scheme (a high contrast color scheme with light text and dark backgrounds) is active, `false` otherwise.
**Deprecated:** Should use the new [`nativeTheme.shouldUseInvertedColorScheme`](native-theme.md#nativethemeshoulduseinvertedcolorscheme-macos-windows-readonly) API.
### `systemPreferences.isHighContrastColorScheme()` _macOS_ _Windows_ _Deprecated_
### `systemPreferences.isHighContrastColorScheme()` _macOS_ _Windows_
Returns `Boolean` - `true` if a high contrast theme is active, `false` otherwise.
**Depreacted:** Should use the new [`nativeTheme.shouldUseHighContrastColors`](native-theme.md#nativethemeshouldusehighcontrastcolors-macos-windows-readonly) API.
### `systemPreferences.getEffectiveAppearance()` _macOS_
Returns `String` - Can be `dark`, `light` or `unknown`.
@@ -375,9 +365,7 @@ using `electron-packager` or `electron-forge` just set the `enableDarwinDarkMode
packager option to `true`. See the [Electron Packager API](https://github.com/electron/electron-packager/blob/master/docs/api.md#darwindarkmodesupport)
for more details.
**[Deprecated](modernization/property-updates.md)**
### `systemPreferences.getAppLevelAppearance()` _macOS_ _Deprecated_
### `systemPreferences.getAppLevelAppearance()` _macOS_
Returns `String` | `null` - Can be `dark`, `light` or `unknown`.
@@ -387,7 +375,7 @@ You can use the `setAppLevelAppearance` API to set this value.
**[Deprecated](modernization/property-updates.md)**
### `systemPreferences.setAppLevelAppearance(appearance)` _macOS_ _Deprecated_
### `systemPreferences.setAppLevelAppearance(appearance)` _macOS_
* `appearance` String | null - Can be `dark` or `light`
@@ -462,25 +450,10 @@ Returns an object with system animation settings.
### `systemPreferences.appLevelAppearance` _macOS_
A `String` property that can be `dark`, `light` or `unknown`. It determines the macOS appearance setting for
A `String` property that determines the macOS appearance setting for
your application. This maps to values in: [NSApplication.appearance](https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc). Setting this will override the
system default as well as the value of `getEffectiveAppearance`.
Possible values that can be set are `dark` and `light`, and possible return values are `dark`, `light`, and `unknown`.
This property is only available on macOS 10.14 Mojave or newer.
### `systemPreferences.effectiveAppearance` _macOS_ _Readonly_
A `String` property that can be `dark`, `light` or `unknown`.
Returns the macOS appearance setting that is currently applied to your application,
maps to [NSApplication.effectiveAppearance](https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc)
Please note that until Electron is built targeting the 10.14 SDK, your application's
`effectiveAppearance` will default to 'light' and won't inherit the OS preference. In
the interim in order for your application to inherit the OS preference you must set the
`NSRequiresAquaSystemAppearance` key in your apps `Info.plist` to `false`. If you are
using `electron-packager` or `electron-forge` just set the `enableDarwinDarkMode`
packager option to `true`. See the [Electron Packager API](https://github.com/electron/electron-packager/blob/master/docs/api.md#darwindarkmodesupport)
for more details.

View File

@@ -11,7 +11,7 @@ Process: [Main](../tutorial/application-architecture.md#main-and-renderer-proces
* `backgroundColor` String (optional) - Button background color in hex format,
i.e `#ABCDEF`.
* `icon` [NativeImage](native-image.md) | String (optional) - Button icon.
* `iconPosition` String (optional) - Can be `left`, `right` or `overlay`. Defaults to `overlay`.
* `iconPosition` String (optional) - Can be `left`, `right` or `overlay`.
* `click` Function (optional) - Function to call when the button is clicked.
### Instance Properties

View File

@@ -9,7 +9,7 @@ Process: [Main](../tutorial/application-architecture.md#main-and-renderer-proces
* `options` Object
* `label` String (optional) - Popover button text.
* `icon` [NativeImage](native-image.md) (optional) - Popover button icon.
* `items` [TouchBar](touch-bar.md) - Items to display in the popover.
* `items` [TouchBar](touch-bar.md) (optional) - Items to display in the popover.
* `showCloseButton` Boolean (optional) - `true` to display a close button
on the left of the popover, `false` to not show it. Default is `true`.

View File

@@ -12,10 +12,10 @@ Process: [Main](../tutorial/application-architecture.md#main-and-renderer-proces
* `selectedIndex` Integer - The index of the item the user selected.
* `highlight` Function (optional) - Called when the user taps any item.
* `highlightedIndex` Integer - The index of the item the user touched.
* `selectedStyle` String (optional) - Selected item style. Can be `background`, `outline` or `none`. Defaults to `none`.
* `overlayStyle` String (optional) - Selected overlay item style. Can be `background`, `outline` or `none`. Defaults to `none`.
* `selectedStyle` String (optional) - Selected item style. Defaults to `null`.
* `overlayStyle` String (optional) - Selected overlay item style. Defaults to `null`.
* `showArrowButtons` Boolean (optional) - Defaults to `false`.
* `mode` String (optional) - Can be `fixed` or `free`. The default is `free`.
* `mode` String (optional) - Defaults to `free`.
* `continuous` Boolean (optional) - Defaults to `true`.
### Instance Properties
@@ -34,7 +34,7 @@ updates the control in the touch bar. Possible values:
* `background` - Maps to `[NSScrubberSelectionStyle roundedBackgroundStyle]`.
* `outline` - Maps to `[NSScrubberSelectionStyle outlineOverlayStyle]`.
* `none` - Removes all styles.
* `null` - Actually null, not a string, removes all styles.
#### `touchBarScrubber.overlayStyle`
@@ -44,7 +44,7 @@ touch bar. Possible values:
* `background` - Maps to `[NSScrubberSelectionStyle roundedBackgroundStyle]`.
* `outline` - Maps to `[NSScrubberSelectionStyle outlineOverlayStyle]`.
* `none` - Removes all styles.
* `null` - Actually null, not a string, removes all styles.
#### `touchBarScrubber.showArrowButtons`

View File

@@ -10,23 +10,23 @@ Process: [Main](../tutorial/application-architecture.md#main-and-renderer-proces
* `segmentStyle` String (optional) - Style of the segments:
* `automatic` - Default. The appearance of the segmented control is
automatically determined based on the type of window in which the control
is displayed and the position within the window. Maps to `NSSegmentStyleAutomatic`.
* `rounded` - The control is displayed using the rounded style. Maps to `NSSegmentStyleRounded`.
is displayed and the position within the window.
* `rounded` - The control is displayed using the rounded style.
* `textured-rounded` - The control is displayed using the textured rounded
style. Maps to `NSSegmentStyleTexturedRounded`.
* `round-rect` - The control is displayed using the round rect style. Maps to `NSSegmentStyleRoundRect`.
style.
* `round-rect` - The control is displayed using the round rect style.
* `textured-square` - The control is displayed using the textured square
style. Maps to `NSSegmentStyleTexturedSquare`.
* `capsule` - The control is displayed using the capsule style. Maps to `NSSegmentStyleCapsule`.
* `small-square` - The control is displayed using the small square style. Maps to `NSSegmentStyleSmallSquare`.
style.
* `capsule` - The control is displayed using the capsule style.
* `small-square` - The control is displayed using the small square style.
* `separated` - The segments in the control are displayed very close to each
other but not touching. Maps to `NSSegmentStyleSeparated`.
other but not touching.
* `mode` String (optional) - The selection mode of the control:
* `single` - Default. One item selected at a time, selecting one deselects the previously selected item. Maps to `NSSegmentSwitchTrackingSelectOne`.
* `multiple` - Multiple items can be selected at a time. Maps to `NSSegmentSwitchTrackingSelectAny`.
* `buttons` - Make the segments act as buttons, each segment can be pressed and released but never marked as active. Maps to `NSSegmentSwitchTrackingMomentary`.
* `single` - Default. One item selected at a time, selecting one deselects the previously selected item.
* `multiple` - Multiple items can be selected at a time.
* `buttons` - Make the segments act as buttons, each segment can be pressed and released but never marked as active.
* `segments` [SegmentedControlSegment[]](structures/segmented-control-segment.md) - An array of segments to place in this control.
* `selectedIndex` Integer (optional) - The index of the currently selected segment, will update automatically with user interaction. When the mode is `multiple` it will be the last selected item.
* `selectedIndex` Integer (optional) - The index of the currently selected segment, will update automatically with user interaction. When the mode is multiple it will be the last selected item.
* `change` Function (optional) - Called when the user selects a new segment.
* `selectedIndex` Integer - The index of the segment the user selected.
* `isSelected` Boolean - Whether as a result of user selection the segment is selected or not.

View File

@@ -8,6 +8,6 @@ Process: [Main](../tutorial/application-architecture.md#main-and-renderer-proces
* `options` Object
* `size` String (optional) - Size of spacer, possible values are:
* `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`.
* `small` - Small space between items.
* `large` - Large space between items.
* `flexible` - Take up all available space.

View File

@@ -222,31 +222,12 @@ Returns `Boolean` - Whether double click events will be ignored.
#### `tray.displayBalloon(options)` _Windows_
* `options` Object
* `icon` ([NativeImage](native-image.md) | String) (optional) - Icon to use when `iconType` is `custom`.
* `iconType` String (optional) - Can be `none`, `info`, `warning`, `error` or `custom`. Default is `custom`.
* `icon` ([NativeImage](native-image.md) | String) (optional) -
* `title` String
* `content` String
* `largeIcon` Boolean (optional) - The large version of the icon should be used. Default is `true`. Maps to [`NIIF_LARGE_ICON`][NIIF_LARGE_ICON].
* `noSound` Boolean (optional) - Do not play the associated sound. Default is `false`. Maps to [`NIIF_NOSOUND`][NIIF_NOSOUND].
* `respectQuietTime` Boolean (optional) - Do not display the balloon notification if the current user is in "quiet time". Default is `false`. Maps to [`NIIF_RESPECT_QUIET_TIME`][NIIF_RESPECT_QUIET_TIME].
Displays a tray balloon.
[NIIF_NOSOUND]: https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataa#niif_nosound-0x00000010
[NIIF_LARGE_ICON]: https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataa#niif_large_icon-0x00000020
[NIIF_RESPECT_QUIET_TIME]: https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataa#niif_respect_quiet_time-0x00000080
#### `tray.removeBalloon()` _Windows_
Removes a tray balloon.
#### `tray.focus()` _Windows_
Returns focus to the taskbar notification area.
Notification area icons should use this message when they have completed their UI operation.
For example, if the icon displays a shortcut menu, but the user presses ESC to cancel it,
use `tray.focus()` to return focus to the notification area.
#### `tray.popUpContextMenu([menu, position])` _macOS_ _Windows_
* `menu` Menu (optional)

View File

@@ -1264,14 +1264,16 @@ Returns [`PrinterInfo[]`](structures/printer-info.md).
* `dpi` Object (optional)
* `horizontal` Number (optional) - The horizontal dpi.
* `vertical` Number (optional) - The vertical dpi.
* `header` String (optional) - String to be printed as page header.
* `footer` String (optional) - String to be printed as page footer.
* `callback` Function (optional)
* `success` Boolean - Indicates success of the print call.
* `failureReason` String - Called back if the print fails; can be `cancelled` or `failed`.
Prints window's web page. When `silent` is set to `true`, Electron will pick
the system's default printer if `deviceName` is empty and the default settings for printing.
the system's default printer if `deviceName` is empty and the default settings
for printing.
Calling `window.print()` in web page is equivalent to calling
`webContents.print({ silent: false, printBackground: false, deviceName: '' })`.
Use `page-break-before: always;` CSS style to force to print to a new page.
@@ -1593,8 +1595,8 @@ End subscribing for frame presentation events.
* `item` Object
* `file` String[] | String - The path(s) to the file(s) being dragged.
* `icon` [NativeImage](native-image.md) | String - The image must be
non-empty on macOS.
* `icon` [NativeImage](native-image.md) - The image must be non-empty on
macOS.
Sets the `item` as dragging item for current drag-drop operation, `file` is the
absolute path of the file to be dragged, and `icon` is the image showing under

View File

@@ -99,16 +99,16 @@ Some examples of valid `urls`:
* `timestamp` Double
* `requestHeaders` Record<string, string>
* `callback` Function
* `beforeSendResponse` Object
* `response` Object
* `cancel` Boolean (optional)
* `requestHeaders` Record<string, string | string[]> (optional) - When provided, request will be made
* `requestHeaders` Record<string, string> (optional) - When provided, request will be made
with these headers.
The `listener` will be called with `listener(details, callback)` before sending
an HTTP request, once the request headers are available. This may occur after a
TCP connection is made to the server, but before any http data is sent.
The `callback` has to be called with a `response` object.
The `callback` has to be called with an `response` object.
#### `webRequest.onSendHeaders([filter, ]listener)`
@@ -148,9 +148,9 @@ response are visible by the time this listener is fired.
* `statusCode` Integer
* `responseHeaders` Record<string, string> (optional)
* `callback` Function
* `headersReceivedResponse` Object
* `response` Object
* `cancel` Boolean (optional)
* `responseHeaders` Record<string, string | string[]> (optional) - When provided, the server is assumed
* `responseHeaders` Record<string, string> (optional) - When provided, the server is assumed
to have responded with these headers.
* `statusLine` String (optional) - Should be provided when overriding
`responseHeaders` to change header status otherwise original response
@@ -159,7 +159,7 @@ response are visible by the time this listener is fired.
The `listener` will be called with `listener(details, callback)` when HTTP
response headers of a request have been received.
The `callback` has to be called with a `response` object.
The `callback` has to be called with an `response` object.
#### `webRequest.onResponseStarted([filter, ]listener)`
@@ -201,7 +201,6 @@ and response headers are available.
* `timestamp` Double
* `redirectURL` String
* `statusCode` Integer
* `statusLine` String
* `ip` String (optional) - The server IP address that the request was
actually sent to.
* `fromCache` Boolean

View File

@@ -113,10 +113,3 @@ This can happen during build, when Debugging Tools for Windows has been installe
### ImportError: No module named win32file
Make sure you have installed `pywin32` with `pip install pywin32`.
### Build Scripts Hang Until Keypress
This bug is a "feature" of Windows' command prompt. It happens when clicking inside the prompt window with
`QuickEdit` enabled and is intended to allow selecting and copying output text easily.
Since each accidental click will pause the build process, you might want to disable this
feature in the command prompt properties.

View File

@@ -48,12 +48,3 @@ would run `npm run test -- -g ipc`.
1. Push the Windows key and search for _Manage optional features_.
1. Click _Add a feature_.
1. Select _Japanese Supplemental Fonts_ and click _Install_.
Some tests which rely on precise pixel measurements may not work correctly on
devices with Hi-DPI screen settings due to floating point precision errors.
To run these tests correctly, make sure the device is set to 100% scaling.
To configure display scaling:
1. Push the Windows key and search for _Display settings_.
1. Under _Scale and layout_, make sure that the device is set to 100%.

View File

@@ -1,20 +0,0 @@
// Retrieve information about screen size, displays, cursor position, etc.
//
// For more info, see:
// https://electronjs.org/docs/api/screen
const { app, BrowserWindow } = require('electron')
let mainWindow = null
app.on('ready', () => {
// We cannot require the screen module until the app is ready.
const { screen } = require('electron')
// Create a window that fills the screen's available work area.
const primaryDisplay = screen.getPrimaryDisplay()
const { width, height } = primaryDisplay.workAreaSize
mainWindow = new BrowserWindow({ width, height })
mainWindow.loadURL('https://electronjs.org')
})

View File

@@ -31,7 +31,8 @@ unifies the existing (and well maintained) build tools for Electron development
into a cohesive package so that anyone can jump right in to Electron
development.
Forge comes with [a ready-to-use template](https://electronforge.io/templates) using Webpack as a bundler. It includes an example typescript configuration and provides two configuration files to enable easy customization. It uses the same core modules used by the
Forge comes with [ready-to-use templates](https://electronforge.io/templates) for popular
frameworks like React, Vue, or Angular. It uses the same core modules used by the
greater Electron community (like [`electron-packager`](https://github.com/electron/electron-packager))  
changes made by Electron maintainers (like Slack) benefit Forge's users, too.

View File

@@ -195,8 +195,6 @@ Finally the `index.html` is the web page you want to show:
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<!-- https://electronjs.org/docs/tutorial/security#csp-meta-tag -->
<meta http-equiv="Content-Security-Policy" content="script-src 'self';" />
</head>
<body>
<h1>Hello World!</h1>

View File

@@ -27,8 +27,18 @@ see [SECURITY.md](https://github.com/electron/electron/tree/master/SECURITY.md)
## Chromium Security Issues and Upgrades
Electron keeps up to date with alternating Chromium releases. For more information,
see the [Electron Release Cadence blog post](https://electronjs.org/blog/12-week-cadence).
While Electron strives to support new versions of Chromium as soon as possible,
developers should be aware that upgrading is a serious undertaking - involving
hand-editing dozens or even hundreds of files. Given the resources and
contributions available today, Electron will often not be on the very latest
version of Chromium, lagging behind by several weeks or a few months.
We feel that our current system of updating the Chromium component strikes an
appropriate balance between the resources we have available and the needs of
the majority of applications built on top of the framework. We definitely are
interested in hearing more about specific use cases from the people that build
things on top of Electron. Pull requests and contributions supporting this
effort are always very welcome.
## Security Is Everyone's Responsibility
@@ -511,7 +521,7 @@ no circumstances should you enable features speculatively.
// Bad
const mainWindow = new BrowserWindow({
webPreferences: {
enableBlinkFeatures: 'ExecCommandInJavaScript'
enableBlinkFeatures: ['ExecCommandInJavaScript']
}
})
```

View File

@@ -18,55 +18,4 @@
<message name="IDS_DESKTOP_MEDIA_PICKER_MULTIPLE_SCREEN_NAME" desc="Name for screens in the desktop media picker UI when there are multiple monitors.">
{SCREEN_INDEX, plural, =1{Screen #} other{Screen #}}
</message>
<!-- Picture-in-Picture -->
<if expr="is_macosx">
<message name="IDS_PICTURE_IN_PICTURE_TITLE_TEXT" desc="Title of the Picture-in-Picture window. This appears in the system tray and window header.">
Picture in Picture
</message>
</if>
<if expr="not is_macosx">
<message name="IDS_PICTURE_IN_PICTURE_TITLE_TEXT" desc="Title of the Picture-in-Picture window. This appears in the system tray and window header.">
Picture in picture
</message>
</if>
<message name="IDS_PICTURE_IN_PICTURE_PAUSE_CONTROL_TEXT" desc="Text label of the pause control button. The button appears when the user hovers over the Picture-in-Picture window and the video is currently playing.">
Pause
</message>
<message name="IDS_PICTURE_IN_PICTURE_PLAY_CONTROL_TEXT" desc="Text label of the play control button. The button appears when the user hovers over the Picture-in-Picture window and the video is currently paused.">
Play
</message>
<message name="IDS_PICTURE_IN_PICTURE_REPLAY_CONTROL_TEXT" desc="Text label of the replay control button. The button appears when the user hovers over the Picture-in-Picture window and the video is ended.">
Play from the beginning
</message>
<message name="IDS_PICTURE_IN_PICTURE_BACK_TO_TAB_CONTROL_TEXT" desc="Text label of the back to tab control button. The button appears when the user hovers over the Picture-in-Picture window.">
Back to video player
</message>
<message name="IDS_PICTURE_IN_PICTURE_MUTE_CONTROL_TEXT" desc="Text label of the mute control button. The button appears when the user hovers over the Picture-in-Picture window and the video is currently unmuted.">
Mute
</message>
<message name="IDS_PICTURE_IN_PICTURE_UNMUTE_CONTROL_TEXT" desc="Text label of the mute control button. The button appears when the user hovers over the Picture-in-Picture window and the video is currently muted.">
Unmute
</message>
<message name="IDS_PICTURE_IN_PICTURE_SKIP_AD_CONTROL_TEXT" desc="Text label of the skip ad control button. The button appears when the user hovers over the Picture-in-Picture window.">
Skip Ad
</message>
<message name="IDS_PICTURE_IN_PICTURE_CLOSE_CONTROL_TEXT" desc="Text label of the close control button. The button appears when the user hovers over the Picture-in-Picture window.">
Close
</message>
<message name="IDS_PICTURE_IN_PICTURE_RESIZE_HANDLE_TEXT" desc="Text label of the resize handle. The button appears when the user hovers over the Picture-in-Picture window.">
Resize
</message>
<message name="IDS_PICTURE_IN_PICTURE_PLAY_PAUSE_CONTROL_ACCESSIBLE_TEXT" desc="Accessible text label used for the controls button in the Picture-in-Picture window. The button toggles between play and pause controls.">
Toggle video to play or pause
</message>
<message name="IDS_PICTURE_IN_PICTURE_MUTE_CONTROL_ACCESSIBLE_TEXT" desc="Accessible text label used for the controls button in the Picture-in-Picture window. The button toggles mute state.">
Toggle mute
</message>
<message name="IDS_PICTURE_IN_PICTURE_NEXT_TRACK_CONTROL_ACCESSIBLE_TEXT" desc="Accessible text label used for the controls button in the Picture-in-Picture window. The button invokes next track action.">
Next track
</message>
<message name="IDS_PICTURE_IN_PICTURE_PREVIOUS_TRACK_CONTROL_ACCESSIBLE_TEXT" desc="Accessible text label used for the controls button in the Picture-in-Picture window. The button invokes previous track action.">
Previous track
</message>
</grit-part>

View File

@@ -34,7 +34,6 @@ auto_filenames = {
"docs/api/menu.md",
"docs/api/modernization",
"docs/api/native-image.md",
"docs/api/native-theme.md",
"docs/api/net-log.md",
"docs/api/net.md",
"docs/api/notification.md",
@@ -130,21 +129,19 @@ auto_filenames = {
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/native-theme.ts",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/is-promise.ts",
"lib/common/web-view-methods.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.ts",
@@ -165,8 +162,8 @@ auto_filenames = {
"lib/renderer/web-view/web-view-element.ts",
"lib/renderer/web-view/web-view-impl.ts",
"lib/renderer/web-view/web-view-init.ts",
"lib/sandboxed_renderer/api/exports/electron.ts",
"lib/sandboxed_renderer/api/module-list.ts",
"lib/sandboxed_renderer/api/exports/electron.js",
"lib/sandboxed_renderer/api/module-list.js",
"lib/sandboxed_renderer/init.js",
"package.json",
"tsconfig.electron.json",
@@ -215,7 +212,7 @@ auto_filenames = {
"lib/browser/api/content-tracing.js",
"lib/browser/api/crash-reporter.js",
"lib/browser/api/dialog.js",
"lib/browser/api/exports/electron.ts",
"lib/browser/api/exports/electron.js",
"lib/browser/api/global-shortcut.js",
"lib/browser/api/in-app-purchase.js",
"lib/browser/api/ipc-main.ts",
@@ -223,7 +220,7 @@ auto_filenames = {
"lib/browser/api/menu-item.js",
"lib/browser/api/menu-utils.js",
"lib/browser/api/menu.js",
"lib/browser/api/module-list.ts",
"lib/browser/api/module-list.js",
"lib/browser/api/net-log.js",
"lib/browser/api/net.js",
"lib/browser/api/notification.js",
@@ -232,7 +229,7 @@ auto_filenames = {
"lib/browser/api/protocol.ts",
"lib/browser/api/screen.ts",
"lib/browser/api/session.js",
"lib/browser/api/system-preferences.ts",
"lib/browser/api/system-preferences.js",
"lib/browser/api/top-level-window.js",
"lib/browser/api/touch-bar.js",
"lib/browser/api/tray.js",
@@ -254,7 +251,6 @@ auto_filenames = {
"lib/browser/guest-view-manager.js",
"lib/browser/guest-window-manager.js",
"lib/browser/init.ts",
"lib/browser/ipc-main-impl.ts",
"lib/browser/ipc-main-internal-utils.ts",
"lib/browser/ipc-main-internal.ts",
"lib/browser/navigation-controller.js",
@@ -263,14 +259,13 @@ auto_filenames = {
"lib/browser/utils.ts",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/native-theme.ts",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
@@ -289,14 +284,13 @@ auto_filenames = {
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/native-theme.ts",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
@@ -305,9 +299,9 @@ auto_filenames = {
"lib/common/web-view-methods.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/exports/electron.ts",
"lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/module-list.ts",
"lib/renderer/api/exports/electron.js",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/module-list.js",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.ts",
@@ -340,14 +334,13 @@ auto_filenames = {
"lib/browser/api/module-keys.js",
"lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/exports/electron.js",
"lib/common/api/module-list.js",
"lib/common/api/native-image.js",
"lib/common/api/native-theme.ts",
"lib/common/api/shell.js",
"lib/common/buffer-utils.ts",
"lib/common/clipboard-utils.ts",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts",
"lib/common/error-utils.ts",
"lib/common/init.ts",
@@ -355,9 +348,9 @@ auto_filenames = {
"lib/common/reset-search-paths.ts",
"lib/renderer/api/crash-reporter.js",
"lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/exports/electron.ts",
"lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/module-list.ts",
"lib/renderer/api/exports/electron.js",
"lib/renderer/api/ipc-renderer.js",
"lib/renderer/api/module-list.js",
"lib/renderer/api/remote.js",
"lib/renderer/api/web-frame.ts",
"lib/renderer/callbacks-registry.ts",

View File

@@ -47,8 +47,6 @@ filenames = {
"shell/browser/api/atom_api_content_tracing.cc",
"shell/browser/api/atom_api_cookies.cc",
"shell/browser/api/atom_api_cookies.h",
"shell/browser/api/atom_api_data_pipe_holder.cc",
"shell/browser/api/atom_api_data_pipe_holder.h",
"shell/browser/api/atom_api_debugger.cc",
"shell/browser/api/atom_api_debugger.h",
"shell/browser/api/atom_api_dialog.cc",
@@ -77,6 +75,8 @@ filenames = {
"shell/browser/api/atom_api_power_monitor.h",
"shell/browser/api/atom_api_power_save_blocker.cc",
"shell/browser/api/atom_api_power_save_blocker.h",
"shell/browser/api/atom_api_protocol.cc",
"shell/browser/api/atom_api_protocol.h",
"shell/browser/api/atom_api_protocol_ns.cc",
"shell/browser/api/atom_api_protocol_ns.h",
"shell/browser/api/atom_api_screen.cc",
@@ -91,6 +91,8 @@ filenames = {
"shell/browser/api/atom_api_top_level_window.h",
"shell/browser/api/atom_api_tray.cc",
"shell/browser/api/atom_api_tray.h",
"shell/browser/api/atom_api_url_request.cc",
"shell/browser/api/atom_api_url_request.h",
"shell/browser/api/atom_api_url_request_ns.cc",
"shell/browser/api/atom_api_url_request_ns.h",
"shell/browser/api/atom_api_view.cc",
@@ -101,6 +103,8 @@ filenames = {
"shell/browser/api/atom_api_web_contents_mac.mm",
"shell/browser/api/atom_api_web_contents_view.cc",
"shell/browser/api/atom_api_web_contents_view.h",
"shell/browser/api/atom_api_web_request.cc",
"shell/browser/api/atom_api_web_request.h",
"shell/browser/api/atom_api_web_request_ns.cc",
"shell/browser/api/atom_api_web_request_ns.h",
"shell/browser/api/atom_api_web_view_manager.cc",
@@ -112,6 +116,8 @@ filenames = {
"shell/browser/api/event.h",
"shell/browser/api/event_emitter.cc",
"shell/browser/api/event_emitter.h",
"shell/browser/api/stream_subscriber.cc",
"shell/browser/api/stream_subscriber.h",
"shell/browser/api/trackable_object.cc",
"shell/browser/api/trackable_object.h",
"shell/browser/api/frame_subscriber.cc",
@@ -127,10 +133,8 @@ filenames = {
"shell/browser/auto_updater.cc",
"shell/browser/auto_updater.h",
"shell/browser/auto_updater_mac.mm",
"shell/browser/atom_autofill_driver_factory.cc",
"shell/browser/atom_autofill_driver_factory.h",
"shell/browser/atom_autofill_driver.cc",
"shell/browser/atom_autofill_driver.h",
"shell/browser/atom_blob_reader.cc",
"shell/browser/atom_blob_reader.h",
"shell/browser/atom_browser_client.cc",
"shell/browser/atom_browser_client.h",
"shell/browser/atom_browser_context.cc",
@@ -172,6 +176,8 @@ filenames = {
"shell/browser/common_web_contents_delegate.h",
"shell/browser/cookie_change_notifier.cc",
"shell/browser/cookie_change_notifier.h",
"shell/browser/io_thread.cc",
"shell/browser/io_thread.h",
"shell/browser/javascript_environment.cc",
"shell/browser/javascript_environment.h",
"shell/browser/lib/bluetooth_chooser.cc",
@@ -179,6 +185,8 @@ filenames = {
"shell/browser/lib/power_observer.h",
"shell/browser/lib/power_observer_linux.h",
"shell/browser/lib/power_observer_linux.cc",
"shell/browser/loader/layered_resource_handler.cc",
"shell/browser/loader/layered_resource_handler.h",
"shell/browser/login_handler.cc",
"shell/browser/login_handler.h",
"shell/browser/mac/atom_application.h",
@@ -215,26 +223,58 @@ filenames = {
"shell/browser/media/media_device_id_salt.h",
"shell/browser/media/media_stream_devices_controller.cc",
"shell/browser/media/media_stream_devices_controller.h",
"shell/browser/net/about_protocol_handler.cc",
"shell/browser/net/about_protocol_handler.h",
"shell/browser/net/asar/asar_protocol_handler.cc",
"shell/browser/net/asar/asar_protocol_handler.h",
"shell/browser/net/asar/asar_url_loader.cc",
"shell/browser/net/asar/asar_url_loader.h",
"shell/browser/net/asar/url_request_asar_job.cc",
"shell/browser/net/asar/url_request_asar_job.h",
"shell/browser/net/atom_cert_verifier.cc",
"shell/browser/net/atom_cert_verifier.h",
"shell/browser/net/atom_network_delegate.cc",
"shell/browser/net/atom_network_delegate.h",
"shell/browser/net/atom_url_loader_factory.cc",
"shell/browser/net/atom_url_loader_factory.h",
"shell/browser/net/cert_verifier_client.cc",
"shell/browser/net/cert_verifier_client.h",
"shell/browser/net/atom_url_request.cc",
"shell/browser/net/atom_url_request.h",
"shell/browser/net/atom_url_request_job_factory.cc",
"shell/browser/net/atom_url_request_job_factory.h",
"shell/browser/net/http_protocol_handler.cc",
"shell/browser/net/http_protocol_handler.h",
"shell/browser/net/proxying_url_loader_factory.cc",
"shell/browser/net/proxying_url_loader_factory.h",
"shell/browser/net/js_asker.cc",
"shell/browser/net/js_asker.h",
"shell/browser/net/network_context_service_factory.cc",
"shell/browser/net/network_context_service_factory.h",
"shell/browser/net/network_context_service.cc",
"shell/browser/net/network_context_service.h",
"shell/browser/net/node_stream_loader.cc",
"shell/browser/net/node_stream_loader.h",
"shell/browser/net/require_ct_delegate.cc",
"shell/browser/net/require_ct_delegate.h",
"shell/browser/net/resolve_proxy_helper.cc",
"shell/browser/net/resolve_proxy_helper.h",
"shell/browser/net/system_network_context_manager.cc",
"shell/browser/net/system_network_context_manager.h",
"shell/browser/net/url_pipe_loader.cc",
"shell/browser/net/url_pipe_loader.h",
"shell/browser/net/url_request_about_job.cc",
"shell/browser/net/url_request_about_job.h",
"shell/browser/net/url_request_async_asar_job.cc",
"shell/browser/net/url_request_async_asar_job.h",
"shell/browser/net/url_request_string_job.cc",
"shell/browser/net/url_request_string_job.h",
"shell/browser/net/url_request_buffer_job.cc",
"shell/browser/net/url_request_buffer_job.h",
"shell/browser/net/url_request_context_getter.cc",
"shell/browser/net/url_request_context_getter.h",
"shell/browser/net/url_request_fetch_job.cc",
"shell/browser/net/url_request_fetch_job.h",
"shell/browser/net/url_request_stream_job.cc",
"shell/browser/net/url_request_stream_job.h",
"shell/browser/notifications/linux/libnotify_notification.cc",
"shell/browser/notifications/linux/libnotify_notification.h",
"shell/browser/notifications/linux/notification_presenter_linux.cc",
@@ -276,8 +316,6 @@ filenames = {
"shell/browser/relauncher_win.cc",
"shell/browser/relauncher.cc",
"shell/browser/relauncher.h",
"shell/browser/renderer_host/electron_render_message_filter.cc",
"shell/browser/renderer_host/electron_render_message_filter.h",
"shell/browser/session_preferences.cc",
"shell/browser/session_preferences.h",
"shell/browser/special_storage_policy.cc",
@@ -326,8 +364,6 @@ filenames = {
"shell/browser/ui/file_dialog_gtk.cc",
"shell/browser/ui/file_dialog_mac.mm",
"shell/browser/ui/file_dialog_win.cc",
"shell/browser/ui/util_gtk.cc",
"shell/browser/ui/util_gtk.h",
"shell/browser/ui/inspectable_web_contents.cc",
"shell/browser/ui/inspectable_web_contents.h",
"shell/browser/ui/inspectable_web_contents_delegate.h",
@@ -427,8 +463,6 @@ filenames = {
"shell/common/api/atom_api_native_image.cc",
"shell/common/api/atom_api_native_image.h",
"shell/common/api/atom_api_native_image_mac.mm",
"shell/common/api/atom_api_native_theme.cc",
"shell/common/api/atom_api_native_theme.h",
"shell/common/api/atom_api_shell.cc",
"shell/common/api/atom_api_v8_util.cc",
"shell/common/api/electron_bindings.cc",
@@ -437,7 +471,6 @@ filenames = {
"shell/common/api/event_emitter_caller.cc",
"shell/common/api/event_emitter_caller.h",
"shell/common/api/features.cc",
"shell/common/api/gin_utils.h",
"shell/common/api/locker.cc",
"shell/common/api/locker.h",
"shell/common/api/object_life_monitor.cc",
@@ -475,22 +508,6 @@ filenames = {
"shell/common/crash_reporter/linux/crash_dump_handler.h",
"shell/common/crash_reporter/win/crash_service_main.cc",
"shell/common/crash_reporter/win/crash_service_main.h",
"shell/common/gin_converters/callback_converter_gin_adapter.h",
"shell/common/gin_converters/file_dialog_converter.cc",
"shell/common/gin_converters/file_dialog_converter.h",
"shell/common/gin_converters/file_path_converter.h",
"shell/common/gin_converters/gurl_converter.h",
"shell/common/gin_converters/image_converter.cc",
"shell/common/gin_converters/image_converter.h",
"shell/common/gin_converters/message_box_converter.cc",
"shell/common/gin_converters/message_box_converter.h",
"shell/common/gin_converters/native_window_converter.h",
"shell/common/gin_converters/net_converter.cc",
"shell/common/gin_converters/net_converter.h",
"shell/common/gin_converters/std_converter.h",
"shell/common/gin_converters/value_converter_gin_adapter.h",
"shell/common/gin_helper/destroyable.cc",
"shell/common/gin_helper/destroyable.h",
"shell/common/gin_util.h",
"shell/common/heap_snapshot.cc",
"shell/common/heap_snapshot.h",
@@ -499,8 +516,6 @@ filenames = {
"shell/common/keyboard_util.h",
"shell/common/deprecate_util.cc",
"shell/common/deprecate_util.h",
"shell/common/error_util.cc",
"shell/common/error_util.h",
"shell/common/mouse_util.cc",
"shell/common/mouse_util.h",
"shell/common/mac/main_application_bundle.h",
@@ -513,14 +528,18 @@ filenames = {
"shell/common/native_mate_converters/callback.h",
"shell/common/native_mate_converters/content_converter.cc",
"shell/common/native_mate_converters/content_converter.h",
"shell/common/native_mate_converters/file_dialog_converter.cc",
"shell/common/native_mate_converters/file_dialog_converter.h",
"shell/common/native_mate_converters/message_box_converter.cc",
"shell/common/native_mate_converters/message_box_converter.h",
"shell/common/native_mate_converters/file_path_converter.h",
"shell/common/native_mate_converters/gfx_converter.cc",
"shell/common/native_mate_converters/gfx_converter.h",
"shell/common/native_mate_converters/gurl_converter.h",
"shell/common/native_mate_converters/image_converter.cc",
"shell/common/native_mate_converters/image_converter.h",
"shell/common/native_mate_converters/map_converter.h",
"shell/common/native_mate_converters/native_window_converter.h",
"shell/common/native_mate_converters/net_converter.cc",
"shell/common/native_mate_converters/net_converter.h",
"shell/common/native_mate_converters/network_converter.cc",
"shell/common/native_mate_converters/network_converter.h",

View File

@@ -4,29 +4,15 @@ const { app, BrowserWindow, deprecate } = require('electron')
const binding = process.electronBinding('dialog')
const v8Util = process.electronBinding('v8_util')
const DialogType = {
OPEN: 'OPEN',
SAVE: 'SAVE'
}
const saveFileDialogProperties = {
createDirectory: 1 << 0,
showHiddenFiles: 1 << 1,
treatPackageAsDirectory: 1 << 2,
showOverwriteConfirmation: 1 << 3,
dontAddToRecent: 1 << 4
}
const openFileDialogProperties = {
const fileDialogProperties = {
openFile: 1 << 0,
openDirectory: 1 << 1,
multiSelections: 1 << 2,
createDirectory: 1 << 3, // macOS
createDirectory: 1 << 3,
showHiddenFiles: 1 << 4,
promptToCreate: 1 << 5, // Windows
noResolveAliases: 1 << 6, // macOS
treatPackageAsDirectory: 1 << 7, // macOS
dontAddToRecent: 1 << 8 // Windows
promptToCreate: 1 << 5,
noResolveAliases: 1 << 6,
treatPackageAsDirectory: 1 << 7
}
const normalizeAccessKey = (text) => {
@@ -58,18 +44,6 @@ const checkAppInitialized = function () {
}
}
const setupDialogProperties = (type, properties) => {
const dialogPropertiesTypes = (type === DialogType.OPEN) ? openFileDialogProperties : saveFileDialogProperties
let dialogProperties = 0
for (const prop in dialogPropertiesTypes) {
if (properties.includes(prop)) {
dialogProperties |= dialogPropertiesTypes[prop]
}
}
return dialogProperties
}
const saveDialog = (sync, window, options) => {
checkAppInitialized()
@@ -84,7 +58,6 @@ const saveDialog = (sync, window, options) => {
buttonLabel = '',
defaultPath = '',
filters = [],
properties = [],
title = '',
message = '',
securityScopedBookmarks = false,
@@ -99,8 +72,6 @@ const saveDialog = (sync, window, options) => {
if (typeof nameFieldLabel !== 'string') throw new TypeError('Name field label must be a string')
const settings = { buttonLabel, defaultPath, filters, title, message, securityScopedBookmarks, nameFieldLabel, showsTagField, window }
settings.properties = setupDialogProperties(DialogType.SAVE, properties)
return (sync) ? binding.showSaveDialogSync(settings) : binding.showSaveDialog(settings)
}
@@ -131,13 +102,20 @@ const openDialog = (sync, window, options) => {
if (!Array.isArray(properties)) throw new TypeError('Properties must be an array')
let dialogProperties = 0
for (const prop in fileDialogProperties) {
if (properties.includes(prop)) {
dialogProperties |= fileDialogProperties[prop]
}
}
if (typeof title !== 'string') throw new TypeError('Title must be a string')
if (typeof buttonLabel !== 'string') throw new TypeError('Button label must be a string')
if (typeof defaultPath !== 'string') throw new TypeError('Default path must be a string')
if (typeof message !== 'string') throw new TypeError('Message must be a string')
const settings = { title, buttonLabel, defaultPath, filters, message, securityScopedBookmarks, window }
settings.properties = setupDialogProperties(DialogType.OPEN, properties)
settings.properties = dialogProperties
return (sync) ? binding.showOpenDialogSync(settings) : binding.showOpenDialog(settings)
}

View File

@@ -0,0 +1,15 @@
'use strict'
const common = require('@electron/internal/common/api/exports/electron')
// since browser module list is also used in renderer, keep it separate.
const moduleList = require('@electron/internal/browser/api/module-list')
// Import common modules.
common.defineProperties(exports)
for (const module of moduleList) {
Object.defineProperty(exports, module.name, {
enumerable: !module.private,
get: common.handleESModule(module.loader)
})
}

View File

@@ -1,6 +0,0 @@
import { defineProperties } from '@electron/internal/common/define-properties'
import { commonModuleList } from '@electron/internal/common/api/module-list'
import { browserModuleList } from '@electron/internal/browser/api/module-list'
defineProperties(exports, commonModuleList)
defineProperties(exports, browserModuleList)

View File

@@ -1,6 +1,38 @@
import { IpcMainImpl } from '@electron/internal/browser/ipc-main-impl'
import { EventEmitter } from 'events'
import { IpcMainInvokeEvent } from 'electron'
const ipcMain = new IpcMainImpl()
class IpcMain extends EventEmitter {
private _invokeHandlers: Map<string, (e: IpcMainInvokeEvent, ...args: any[]) => void> = new Map();
handle: Electron.IpcMain['handle'] = (method, fn) => {
if (this._invokeHandlers.has(method)) {
throw new Error(`Attempted to register a second handler for '${method}'`)
}
if (typeof fn !== 'function') {
throw new Error(`Expected handler to be a function, but found type '${typeof fn}'`)
}
this._invokeHandlers.set(method, async (e, ...args) => {
try {
(e as any)._reply(await Promise.resolve(fn(e, ...args)))
} catch (err) {
(e as any)._throw(err)
}
})
}
handleOnce: Electron.IpcMain['handleOnce'] = (method, fn) => {
this.handle(method, (e, ...args) => {
this.removeHandler(method)
return fn(e, ...args)
})
}
removeHandler (method: string) {
this._invokeHandlers.delete(method)
}
}
const ipcMain = new IpcMain()
// Do not throw exception when channel name is "error".
ipcMain.on('error', () => {})

View File

@@ -1,9 +1,11 @@
'use strict'
// TODO: Updating this file also required updating the module-keys file
const features = process.electronBinding('features')
// Browser side modules, please sort alphabetically.
export const browserModuleList: ElectronInternal.ModuleEntry[] = [
module.exports = [
{ name: 'app', loader: () => require('./app') },
{ name: 'autoUpdater', loader: () => require('./auto-updater') },
{ name: 'BrowserView', loader: () => require('./browser-view') },
@@ -34,7 +36,7 @@ export const browserModuleList: ElectronInternal.ModuleEntry[] = [
]
if (features.isViewApiEnabled()) {
browserModuleList.push(
module.exports.push(
{ name: 'BoxLayout', loader: () => require('./views/box-layout') },
{ name: 'Button', loader: () => require('./views/button') },
{ name: 'LabelButton', loader: () => require('./views/label-button') },

View File

@@ -0,0 +1,15 @@
'use strict'
const { EventEmitter } = require('events')
const { deprecate } = require('electron')
const { systemPreferences, SystemPreferences } = process.electronBinding('system_preferences')
// SystemPreferences is an EventEmitter.
Object.setPrototypeOf(SystemPreferences.prototype, EventEmitter.prototype)
EventEmitter.call(systemPreferences)
if ('appLevelAppearance' in systemPreferences) {
deprecate.fnToProperty(SystemPreferences.prototype, 'appLevelAppearance', '_getAppLevelAppearance', '_setAppLevelAppearance')
}
module.exports = systemPreferences

View File

@@ -1,42 +0,0 @@
import { EventEmitter } from 'events'
import { deprecate } from 'electron'
const { systemPreferences, SystemPreferences } = process.electronBinding('system_preferences')
// SystemPreferences is an EventEmitter.
Object.setPrototypeOf(SystemPreferences.prototype, EventEmitter.prototype)
EventEmitter.call(systemPreferences)
if ('appLevelAppearance' in systemPreferences) {
deprecate.fnToProperty(
SystemPreferences.prototype,
'appLevelAppearance',
'_getAppLevelAppearance',
'_setAppLevelAppearance'
)
}
if ('effectiveAppearance' in systemPreferences) {
deprecate.fnToProperty(
SystemPreferences.prototype,
'effectiveAppearance',
'_getEffectiveAppearance'
)
}
SystemPreferences.prototype.isDarkMode = deprecate.moveAPI(
SystemPreferences.prototype.isDarkMode,
'systemPreferences.isDarkMode()',
'nativeTheme.shouldUseDarkColors'
)
SystemPreferences.prototype.isInvertedColorScheme = deprecate.moveAPI(
SystemPreferences.prototype.isInvertedColorScheme,
'systemPreferences.isInvertedColorScheme()',
'nativeTheme.shouldUseInvertedColorScheme'
)
SystemPreferences.prototype.isHighContrastColorScheme = deprecate.moveAPI(
SystemPreferences.prototype.isHighContrastColorScheme,
'systemPreferences.isHighContrastColorScheme()',
'nativeTheme.shouldUseHighContrastColors'
)
module.exports = systemPreferences

View File

@@ -327,15 +327,14 @@ WebContents.prototype._init = function () {
}
})
this.on('-ipc-invoke', function (event, internal, channel, args) {
this.on('-ipc-invoke', function (event, channel, args) {
event._reply = (result) => event.sendReply({ result })
event._throw = (error) => {
console.error(`Error occurred in handler for '${channel}':`, error)
event.sendReply({ error: error.toString() })
}
const target = internal ? ipcMainInternal : ipcMain
if (target._invokeHandlers.has(channel)) {
target._invokeHandlers.get(channel)(event, ...args)
if (ipcMain._invokeHandlers.has(channel)) {
ipcMain._invokeHandlers.get(channel)(event, ...args)
} else {
event._throw(`No handler registered for '${channel}'`)
}

View File

@@ -1,12 +1,7 @@
'use strict'
if (process.electronBinding('features').isExtensionsEnabled()) {
throw new Error('Attempted to load JS chrome-extension polyfill with //extensions support enabled')
}
const { app, webContents, BrowserWindow } = require('electron')
const { getAllWebContents } = process.electronBinding('web_contents')
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
const { Buffer } = require('buffer')
@@ -161,7 +156,7 @@ const hookWebContentsEvents = function (webContents) {
// Handle the chrome.* API messages.
let nextId = 0
ipcMainUtils.handleSync('CHROME_RUNTIME_CONNECT', function (event, extensionId, connectInfo) {
ipcMainUtils.handle('CHROME_RUNTIME_CONNECT', function (event, extensionId, connectInfo) {
if (isBackgroundPage(event.sender)) {
throw new Error('chrome.runtime.connect is not supported in background page')
}
@@ -183,7 +178,7 @@ ipcMainUtils.handleSync('CHROME_RUNTIME_CONNECT', function (event, extensionId,
return { tabId, portId }
})
ipcMainUtils.handleSync('CHROME_EXTENSION_MANIFEST', function (event, extensionId) {
ipcMainUtils.handle('CHROME_EXTENSION_MANIFEST', function (event, extensionId) {
const manifest = manifestMap[extensionId]
if (!manifest) {
throw new Error(`Invalid extensionId: ${extensionId}`)
@@ -191,7 +186,7 @@ ipcMainUtils.handleSync('CHROME_EXTENSION_MANIFEST', function (event, extensionI
return manifest
})
ipcMainInternal.handle('CHROME_RUNTIME_SEND_MESSAGE', async function (event, extensionId, message) {
ipcMainUtils.handle('CHROME_RUNTIME_SEND_MESSAGE', async function (event, extensionId, message) {
if (isBackgroundPage(event.sender)) {
throw new Error('chrome.runtime.sendMessage is not supported in background page')
}
@@ -204,7 +199,7 @@ ipcMainInternal.handle('CHROME_RUNTIME_SEND_MESSAGE', async function (event, ext
return ipcMainUtils.invokeInWebContents(page.webContents, true, `CHROME_RUNTIME_ONMESSAGE_${extensionId}`, event.sender.id, message)
})
ipcMainInternal.handle('CHROME_TABS_SEND_MESSAGE', async function (event, tabId, extensionId, message) {
ipcMainUtils.handle('CHROME_TABS_SEND_MESSAGE', async function (event, tabId, extensionId, message) {
const contents = webContents.fromId(tabId)
if (!contents) {
throw new Error(`Sending message to unknown tab ${tabId}`)
@@ -238,7 +233,7 @@ const getMessagesPath = (extensionId) => {
}
}
ipcMainUtils.handleSync('CHROME_GET_MESSAGES', async function (event, extensionId) {
ipcMainUtils.handle('CHROME_GET_MESSAGES', async function (event, extensionId) {
const messagesPath = getMessagesPath(extensionId)
return fs.promises.readFile(messagesPath)
})
@@ -257,7 +252,7 @@ const getChromeStoragePath = (storageType, extensionId) => {
return path.join(app.getPath('userData'), `/Chrome Storage/${extensionId}-${storageType}.json`)
}
ipcMainInternal.handle('CHROME_STORAGE_READ', async function (event, storageType, extensionId) {
ipcMainUtils.handle('CHROME_STORAGE_READ', async function (event, storageType, extensionId) {
const filePath = getChromeStoragePath(storageType, extensionId)
try {
@@ -271,7 +266,7 @@ ipcMainInternal.handle('CHROME_STORAGE_READ', async function (event, storageType
}
})
ipcMainInternal.handle('CHROME_STORAGE_WRITE', async function (event, storageType, extensionId, data) {
ipcMainUtils.handle('CHROME_STORAGE_WRITE', async function (event, storageType, extensionId, data) {
const filePath = getChromeStoragePath(storageType, extensionId)
try {
@@ -296,7 +291,7 @@ const assertChromeExtension = function (contents, api) {
}
}
ipcMainInternal.handle('CHROME_TABS_EXECUTE_SCRIPT', async function (event, tabId, extensionId, details) {
ipcMainUtils.handle('CHROME_TABS_EXECUTE_SCRIPT', async function (event, tabId, extensionId, details) {
assertChromeExtension(event.sender, 'chrome.tabs.executeScript()')
const contents = webContents.fromId(tabId)
@@ -432,7 +427,11 @@ const chromeExtensionHandler = function (request, callback) {
}
app.on('session-created', function (ses) {
ses.protocol.registerBufferProtocol('chrome-extension', chromeExtensionHandler)
ses.protocol.registerBufferProtocol('chrome-extension', chromeExtensionHandler, function (error) {
if (error) {
console.error(`Unable to register chrome-extension protocol: ${error}`)
}
})
})
// The persistent path of "DevTools Extensions" preference file.

View File

@@ -2,8 +2,7 @@ import { dialog, Menu } from 'electron'
import * as fs from 'fs'
import * as url from 'url'
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal'
import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-utils'
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
const convertToMenuTemplate = function (items: ContextMenuItem[], handler: (id: number) => void) {
return items.map(function (item) {
@@ -60,7 +59,7 @@ const assertChromeDevTools = function (contents: Electron.WebContents, api: stri
}
}
ipcMainInternal.handle('ELECTRON_INSPECTOR_CONTEXT_MENU', function (event: Electron.IpcMainInvokeEvent, items: ContextMenuItem[], isEditMenu: boolean) {
ipcMainUtils.handle('ELECTRON_INSPECTOR_CONTEXT_MENU', function (event: Electron.IpcMainEvent, items: ContextMenuItem[], isEditMenu: boolean) {
return new Promise(resolve => {
assertChromeDevTools(event.sender, 'window.InspectorFrontendHost.showContextMenuAtPoint()')
@@ -72,7 +71,7 @@ ipcMainInternal.handle('ELECTRON_INSPECTOR_CONTEXT_MENU', function (event: Elect
})
})
ipcMainInternal.handle('ELECTRON_INSPECTOR_SELECT_FILE', async function (event: Electron.IpcMainInvokeEvent) {
ipcMainUtils.handle('ELECTRON_INSPECTOR_SELECT_FILE', async function (event: Electron.IpcMainEvent) {
assertChromeDevTools(event.sender, 'window.UI.createFileSelectorElement()')
const result = await dialog.showOpenDialog({})
@@ -84,7 +83,7 @@ ipcMainInternal.handle('ELECTRON_INSPECTOR_SELECT_FILE', async function (event:
return [path, data]
})
ipcMainUtils.handleSync('ELECTRON_INSPECTOR_CONFIRM', async function (event: Electron.IpcMainInvokeEvent, message: string = '', title: string = '') {
ipcMainUtils.handle('ELECTRON_INSPECTOR_CONFIRM', async function (event: Electron.IpcMainEvent, message: string = '', title: string = '') {
assertChromeDevTools(event.sender, 'window.confirm()')
const options = {

View File

@@ -312,33 +312,21 @@ const isWebViewTagEnabled = function (contents) {
return isWebViewTagEnabledCache.get(contents)
}
const makeSafeHandler = function (channel, handler) {
return (event, ...args) => {
const handleMessage = function (channel, handler) {
ipcMainUtils.handle(channel, (event, ...args) => {
if (isWebViewTagEnabled(event.sender)) {
return handler(event, ...args)
} else {
console.error(`<webview> IPC message ${channel} sent by WebContents with <webview> disabled (${event.sender.id})`)
throw new Error('<webview> disabled')
}
}
}
const handleMessage = function (channel, handler) {
ipcMainInternal.handle(channel, makeSafeHandler(channel, handler))
}
const handleMessageSync = function (channel, handler) {
ipcMainUtils.handleSync(channel, makeSafeHandler(channel, handler))
})
}
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', function (event, params) {
return createGuest(event.sender, params)
})
handleMessageSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', function (event, params) {
return createGuest(event.sender, params)
})
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', function (event, embedderFrameId, elementInstanceId, guestInstanceId, params) {
try {
attachGuest(event, embedderFrameId, elementInstanceId, guestInstanceId, params)
@@ -357,18 +345,11 @@ ipcMainInternal.on('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', function (event,
}
})
const allMethods = new Set([ ...syncMethods, ...asyncMethods ])
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_CALL', function (event, guestInstanceId, method, args) {
const guest = getGuestForWebContents(guestInstanceId, event.sender)
if (!asyncMethods.has(method)) {
throw new Error(`Invalid method: ${method}`)
}
return guest[method](...args)
})
handleMessageSync('ELECTRON_GUEST_VIEW_MANAGER_CALL', function (event, guestInstanceId, method, args) {
const guest = getGuestForWebContents(guestInstanceId, event.sender)
if (!syncMethods.has(method)) {
if (!allMethods.has(method)) {
throw new Error(`Invalid method: ${method}`)
}

View File

@@ -271,30 +271,15 @@ ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_INTERNAL_WINDOW_OPEN', functio
}
})
const makeSafeHandler = function (handler) {
return (event, guestId, ...args) => {
const handleMessage = function (channel, handler) {
ipcMainUtils.handle(channel, (event, guestId, ...args) => {
const guestContents = webContents.fromId(guestId)
if (!guestContents) {
throw new Error(`Invalid guestId: ${guestId}`)
}
return handler(event, guestContents, ...args)
}
}
const handleMessage = function (channel, handler) {
ipcMainInternal.handle(channel, makeSafeHandler(handler))
}
const handleMessageSync = function (channel, handler) {
ipcMainUtils.handleSync(channel, makeSafeHandler(handler))
}
const assertCanAccessWindow = function (contents, guestContents) {
if (!canAccessWindow(contents, guestContents)) {
console.error(`Blocked ${contents.getURL()} from accessing guestId: ${guestContents.id}`)
throw new Error(`Access denied to guestId: ${guestContents.id}`)
}
})
}
const windowMethods = new Set([
@@ -304,7 +289,10 @@ const windowMethods = new Set([
])
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', (event, guestContents, method, ...args) => {
assertCanAccessWindow(event.sender, guestContents)
if (!canAccessWindow(event.sender, guestContents)) {
console.error(`Blocked ${event.sender.getURL()} from accessing guestId: ${guestContents.id}`)
throw new Error(`Access denied to guestId: ${guestContents.id}`)
}
if (!windowMethods.has(method)) {
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
@@ -328,31 +316,20 @@ handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', (event, guestC
}
})
const webContentsMethodsAsync = new Set([
const webContentsMethods = new Set([
'getURL',
'loadURL',
'executeJavaScript',
'print'
])
handleMessage('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method, ...args) => {
assertCanAccessWindow(event.sender, guestContents)
if (!canAccessWindow(event.sender, guestContents)) {
console.error(`Blocked ${event.sender.getURL()} from accessing guestId: ${guestContents.id}`)
throw new Error(`Access denied to guestId: ${guestContents.id}`)
}
if (!webContentsMethodsAsync.has(method)) {
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
throw new Error(`Invalid method: ${method}`)
}
return guestContents[method](...args)
})
const webContentsMethodsSync = new Set([
'getURL'
])
handleMessageSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', (event, guestContents, method, ...args) => {
assertCanAccessWindow(event.sender, guestContents)
if (!webContentsMethodsSync.has(method)) {
if (!webContentsMethods.has(method)) {
console.error(`Blocked ${event.sender.getURL()} from calling method: ${method}`)
throw new Error(`Invalid method: ${method}`)
}

View File

@@ -152,9 +152,7 @@ app._setDefaultAppPaths(packagePath)
require('@electron/internal/browser/devtools')
// Load the chrome extension support.
if (!process.electronBinding('features').isExtensionsEnabled()) {
require('@electron/internal/browser/chrome-extension')
}
require('@electron/internal/browser/chrome-extension')
// Load protocol module to ensure it is populated on app ready
require('@electron/internal/browser/api/protocol')

View File

@@ -1,33 +0,0 @@
import { EventEmitter } from 'events'
import { IpcMainInvokeEvent } from 'electron'
export class IpcMainImpl extends EventEmitter {
private _invokeHandlers: Map<string, (e: IpcMainInvokeEvent, ...args: any[]) => void> = new Map();
handle: Electron.IpcMain['handle'] = (method, fn) => {
if (this._invokeHandlers.has(method)) {
throw new Error(`Attempted to register a second handler for '${method}'`)
}
if (typeof fn !== 'function') {
throw new Error(`Expected handler to be a function, but found type '${typeof fn}'`)
}
this._invokeHandlers.set(method, async (e, ...args) => {
try {
(e as any)._reply(await Promise.resolve(fn(e, ...args)))
} catch (err) {
(e as any)._throw(err)
}
})
}
handleOnce: Electron.IpcMain['handleOnce'] = (method, fn) => {
this.handle(method, (e, ...args) => {
this.removeHandler(method)
return fn(e, ...args)
})
}
removeHandler (method: string) {
this._invokeHandlers.delete(method)
}
}

View File

@@ -1,15 +1,26 @@
import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal'
import * as errorUtils from '@electron/internal/common/error-utils'
type IPCHandler = (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any
type IPCHandler = (event: ElectronInternal.IpcMainInternalEvent, ...args: any[]) => any
export const handleSync = function <T extends IPCHandler> (channel: string, handler: T) {
ipcMainInternal.on(channel, async (event, ...args) => {
try {
event.returnValue = [null, await handler(event, ...args)]
} catch (error) {
event.returnValue = [errorUtils.serialize(error)]
}
const callHandler = async function (handler: IPCHandler, event: ElectronInternal.IpcMainInternalEvent, args: any[], reply: (args: any[]) => void) {
try {
const result = await handler(event, ...args)
reply([null, result])
} catch (error) {
reply([errorUtils.serialize(error)])
}
}
export const handle = function <T extends IPCHandler> (channel: string, handler: T) {
ipcMainInternal.on(channel, (event, requestId, ...args) => {
callHandler(handler, event, args, responseArgs => {
if (requestId) {
event._replyInternal(`${channel}_RESPONSE_${requestId}`, ...responseArgs)
} else {
event.returnValue = responseArgs
}
})
})
}

View File

@@ -1,6 +1,8 @@
import { IpcMainImpl } from '@electron/internal/browser/ipc-main-impl'
import { EventEmitter } from 'events'
export const ipcMainInternal = new IpcMainImpl() as ElectronInternal.IpcMainInternal
const emitter = new EventEmitter()
// Do not throw exception when channel name is "error".
ipcMainInternal.on('error', () => {})
emitter.on('error', () => {})
export const ipcMainInternal = emitter as ElectronInternal.IpcMainInternal

View File

@@ -9,6 +9,7 @@ const eventBinding = process.electronBinding('event')
const clipboard = process.electronBinding('clipboard')
const features = process.electronBinding('features')
const { getContentScripts } = require('@electron/internal/browser/chrome-extension')
const { crashReporterInit } = require('@electron/internal/browser/crash-reporter-init')
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
@@ -241,16 +242,11 @@ const unwrapArgs = function (sender, frameId, contextId, args) {
return args.map(metaToValue)
}
const isRemoteModuleEnabledImpl = function (contents) {
const webPreferences = contents.getLastWebPreferences() || {}
return !!webPreferences.enableRemoteModule
}
const isRemoteModuleEnabledCache = new WeakMap()
const isRemoteModuleEnabled = function (contents) {
if (!isRemoteModuleEnabledCache.has(contents)) {
isRemoteModuleEnabledCache.set(contents, isRemoteModuleEnabledImpl(contents))
isRemoteModuleEnabledCache.set(contents, contents._isRemoteModuleEnabled())
}
return isRemoteModuleEnabledCache.get(contents)
@@ -476,11 +472,11 @@ ipcMainInternal.on('ELECTRON_BROWSER_WINDOW_CLOSE', function (event) {
event.returnValue = null
})
ipcMainUtils.handleSync('ELECTRON_CRASH_REPORTER_INIT', function (event, options) {
ipcMainUtils.handle('ELECTRON_CRASH_REPORTER_INIT', function (event, options) {
return crashReporterInit(options)
})
ipcMainInternal.handle('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES', function (event) {
ipcMainUtils.handle('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES', function (event) {
return event.sender.getLastWebPreferences()
})
@@ -496,7 +492,7 @@ const allowedClipboardMethods = (() => {
}
})()
ipcMainUtils.handleSync('ELECTRON_BROWSER_CLIPBOARD', function (event, method, ...args) {
ipcMainUtils.handle('ELECTRON_BROWSER_CLIPBOARD', function (event, method, ...args) {
if (!allowedClipboardMethods.has(method)) {
throw new Error(`Invalid method: ${method}`)
}
@@ -507,7 +503,7 @@ ipcMainUtils.handleSync('ELECTRON_BROWSER_CLIPBOARD', function (event, method, .
if (features.isDesktopCapturerEnabled()) {
const desktopCapturer = require('@electron/internal/browser/desktop-capturer')
ipcMainInternal.handle('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', function (event, ...args) {
ipcMainUtils.handle('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', function (event, ...args) {
const customEvent = emitCustomEvent(event.sender, 'desktop-capturer-get-sources')
if (customEvent.defaultPrevented) {
@@ -530,24 +526,13 @@ const getPreloadScript = async function (preloadPath) {
return { preloadPath, preloadSrc, preloadError }
}
if (process.electronBinding('features').isExtensionsEnabled()) {
ipcMainUtils.handleSync('ELECTRON_GET_CONTENT_SCRIPTS', () => [])
} else {
const { getContentScripts } = require('@electron/internal/browser/chrome-extension')
ipcMainUtils.handleSync('ELECTRON_GET_CONTENT_SCRIPTS', () => getContentScripts())
}
ipcMainUtils.handle('ELECTRON_GET_CONTENT_SCRIPTS', () => getContentScripts())
ipcMainUtils.handleSync('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event) {
ipcMainUtils.handle('ELECTRON_BROWSER_SANDBOX_LOAD', async function (event) {
const preloadPaths = event.sender._getPreloadPaths()
let contentScripts = []
if (!process.electronBinding('features').isExtensionsEnabled()) {
const { getContentScripts } = require('@electron/internal/browser/chrome-extension')
contentScripts = getContentScripts()
}
return {
contentScripts,
contentScripts: getContentScripts(),
preloadScripts: await Promise.all(preloadPaths.map(path => getPreloadScript(path))),
isRemoteModuleEnabled: isRemoteModuleEnabled(event.sender),
isWebViewTagEnabled: guestViewManager.isWebViewTagEnabled(event.sender),

View File

@@ -51,15 +51,7 @@ const deprecate: ElectronInternal.DeprecationUtil = {
const warn = warnOnce(`${fn.name} function`, `${newName} function`)
return function (this: any) {
warn()
return fn.apply(this, arguments)
}
},
moveAPI: (fn: Function, oldUsage: string, newUsage: string) => {
const warn = warnOnce(oldUsage, newUsage)
return function (this: any) {
warn()
return fn.apply(this, arguments)
fn.apply(this, arguments)
}
},
@@ -77,7 +69,7 @@ const deprecate: ElectronInternal.DeprecationUtil = {
},
// deprecate a getter/setter function pair in favor of a property
fnToProperty: (prototype: any, prop: string, getter: string, setter?: string) => {
fnToProperty: (prototype: any, prop: string, getter: string, setter: string) => {
const withWarnOnce = function (obj: any, key: any, oldName: string, newName: string) {
const warn = warnOnce(oldName, newName)
const method = obj[key]
@@ -88,9 +80,7 @@ const deprecate: ElectronInternal.DeprecationUtil = {
}
prototype[getter.substr(1)] = withWarnOnce(prototype, getter, `${getter.substr(1)} function`, `${prop} property`)
if (setter) {
prototype[setter.substr(1)] = withWarnOnce(prototype, setter, `${setter.substr(1)} function`, `${prop} property`)
}
prototype[setter.substr(1)] = withWarnOnce(prototype, setter, `${setter.substr(1)} function`, `${prop} property`)
},
// remove a property with no replacement

View File

@@ -0,0 +1,37 @@
'use strict'
const moduleList = require('@electron/internal/common/api/module-list')
exports.handleESModule = (loader) => () => {
const value = loader()
if (value.__esModule && value.default) return value.default
return value
}
exports.memoizedGetter = (getter) => {
/*
* It's ok to leak this value as it would be leaked by the global
* node module cache anyway at `Module._cache`. This memoization
* is dramatically faster than relying on nodes module cache however
*/
let memoizedValue = null
return () => {
if (memoizedValue === null) {
memoizedValue = getter()
}
return memoizedValue
}
}
// Attaches properties to |targetExports|.
exports.defineProperties = function (targetExports) {
const descriptors = {}
for (const module of moduleList) {
descriptors[module.name] = {
enumerable: !module.private,
get: exports.handleESModule(module.loader)
}
}
return Object.defineProperties(targetExports, descriptors)
}

View File

@@ -1,8 +1,9 @@
'use strict'
// Common modules, please sort alphabetically
export const commonModuleList: ElectronInternal.ModuleEntry[] = [
module.exports = [
{ name: 'clipboard', loader: () => require('./clipboard') },
{ name: 'nativeImage', loader: () => require('./native-image') },
{ name: 'nativeTheme', loader: () => require('./native-theme') },
{ name: 'shell', loader: () => require('./shell') },
// The internal modules, invisible unless you know their names.
{ name: 'deprecate', loader: () => require('./deprecate'), private: true }

View File

@@ -1,8 +0,0 @@
import { EventEmitter } from 'events'
const { NativeTheme, nativeTheme } = process.electronBinding('native_theme')
Object.setPrototypeOf(NativeTheme.prototype, EventEmitter.prototype)
EventEmitter.call(nativeTheme as any)
module.exports = nativeTheme

View File

@@ -1,17 +0,0 @@
const handleESModule = (loader: ElectronInternal.ModuleLoader) => () => {
const value = loader()
if (value.__esModule && value.default) return value.default
return value
}
// Attaches properties to |targetExports|.
export function defineProperties (targetExports: Object, moduleList: ElectronInternal.ModuleEntry[]) {
const descriptors: PropertyDescriptorMap = {}
for (const module of moduleList) {
descriptors[module.name] = {
enumerable: !module.private,
get: handleESModule(module.loader)
}
}
return Object.defineProperties(targetExports, descriptors)
}

View File

@@ -1,5 +1,5 @@
import { nativeImage } from 'electron'
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'
// |options.types| can't be empty and must be an array
function isValid (options: Electron.SourcesOptions) {
@@ -16,7 +16,7 @@ export async function getSources (options: Electron.SourcesOptions) {
const { thumbnailSize = { width: 150, height: 150 } } = options
const { fetchWindowIcons = false } = options
const sources = await ipcRendererInternal.invoke<ElectronInternal.GetSourcesResult[]>('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', {
const sources = await ipcRendererUtils.invoke<ElectronInternal.GetSourcesResult[]>('ELECTRON_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', {
captureWindow,
captureScreen,
thumbnailSize,

View File

@@ -0,0 +1,14 @@
'use strict'
const common = require('@electron/internal/common/api/exports/electron')
const moduleList = require('@electron/internal/renderer/api/module-list')
// Import common modules.
common.defineProperties(exports)
for (const module of moduleList) {
Object.defineProperty(exports, module.name, {
enumerable: !module.private,
get: common.handleESModule(module.loader)
})
}

View File

@@ -1,6 +0,0 @@
import { defineProperties } from '@electron/internal/common/define-properties'
import { commonModuleList } from '@electron/internal/common/api/module-list'
import { rendererModuleList } from '@electron/internal/renderer/api/module-list'
defineProperties(exports, commonModuleList)
defineProperties(exports, rendererModuleList)

View File

@@ -1,8 +1,10 @@
'use strict'
const { ipc } = process.electronBinding('ipc')
const v8Util = process.electronBinding('v8_util')
// Created by init.js.
const ipcRenderer = v8Util.getHiddenValue<Electron.IpcRenderer>(global, 'ipc')
const ipcRenderer = v8Util.getHiddenValue(global, 'ipc')
const internal = false
ipcRenderer.send = function (channel, ...args) {
@@ -21,12 +23,15 @@ ipcRenderer.sendTo = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, false, webContentsId, channel, args)
}
ipcRenderer.invoke = async function (channel, ...args) {
const { error, result } = await ipc.invoke(internal, channel, args)
if (error) {
throw new Error(`Error invoking remote method '${channel}': ${error}`)
}
return result
ipcRenderer.sendToAll = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, true, webContentsId, channel, args)
}
export default ipcRenderer
ipcRenderer.invoke = function (channel, ...args) {
return ipc.invoke(channel, args).then(({ error, result }) => {
if (error) { throw new Error(`Error invoking remote method '${channel}': ${error}`) }
return result
})
}
module.exports = ipcRenderer

View File

@@ -1,19 +1,22 @@
'use strict'
const features = process.electronBinding('features')
const v8Util = process.electronBinding('v8_util')
const enableRemoteModule = v8Util.getHiddenValue<boolean>(global, 'enableRemoteModule')
const enableRemoteModule = v8Util.getHiddenValue(global, 'enableRemoteModule')
// Renderer side modules, please sort alphabetically.
export const rendererModuleList: ElectronInternal.ModuleEntry[] = [
// A module is `enabled` if there is no explicit condition defined.
module.exports = [
{ name: 'crashReporter', loader: () => require('./crash-reporter') },
{ name: 'ipcRenderer', loader: () => require('./ipc-renderer') },
{ name: 'webFrame', loader: () => require('./web-frame') }
]
if (features.isDesktopCapturerEnabled()) {
rendererModuleList.push({ name: 'desktopCapturer', loader: () => require('./desktop-capturer') })
module.exports.push({ name: 'desktopCapturer', loader: () => require('./desktop-capturer') })
}
if (enableRemoteModule) {
rendererModuleList.push({ name: 'remote', loader: () => require('./remote') })
module.exports.push({ name: 'remote', loader: () => require('./remote') })
}

View File

@@ -349,8 +349,9 @@ const addBuiltinProperty = (name) => {
})
}
const { commonModuleList } = require('@electron/internal/common/api/module-list')
const browserModules = commonModuleList.concat(require('@electron/internal/browser/api/module-keys'))
const browserModules =
require('@electron/internal/common/api/module-list').concat(
require('@electron/internal/browser/api/module-keys'))
// And add a helper receiver for each one.
browserModules

View File

@@ -67,10 +67,6 @@ class Port {
// Inject chrome API to the |context|
export function injectTo (extensionId: string, context: any) {
if (process.electronBinding('features').isExtensionsEnabled()) {
throw new Error('Attempted to load JS chrome-extension polyfill with //extensions support enabled')
}
const chrome = context.chrome = context.chrome || {}
ipcRendererInternal.on(`CHROME_RUNTIME_ONCONNECT_${extensionId}`, (
@@ -157,7 +153,7 @@ export function injectTo (extensionId: string, context: any) {
console.error('options are not supported')
}
ipcRendererInternal.invoke('CHROME_RUNTIME_SEND_MESSAGE', targetExtensionId, message).then(responseCallback)
ipcRendererUtils.invoke('CHROME_RUNTIME_SEND_MESSAGE', targetExtensionId, message).then(responseCallback)
},
onConnect: new Event(),
@@ -172,7 +168,7 @@ export function injectTo (extensionId: string, context: any) {
details: Chrome.Tabs.ExecuteScriptDetails,
resultCallback: Chrome.Tabs.ExecuteScriptCallback = () => {}
) {
ipcRendererInternal.invoke('CHROME_TABS_EXECUTE_SCRIPT', tabId, extensionId, details)
ipcRendererUtils.invoke('CHROME_TABS_EXECUTE_SCRIPT', tabId, extensionId, details)
.then((result: any) => resultCallback([result]))
},
@@ -183,7 +179,7 @@ export function injectTo (extensionId: string, context: any) {
_options: Chrome.Tabs.SendMessageDetails,
responseCallback: Chrome.Tabs.SendMessageCallback = () => {}
) {
ipcRendererInternal.invoke('CHROME_TABS_SEND_MESSAGE', tabId, extensionId, message).then(responseCallback)
ipcRendererUtils.invoke('CHROME_TABS_SEND_MESSAGE', tabId, extensionId, message).then(responseCallback)
},
onUpdated: new Event(),

View File

@@ -1,9 +1,9 @@
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'
const getStorage = (storageType: string, extensionId: number, callback: Function) => {
if (typeof callback !== 'function') throw new TypeError('No callback provided')
ipcRendererInternal.invoke<string>('CHROME_STORAGE_READ', storageType, extensionId)
ipcRendererUtils.invoke<string>('CHROME_STORAGE_READ', storageType, extensionId)
.then(data => {
if (data !== null) {
callback(JSON.parse(data))
@@ -17,7 +17,7 @@ const getStorage = (storageType: string, extensionId: number, callback: Function
const setStorage = (storageType: string, extensionId: number, storage: Record<string, any>, callback: Function) => {
const json = JSON.stringify(storage)
ipcRendererInternal.invoke('CHROME_STORAGE_WRITE', storageType, extensionId, json)
ipcRendererUtils.invoke('CHROME_STORAGE_WRITE', storageType, extensionId, json)
.then(() => {
if (callback) callback()
})

View File

@@ -1,16 +1,17 @@
import { Event } from '@electron/internal/renderer/extensions/event'
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
import { IpcMainEvent } from 'electron'
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal')
class WebNavigation {
private onBeforeNavigate = new Event()
private onCompleted = new Event()
constructor () {
ipcRendererInternal.on('CHROME_WEBNAVIGATION_ONBEFORENAVIGATE', (event: Electron.IpcRendererEvent, details: any) => {
ipcRendererInternal.on('CHROME_WEBNAVIGATION_ONBEFORENAVIGATE', (event: IpcMainEvent, details: any) => {
this.onBeforeNavigate.emit(details)
})
ipcRendererInternal.on('CHROME_WEBNAVIGATION_ONCOMPLETED', (event: Electron.IpcRendererEvent, details: any) => {
ipcRendererInternal.on('CHROME_WEBNAVIGATION_ONCOMPLETED', (event: IpcMainEvent, details: any) => {
this.onCompleted.emit(details)
})
}

View File

@@ -48,6 +48,7 @@ v8Util.setHiddenValue(global, 'ipcNative', {
onMessage (internal: boolean, channel: string, args: any[], senderId: number) {
const sender = internal ? ipcInternalEmitter : ipcEmitter
sender.emit(channel, { sender, senderId }, ...args)
process.activateUvLoop()
}
})
@@ -100,9 +101,7 @@ switch (window.location.protocol) {
}
case 'chrome-extension:': {
// Inject the chrome.* APIs that chrome extensions require
if (!process.electronBinding('features').isExtensionsEnabled()) {
require('@electron/internal/renderer/chrome-api').injectTo(window.location.hostname, window)
}
require('@electron/internal/renderer/chrome-api').injectTo(window.location.hostname, window)
break
}
case 'chrome:':
@@ -113,10 +112,8 @@ switch (window.location.protocol) {
windowSetup(guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen)
// Inject content scripts.
if (!process.electronBinding('features').isExtensionsEnabled()) {
const contentScripts = ipcRendererUtils.invokeSync('ELECTRON_GET_CONTENT_SCRIPTS') as Electron.ContentScriptEntry[]
require('@electron/internal/renderer/content-scripts-injector')(contentScripts)
}
const contentScripts = ipcRendererUtils.invokeSync('ELECTRON_GET_CONTENT_SCRIPTS') as Electron.ContentScriptEntry[]
require('@electron/internal/renderer/content-scripts-injector')(contentScripts)
}
}

View File

@@ -1,5 +1,4 @@
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'
import { invoke, invokeSync } from '@electron/internal/renderer/ipc-renderer-internal-utils'
window.onload = function () {
// Use menu API to show context menu.
@@ -20,7 +19,7 @@ function completeURL (project: string, path: string) {
// The DOM implementation expects (message?: string) => boolean
(window.confirm as any) = function (message: string, title: string) {
return ipcRendererUtils.invokeSync('ELECTRON_INSPECTOR_CONFIRM', message, title) as boolean
return invokeSync('ELECTRON_INSPECTOR_CONFIRM', message, title) as boolean
}
const useEditMenuItems = function (x: number, y: number, items: ContextMenuItem[]) {
@@ -33,7 +32,7 @@ const useEditMenuItems = function (x: number, y: number, items: ContextMenuItem[
const createMenu = function (x: number, y: number, items: ContextMenuItem[]) {
const isEditMenu = useEditMenuItems(x, y, items)
ipcRendererInternal.invoke<number>('ELECTRON_INSPECTOR_CONTEXT_MENU', items, isEditMenu).then(id => {
invoke<number>('ELECTRON_INSPECTOR_CONTEXT_MENU', items, isEditMenu).then(id => {
if (typeof id === 'number') {
window.DevToolsAPI!.contextMenuItemSelected(id)
}
@@ -42,7 +41,7 @@ const createMenu = function (x: number, y: number, items: ContextMenuItem[]) {
}
const showFileChooserDialog = function (callback: (blob: File) => void) {
ipcRendererInternal.invoke<[ string, any ]>('ELECTRON_INSPECTOR_SELECT_FILE').then(([path, data]) => {
invoke<[ string, any ]>('ELECTRON_INSPECTOR_SELECT_FILE').then(([path, data]) => {
if (path && data) {
callback(dataToHtml5FileObject(path, data))
}

View File

@@ -4,18 +4,38 @@ import * as errorUtils from '@electron/internal/common/error-utils'
type IPCHandler = (event: Electron.IpcRendererEvent, ...args: any[]) => any
export const handle = function <T extends IPCHandler> (channel: string, handler: T) {
ipcRendererInternal.on(channel, async (event, requestId, ...args) => {
const replyChannel = `${channel}_RESPONSE_${requestId}`
try {
event.sender.send(replyChannel, null, await handler(event, ...args))
} catch (error) {
event.sender.send(replyChannel, errorUtils.serialize(error))
}
ipcRendererInternal.on(channel, (event, requestId, ...args) => {
new Promise(resolve => resolve(handler(event, ...args))
).then(result => {
return [null, result]
}, error => {
return [errorUtils.serialize(error)]
}).then(responseArgs => {
event.sender.send(`${channel}_RESPONSE_${requestId}`, ...responseArgs)
})
})
}
let nextId = 0
export function invoke<T> (command: string, ...args: any[]) {
return new Promise<T>((resolve, reject) => {
const requestId = ++nextId
ipcRendererInternal.once(`${command}_RESPONSE_${requestId}`, (
_event, error: Electron.SerializedError, result: any
) => {
if (error) {
reject(errorUtils.deserialize(error))
} else {
resolve(result)
}
})
ipcRendererInternal.send(command, requestId, ...args)
})
}
export function invokeSync<T> (command: string, ...args: any[]): T {
const [ error, result ] = ipcRendererInternal.sendSync(command, ...args)
const [ error, result ] = ipcRendererInternal.sendSync(command, null, ...args)
if (error) {
throw errorUtils.deserialize(error)

View File

@@ -1,30 +1,22 @@
const { ipc } = process.electronBinding('ipc')
const binding = process.electronBinding('ipc')
const v8Util = process.electronBinding('v8_util')
// Created by init.js.
export const ipcRendererInternal = v8Util.getHiddenValue<Electron.IpcRendererInternal>(global, 'ipc-internal')
export const ipcRendererInternal: Electron.IpcRendererInternal = v8Util.getHiddenValue(global, 'ipc-internal')
const internal = true
ipcRendererInternal.send = function (channel, ...args) {
return ipc.send(internal, channel, args)
return binding.ipc.send(internal, channel, args)
}
ipcRendererInternal.sendSync = function (channel, ...args) {
return ipc.sendSync(internal, channel, args)[0]
return binding.ipc.sendSync(internal, channel, args)[0]
}
ipcRendererInternal.sendTo = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, false, webContentsId, channel, args)
return binding.ipc.sendTo(internal, false, webContentsId, channel, args)
}
ipcRendererInternal.sendToAll = function (webContentsId, channel, ...args) {
return ipc.sendTo(internal, true, webContentsId, channel, args)
}
ipcRendererInternal.invoke = async function<T> (channel: string, ...args: any[]) {
const { error, result } = await ipc.invoke<T>(internal, channel, args)
if (error) {
throw new Error(`Error invoking remote method '${channel}': ${error}`)
}
return result
return binding.ipc.sendTo(internal, true, webContentsId, channel, args)
}

View File

@@ -1,5 +1,5 @@
import { webFrame } from 'electron'
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
import { invoke } from '@electron/internal/renderer/ipc-renderer-internal-utils'
let shouldLog: boolean | null = null
@@ -299,7 +299,7 @@ const logSecurityWarnings = function (
const getWebPreferences = async function () {
try {
return ipcRendererInternal.invoke<Electron.WebPreferences>('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES')
return invoke<Electron.WebPreferences>('ELECTRON_BROWSER_GET_LAST_WEB_PREFERENCES')
} catch (error) {
console.warn(`getLastWebPreferences() failed: ${error}`)
}

View File

@@ -1,6 +1,6 @@
import { webFrame, IpcMessageEvent } from 'electron'
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'
import { invoke, invokeSync } from '@electron/internal/renderer/ipc-renderer-internal-utils'
import { WebViewImpl } from '@electron/internal/renderer/web-view/web-view-impl'
@@ -93,11 +93,11 @@ export function deregisterEvents (viewInstanceId: number) {
}
export function createGuest (params: Record<string, any>): Promise<number> {
return ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params)
return invoke('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params)
}
export function createGuestSync (params: Record<string, any>): number {
return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params)
return invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params)
}
export function attachGuest (
@@ -107,7 +107,7 @@ export function attachGuest (
if (embedderFrameId < 0) { // this error should not happen.
throw new Error('Invalid embedder frame')
}
ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', embedderFrameId, elementInstanceId, guestInstanceId, params)
invoke('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', embedderFrameId, elementInstanceId, guestInstanceId, params)
}
export const guestViewInternalModule = {

View File

@@ -1,4 +1,4 @@
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'
import { WebViewImpl } from '@electron/internal/renderer/web-view/web-view-impl'
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants'
@@ -196,7 +196,7 @@ class SrcAttribute extends WebViewAttribute {
const method = 'loadURL'
const args = [this.getValue(), opts]
ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', guestInstanceId, method, args)
ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', guestInstanceId, method, args)
}
}

View File

@@ -1,6 +1,5 @@
import { remote, webFrame } from 'electron'
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal'
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'
import * as guestViewInternal from '@electron/internal/renderer/web-view/guest-view-internal'
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants'
@@ -254,7 +253,7 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem
const createNonBlockHandler = function (method: string) {
return function (this: ElectronInternal.WebViewElement, ...args: Array<any>) {
return ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args)
return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args)
}
}

View File

@@ -106,7 +106,7 @@ class LocationProxy {
}
private _invokeWebContentsMethod (method: string, ...args: any[]) {
return ipcRendererInternal.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, method, ...args)
return ipcRendererUtils.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, method, ...args)
}
private _invokeWebContentsMethodSync (method: string, ...args: any[]) {
@@ -158,7 +158,7 @@ class BrowserWindowProxy {
}
public postMessage (message: any, targetOrigin: string) {
ipcRendererInternal.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, toString(targetOrigin), window.location.origin)
ipcRendererUtils.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, toString(targetOrigin), window.location.origin)
}
public eval (code: string) {
@@ -166,11 +166,11 @@ class BrowserWindowProxy {
}
private _invokeWindowMethod (method: string, ...args: any[]) {
return ipcRendererInternal.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, method, ...args)
return ipcRendererUtils.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, method, ...args)
}
private _invokeWebContentsMethod (method: string, ...args: any[]) {
return ipcRendererInternal.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, method, ...args)
return ipcRendererUtils.invoke('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, method, ...args)
}
}

View File

@@ -0,0 +1,25 @@
'use strict'
const moduleList = require('@electron/internal/sandboxed_renderer/api/module-list')
const handleESModule = (m) => {
// Handle Typescript modules with an "export default X" statement
if (m.__esModule && m.default) return m.default
return m
}
for (const {
name,
load,
enabled = true,
private: isPrivate = false
} of moduleList) {
if (!enabled) {
continue
}
Object.defineProperty(exports, name, {
enumerable: !isPrivate,
get: () => handleESModule(load())
})
}

View File

@@ -1,4 +0,0 @@
import { defineProperties } from '@electron/internal/common/define-properties'
import { moduleList } from '@electron/internal/sandboxed_renderer/api/module-list'
defineProperties(exports, moduleList)

View File

@@ -0,0 +1,38 @@
'use strict'
const features = process.electronBinding('features')
module.exports = [
{
name: 'crashReporter',
load: () => require('@electron/internal/renderer/api/crash-reporter')
},
{
name: 'desktopCapturer',
load: () => require('@electron/internal/renderer/api/desktop-capturer'),
enabled: features.isDesktopCapturerEnabled()
},
{
name: 'ipcRenderer',
load: () => require('@electron/internal/renderer/api/ipc-renderer')
},
{
name: 'nativeImage',
load: () => require('@electron/internal/common/api/native-image')
},
{
name: 'remote',
load: () => require('@electron/internal/renderer/api/remote'),
enabled: process.isRemoteModuleEnabled
},
{
name: 'webFrame',
load: () => require('@electron/internal/renderer/api/web-frame')
},
// The internal modules, invisible unless you know their names.
{
name: 'deprecate',
load: () => require('@electron/internal/common/api/deprecate'),
private: true
}
]

View File

@@ -1,40 +0,0 @@
const features = process.electronBinding('features')
export const moduleList: ElectronInternal.ModuleEntry[] = [
{
name: 'crashReporter',
loader: () => require('@electron/internal/renderer/api/crash-reporter')
},
{
name: 'ipcRenderer',
loader: () => require('@electron/internal/renderer/api/ipc-renderer')
},
{
name: 'nativeImage',
loader: () => require('@electron/internal/common/api/native-image')
},
{
name: 'webFrame',
loader: () => require('@electron/internal/renderer/api/web-frame')
},
// The internal modules, invisible unless you know their names.
{
name: 'deprecate',
loader: () => require('@electron/internal/common/api/deprecate'),
private: true
}
]
if (features.isDesktopCapturerEnabled()) {
moduleList.push({
name: 'desktopCapturer',
loader: () => require('@electron/internal/renderer/api/desktop-capturer')
})
}
if (process.isRemoteModuleEnabled) {
moduleList.push({
name: 'remote',
loader: () => require('@electron/internal/renderer/api/remote')
})
}

View File

@@ -11,10 +11,10 @@ const v8Util = process.electronBinding('v8_util')
// Expose Buffer shim as a hidden value. This is used by C++ code to
// deserialize Buffer instances sent from browser process.
v8Util.setHiddenValue(global, 'Buffer', Buffer)
// The `lib/renderer/api/ipc-renderer.ts` module looks for the ipc object in the
// The `lib/renderer/api/ipc-renderer.js` module looks for the ipc object in the
// "ipc" hidden value
v8Util.setHiddenValue(global, 'ipc', new EventEmitter())
// The `lib/renderer/ipc-renderer-internal.ts` module looks for the ipc object in the
// The `lib/renderer/ipc-renderer-internal.js` module looks for the ipc object in the
// "ipc-internal" hidden value
v8Util.setHiddenValue(global, 'ipc-internal', new EventEmitter())
// The process object created by webpack is not an event emitter, fix it so
@@ -116,9 +116,7 @@ switch (window.location.protocol) {
}
case 'chrome-extension:': {
// Inject the chrome.* APIs that chrome extensions require
if (!process.electronBinding('features').isExtensionsEnabled()) {
require('@electron/internal/renderer/chrome-api').injectTo(window.location.hostname, window)
}
require('@electron/internal/renderer/chrome-api').injectTo(window.location.hostname, window)
break
}
case 'chrome': {
@@ -126,9 +124,7 @@ switch (window.location.protocol) {
}
default: {
// Inject content scripts.
if (!process.electronBinding('features').isExtensionsEnabled()) {
require('@electron/internal/renderer/content-scripts-injector')(contentScripts)
}
require('@electron/internal/renderer/content-scripts-injector')(contentScripts)
}
}

View File

@@ -24,12 +24,16 @@ std::string V8TypeAsString(v8::Isolate* isolate, v8::Local<v8::Value> value) {
} // namespace
Arguments::Arguments() = default;
Arguments::Arguments()
: isolate_(NULL), info_(NULL), next_(0), insufficient_arguments_(false) {}
Arguments::Arguments(const v8::FunctionCallbackInfo<v8::Value>& info)
: isolate_(info.GetIsolate()), info_(&info) {}
: isolate_(info.GetIsolate()),
info_(&info),
next_(0),
insufficient_arguments_(false) {}
Arguments::~Arguments() = default;
Arguments::~Arguments() {}
v8::Local<v8::Value> Arguments::PeekNext() const {
if (next_ >= info_->Length())

View File

@@ -9,7 +9,6 @@
#include <vector>
#include "base/macros.h"
#include "base/optional.h"
#include "native_mate/converter.h"
namespace mate {
@@ -35,17 +34,6 @@ class Arguments {
return ConvertFromV8(isolate_, info_->Data(), out);
}
template <typename T>
bool GetNext(base::Optional<T>* out) {
if (next_ >= info_->Length())
return true;
v8::Local<v8::Value> val = (*info_)[next_];
bool success = ConvertFromV8(isolate_, val, out);
if (success)
next_++;
return success;
}
template <typename T>
bool GetNext(T* out) {
if (next_ >= info_->Length()) {
@@ -95,10 +83,10 @@ class Arguments {
v8::Isolate* isolate() const { return isolate_; }
private:
v8::Isolate* isolate_ = nullptr;
const v8::FunctionCallbackInfo<v8::Value>* info_ = nullptr;
int next_ = 0;
bool insufficient_arguments_ = false;
v8::Isolate* isolate_;
const v8::FunctionCallbackInfo<v8::Value>* info_;
int next_;
bool insufficient_arguments_;
};
} // namespace mate

View File

@@ -6,7 +6,7 @@
namespace mate {
Dictionary::Dictionary() = default;
Dictionary::Dictionary() : isolate_(NULL) {}
Dictionary::Dictionary(v8::Isolate* isolate, v8::Local<v8::Object> object)
: isolate_(isolate), object_(object) {}

View File

@@ -125,7 +125,7 @@ class Dictionary {
v8::Isolate* isolate() const { return isolate_; }
protected:
v8::Isolate* isolate_ = nullptr;
v8::Isolate* isolate_;
private:
v8::Local<v8::Object> object_;

View File

@@ -5,8 +5,6 @@
#ifndef NATIVE_MATE_NATIVE_MATE_FUNCTION_TEMPLATE_H_
#define NATIVE_MATE_NATIVE_MATE_FUNCTION_TEMPLATE_H_
#include "../shell/common/error_util.h"
#include "../shell/common/gin_helper/destroyable.h"
#include "base/callback.h"
#include "base/logging.h"
#include "native_mate/arguments.h"
@@ -21,6 +19,23 @@ enum CreateFunctionTemplateFlags {
namespace internal {
struct Destroyable {
static void Destroy(Arguments* args) {
if (IsDestroyed(args))
return;
v8::Local<v8::Object> holder = args->GetHolder();
delete static_cast<WrappableBase*>(
holder->GetAlignedPointerFromInternalField(0));
holder->SetAlignedPointerInInternalField(0, nullptr);
}
static bool IsDestroyed(Arguments* args) {
v8::Local<v8::Object> holder = args->GetHolder();
return holder->InternalFieldCount() == 0 ||
holder->GetAlignedPointerFromInternalField(0) == nullptr;
}
};
template <typename T>
struct CallbackParamTraits {
typedef T LocalType;
@@ -67,10 +82,10 @@ class CallbackHolder : public CallbackHolderBase {
int flags)
: CallbackHolderBase(isolate), callback(callback), flags(flags) {}
base::Callback<Sig> callback;
int flags = 0;
int flags;
private:
virtual ~CallbackHolder() = default;
virtual ~CallbackHolder() {}
DISALLOW_COPY_AND_ASSIGN(CallbackHolder);
};
@@ -113,16 +128,6 @@ inline bool GetNextArgument(Arguments* args,
return true;
}
// Allow clients to pass a util::Error to throw errors if they
// don't need the full mate::Arguments
inline bool GetNextArgument(Arguments* args,
int create_flags,
bool is_first,
electron::util::ErrorThrower* result) {
*result = electron::util::ErrorThrower(args->isolate());
return true;
}
// Classes for generating and storing an argument pack of integer indices
// (based on well-known "indices trick", see: http://goo.gl/bKKojn):
template <size_t... indices>
@@ -146,11 +151,11 @@ struct ArgumentHolder {
using ArgLocalType = typename CallbackParamTraits<ArgType>::LocalType;
ArgLocalType value;
bool ok = false;
bool ok;
ArgumentHolder(Arguments* args, int create_flags) {
ArgumentHolder(Arguments* args, int create_flags) : ok(false) {
if (index == 0 && (create_flags & HolderIsFirstArgument) &&
gin_helper::Destroyable::IsDestroyed(args->GetHolder())) {
Destroyable::IsDestroyed(args)) {
args->ThrowError("Object has been destroyed");
return;
}

View File

@@ -16,7 +16,7 @@ namespace mate {
template <typename T>
class Handle {
public:
Handle() = default;
Handle() : object_(NULL) {}
Handle(v8::Local<v8::Object> wrapper, T* object)
: wrapper_(wrapper), object_(object) {}
@@ -34,7 +34,7 @@ class Handle {
private:
v8::Local<v8::Object> wrapper_;
T* object_ = nullptr;
T* object_;
};
template <typename T>

View File

@@ -11,7 +11,7 @@ ObjectTemplateBuilder::ObjectTemplateBuilder(
v8::Local<v8::ObjectTemplate> templ)
: isolate_(isolate), template_(templ) {}
ObjectTemplateBuilder::~ObjectTemplateBuilder() = default;
ObjectTemplateBuilder::~ObjectTemplateBuilder() {}
ObjectTemplateBuilder& ObjectTemplateBuilder::SetImpl(base::StringPiece name,
v8::Local<v8::Data> val) {
@@ -28,6 +28,12 @@ ObjectTemplateBuilder& ObjectTemplateBuilder::SetPropertyImpl(
return *this;
}
ObjectTemplateBuilder& ObjectTemplateBuilder::MakeDestroyable() {
SetMethod("destroy", base::Bind(internal::Destroyable::Destroy));
SetMethod("isDestroyed", base::Bind(internal::Destroyable::IsDestroyed));
return *this;
}
v8::Local<v8::ObjectTemplate> ObjectTemplateBuilder::Build() {
v8::Local<v8::ObjectTemplate> result = template_;
template_.Clear();

View File

@@ -99,6 +99,9 @@ class ObjectTemplateBuilder {
CallbackTraits<U>::CreateTemplate(isolate_, setter));
}
// Add "destroy" and "isDestroyed" methods.
ObjectTemplateBuilder& MakeDestroyable();
v8::Local<v8::ObjectTemplate> Build();
private:

View File

@@ -6,7 +6,7 @@
namespace mate {
PersistentDictionary::PersistentDictionary() = default;
PersistentDictionary::PersistentDictionary() {}
PersistentDictionary::PersistentDictionary(v8::Isolate* isolate,
v8::Local<v8::Object> object)
@@ -17,7 +17,7 @@ PersistentDictionary::PersistentDictionary(v8::Isolate* isolate,
PersistentDictionary::PersistentDictionary(const PersistentDictionary& other) =
default;
PersistentDictionary::~PersistentDictionary() = default;
PersistentDictionary::~PersistentDictionary() {}
v8::Local<v8::Object> PersistentDictionary::GetHandle() const {
return handle_->NewHandle();

View File

@@ -6,13 +6,13 @@
namespace mate {
Promise::Promise() = default;
Promise::Promise() : isolate_(NULL) {}
Promise::Promise(v8::Isolate* isolate) : isolate_(isolate) {
resolver_ = v8::Promise::Resolver::New(isolate);
}
Promise::~Promise() = default;
Promise::~Promise() {}
Promise Promise::Create(v8::Isolate* isolate) {
return Promise(isolate);

View File

@@ -37,7 +37,7 @@ class Promise {
void RejectWithErrorMessage(const std::string& error);
protected:
v8::Isolate* isolate_ = nullptr;
v8::Isolate* isolate_;
private:
v8::Local<v8::Promise::Resolver> resolver_;

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