Compare commits

..

42 Commits

Author SHA1 Message Date
Sudowoodo Release Bot
605ee9e28a Bump v21.0.0-beta.3 2022-09-06 15:03:08 -07:00
Samuel Attard
e48878ea63 chore: cherry-pick 9b5207569882 from chromium (#35543)
* chore: cherry-pick 9b5207569882 from chromium

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2022-09-06 10:27:46 -07:00
trop[bot]
e78aa6af16 fix: screen.getCursorScreenPoint() crash on Wayland (#35575)
fix: screen.getCursorScreenPoint() crash on Wayland

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-09-06 12:18:03 -04:00
Sudowoodo Release Bot
fb0bbf0100 Bump v21.0.0-beta.2 2022-09-01 06:31:01 -07:00
trop[bot]
5e8b4bd86f fix: crash when switching origins with emulation settings set (#35488)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-08-31 11:20:10 +09:00
Sudowoodo Release Bot
da47103ad7 Bump v21.0.0-beta.1 2022-08-30 10:11:56 -07:00
trop[bot]
7b62386296 fix: crash on WebWorker destruction (#35492)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-08-30 13:58:28 +02:00
trop[bot]
018bc0993e chore: use nghttp2's config.h on all platforms (#35487)
https://github.com/nodejs/node/pull/27283

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-08-30 10:57:32 +02:00
Sudowoodo Release Bot
f9b02358c6 Bump v21.0.0-alpha.6 2022-08-29 15:51:14 -07:00
trop[bot]
23aa6e5084 build: update libcxx filenames (#35497)
* build: update libcxx filenames

* build: change upload_to_storage variable

Co-authored-by: VerteDinde <vertedinde@electronjs.org>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2022-08-29 15:50:06 -07:00
Sudowoodo Release Bot
65a2c18560 Revert "Bump v21.0.0-alpha.6"
This reverts commit c8b3e23f31.
2022-08-29 10:36:52 -07:00
Sudowoodo Release Bot
c8b3e23f31 Bump v21.0.0-alpha.6 2022-08-29 09:19:34 -07:00
trop[bot]
4ab9295e62 chore: delete implicit fallthrough patch (#35469)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-08-29 15:25:38 +02:00
trop[bot]
0e79733404 docs: update docs description to match sidebar (#35482)
Update introduction.md

Co-authored-by: Nik K <nk@nikk.ca>
2022-08-29 12:28:21 +02:00
trop[bot]
38d408a26b fix: pass rfh instances through to the permission helper (#35467)
* fix: pass rfh instances through to the permission helper

* refactor: use WeakDocumentPtr instead of frame node id

* fix: handle missing initiator document

* fix: dispatch openExternal event for top level webview navs still

Co-authored-by: Samuel Attard <sattard@salesforce.com>
2022-08-29 09:52:53 +02:00
trop[bot]
0ad176fd13 fix: fullscreen crashing with roundedCorners: false (#35454)
fix: fullscreen crashing with roundedCorners

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-08-25 15:52:24 +02:00
trop[bot]
a3cfd1a206 fix: Node.js atob input validation (#35443)
fix: Node.js atob input validation

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-08-25 15:08:20 +02:00
trop[bot]
63fe34c703 build: fix export patches to work when source directory does not exist (#35437)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-08-25 10:18:11 +09:00
trop[bot]
c99a52eab4 chore: bump chromium to 106.0.5216.0 (21-x-y) (#35363)
* chore: bump chromium to 106.0.5216.0 (main) (#34993)

* Trigger Build

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-08-23 15:22:47 -04:00
trop[bot]
95eb6ea772 fix: undefined details.requestingUrl from session.setPermissionCheckHandler (#35409)
fix: undefined details.requestingUrl from setPermissionCheckHandler

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2022-08-23 10:27:14 -04:00
trop[bot]
8d6c29ecbc fix: add restore event for minimized maximization (#35410)
Co-authored-by: mlaurencin <mlaurencin@electronjs.org>
2022-08-23 14:39:46 +02:00
trop[bot]
637824e086 fix: promise support with webFrameMain.executeJavaScript (#35359)
* fix: promise support with webFrameMain.executeJavaScript

* chore: reject when result is an error

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2022-08-23 11:39:59 +02:00
trop[bot]
cb6fa8268f fix: ensure chrome colors are initialized (#35401)
* fix: ensure chrome colors are initialized

* build: fix linking on windows

* build: fix linking on windows

* build: add needed files to chromium_src/BUILD

Co-authored-by: Samuel Attard <sattard@salesforce.com>
Co-authored-by: VerteDinde <keeleymhammond@gmail.com>
2022-08-23 11:19:32 +02:00
Sudowoodo Release Bot
76e8536ca8 Bump v21.0.0-alpha.5 2022-08-22 16:25:16 -07:00
trop[bot]
b075434447 fix: IPC emit order in -ipc-ports handler (#35364)
Co-authored-by: Milan Burda <miburda@microsoft.com>
2022-08-18 18:00:45 -07:00
Sudowoodo Release Bot
9673d29ebe Bump v21.0.0-alpha.4 2022-08-18 12:05:12 -07:00
trop[bot]
5e6d152231 fix: don't bypass redirect checks (#35366)
Co-authored-by: Jeremy Rose <japthorp@slack-corp.com>
2022-08-18 10:09:18 -07:00
trop[bot]
b31a4b4394 fix: Frameless window shows frame while opening (#35353)
* fix: Frameless window shows frame while opening

* Clarify comments

* Inline setter

* Edit comment

Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>
2022-08-17 15:20:20 -07:00
trop[bot]
28ca18a912 feat: add WebContents.ipc (#35231)
feat: add WebContents.ipc (#34959)

Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2022-08-17 09:50:15 -07:00
trop[bot]
8caea9006a fix: add uv_loop_close when object release to fix crash (#35336)
Co-authored-by: yangzuohui <yangzuohui@bytedance.com>
2022-08-16 17:03:05 +09:00
trop[bot]
855536bcb9 refactor: simplify Browser::SetLoginItemSettings (#35329)
refactor: simplify Browser::SetLoginItemSettings

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-08-15 16:43:48 -04:00
trop[bot]
1978a0b5fe fix: serialPort.open() failing (#35339)
fix: serialPort.open() failing

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2022-08-15 13:53:00 -04:00
Sudowoodo Release Bot
fe70152b43 Bump v21.0.0-alpha.3 2022-08-15 08:42:41 -07:00
trop[bot]
9b38a25206 docs: add Electron deps to license credits file (#35332)
* docs: add Electron deps to license credits file

* fixup! docs: add Electron deps to license credits file

remove nan; it is dev-only

Co-authored-by: Charles Kerr <charles@charleskerr.com>
2022-08-15 10:42:39 -04:00
trop[bot]
a66d3bf206 docs: removes unused import in preload script (#35334)
* Remove unused import of path

This import gives out the error in the preload script:

Error: module not found: path
    at preloadRequire

* Remove import path as it is not used in the script

note: Removes import path as it is not used in the script

Co-authored-by: Rhitik Bhatt <bhattrhitik95@gmail.com>
2022-08-15 17:06:50 +09:00
Sudowoodo Release Bot
752b10f16f Bump v21.0.0-alpha.2 2022-08-11 09:37:32 -07:00
trop[bot]
5803a67963 docs: fix getStoragePath return type (#35296)
Fixes #35255

Co-authored-by: Samuel Attard <sam@electronjs.org>
2022-08-10 22:42:17 +02:00
trop[bot]
40058af821 fix(docs): fix a typo in section on debugging with VSCode (#35285)
fix(docs): fix a typo

Co-authored-by: Trang Le <trang.thule@zoho.com>
2022-08-09 15:30:29 -07:00
trop[bot]
64b40ea69c docs: update tray docs with info for mac menubar icons (#35221)
Co-authored-by: Brad Carter <16466430+carterbs@users.noreply.github.com>
2022-08-09 09:01:10 +09:00
trop[bot]
7c6e16975f fix: app.relaunch loses args when execPath specified (#35254)
fix: app.relaunch loses args when execPath specified (#35108)

Co-authored-by: Aaron Meriwether <me@ameriwether.com>
2022-08-09 08:54:58 +09:00
trop[bot]
c9e7f33f7e test: temporarily disable tests on mas arm64 that are causing a crash (#35247)
* test: temporarily disable test on mas arm64 that is causing crash

* disable the right test

* chore: speculative fix for CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER crash

* enable all the tests

* Revert "chore: speculative fix for CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER crash"

This reverts commit b7c8ef364c.

* test: disable tests that crash on mas arm64

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2022-08-08 10:02:58 -04:00
Sudowoodo Release Bot
98aa0ef090 Bump v21.0.0-alpha.1 2022-08-03 07:37:56 -07:00
762 changed files with 12496 additions and 12258 deletions

View File

@@ -216,7 +216,6 @@ step-maybe-cleanup-arm64-mac: &step-maybe-cleanup-arm64-mac
rm -rf ~/Library/Application\ Support/electron*
security delete-generic-password -l "Chromium Safe Storage" || echo "✓ Keychain does not contain password from tests"
security delete-generic-password -l "Electron Test Main Safe Storage" || echo "✓ Keychain does not contain password from tests"
security delete-generic-password -a "electron-test-safe-storage" || echo "✓ Keychain does not contain password from tests"
elif [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
XVFB=/usr/bin/Xvfb
/sbin/start-stop-daemon --stop --exec $XVFB || echo "Xvfb not running"
@@ -992,7 +991,7 @@ step-ts-compile: &step-ts-compile
do
out="${f:29}"
if [ "$out" != "base.js" ]; then
node script/yarn webpack --config $f --output-filename=$out --output-path=./.tmp --env mode=development
node script/yarn webpack --config $f --output-filename=$out --output-path=./.tmp --env.mode=development
fi
done
@@ -1061,16 +1060,19 @@ steps-tests: &steps-tests
export LLVM_SYMBOLIZER_PATH=$PWD/third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer
export MOCHA_TIMEOUT=180000
echo "Piping output to ASAN_SYMBOLIZE ($ASAN_SYMBOLIZE)"
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.ts | circleci tests split --split-by=timings)) 2>&1 | $ASAN_SYMBOLIZE
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec-main/*-spec.ts | circleci tests split --split-by=timings)) 2>&1 | $ASAN_SYMBOLIZE
(cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.js | circleci tests split --split-by=timings)) 2>&1 | $ASAN_SYMBOLIZE
else
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
export ELECTRON_SKIP_NATIVE_MODULE_TESTS=true
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging)
(cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging)
else
if [ "$TARGET_ARCH" == "ia32" ]; then
npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js
fi
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.ts | circleci tests split --split-by=timings))
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec-main/*-spec.ts | circleci tests split --split-by=timings))
(cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.js | circleci tests split --split-by=timings))
fi
fi
- run:
@@ -1079,6 +1081,9 @@ steps-tests: &steps-tests
cd src
# Check if test results exist and are not empty.
if [ ! -s "junit/test-results-remote.xml" ]; then
exit 1
fi
if [ ! -s "junit/test-results-main.xml" ]; then
exit 1
fi

2
.github/CODEOWNERS vendored
View File

@@ -4,7 +4,7 @@
# https://git-scm.com/docs/gitignore
# Upgrades WG
/patches/ @electron/patch-owners
/patches/ @electron/wg-upgrades @electron/wg-security
DEPS @electron/wg-upgrades
# Releases WG

2
.github/semantic.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
# Always validate the PR title, and ignore the commits
titleOnly: true

14
.github/stale.yml vendored
View File

@@ -1,14 +0,0 @@
daysUntilStale: 90
daysUntilClose: 30
exemptLabels:
- discussion
- security 🔒
- "enhancement :sparkles:"
staleLabel: stale
markComment: >
This issue has been automatically marked as stale. **If this issue is still affecting you, please leave any comment** (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the [latest version of Electron](https://www.electronjs.org/releases/stable) or in the [beta](https://www.electronjs.org/releases/beta)—please include it with your comment!
closeComment: >
This issue has been closed as it was considered stale, this issue will not be
monitored. If this is a bug and you can reproduce this issue on a [supported
version of Electron](https://www.electronjs.org/docs/latest/tutorial/electron-timelines#timeline) please open a new issue and ensure a repro is provided.

View File

@@ -117,6 +117,21 @@ jobs:
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
MOCHA_REPORTER: mocha-multi-reporters
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
- name: Run Electron Remote based tests
if: ${{ success() || failure() }}
run: |
cd src
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
set npm_config_arch=arm64
cd electron
node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion
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
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
- name: Verify ffmpeg
run: |
cd src

View File

@@ -1,24 +0,0 @@
name: Issue Labeled
on:
issues:
types: [labeled]
jobs:
issue-labeled:
runs-on: ubuntu-latest
steps:
- name: blocked/need-repro
if: github.event.label.name == 'blocked/need-repro'
uses: actions-cool/issues-helper@dad28fdb88da5f082c04659b7373d85790f9b135 # v3.3.0
with:
actions: 'create-comment'
body: |
Hello @${{ github.event.issue.user.login }}. Thanks for reporting this and helping to make Electron better!
Would it be possible for you to make a standalone testcase with only the code necessary to reproduce the issue? For example, [Electron Fiddle](https://www.electronjs.org/fiddle) is a great tool for making small test cases and makes it easy to publish your test case to a [gist](https://gist.github.com) that Electron maintainers can use.
Stand-alone test cases make fixing issues go more smoothly: it ensure everyone's looking at the same issue, it removes all unnecessary variables from the equation, and it can also provide the basis for automated regression tests.
Now adding the `blocked/need-repro` label for this reason. After you make a test case, please link to it in a followup comment. This issue will be closed in 10 days if the above is not addressed.

View File

@@ -14,13 +14,13 @@ jobs:
- uses: actions/checkout@v3
- name: Check Tag
run: |
if [[ ${{ github.event.release.tag_name }} =~ ^v[0-9]+\.0\.0$ ]]; then
if [[ ${{ github.event.ref }} =~ ^refs/tags/v[0-9]+\.0\.0$ ]]; then
echo ::set-output name=should_release::true
fi
trigger:
runs-on: ubuntu-latest
needs: check_tag
if: needs.check_tag.outputs.should_release == 'true'
if: jobs.check_tag.outputs.should_release == 'true'
steps:
- uses: actions/checkout@v3
- name: Trigger New chromedriver Release

4
.gitignore vendored
View File

@@ -41,7 +41,7 @@ spec/.hash
.eslintcache*
# Generated native addon files
/spec/fixtures/native-addon/echo/build/
/spec-main/fixtures/native-addon/echo/build/
# If someone runs tsc this is where stuff will end up
ts-gen
@@ -53,4 +53,4 @@ ts-gen
# Used to accelerate builds after sync
patches/mtime-cache.json
spec/fixtures/logo.png
spec/fixtures/logo.png

2
.nvmrc
View File

@@ -1 +1 @@
16
14

View File

@@ -404,6 +404,9 @@ source_set("electron_lib") {
"//media/mojo/mojom",
"//net:extras",
"//net:net_resources",
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/shared_impl",
"//printing/buildflags",
"//services/device/public/cpp/geolocation",
"//services/device/public/cpp/hid",
@@ -622,14 +625,6 @@ source_set("electron_lib") {
]
}
if (enable_ppapi) {
deps += [
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/shared_impl",
]
}
if (enable_run_as_node) {
sources += [
"shell/app/node_main.cc",

4
DEPS
View File

@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'108.0.5329.0',
'106.0.5216.0',
'node_version':
'v16.17.1',
'v16.16.0',
'nan_version':
'16fa32231e2ccd89d2804b3f765319128b20c4ac',
'squirrel.mac_version':

View File

@@ -1 +1 @@
22.0.0-alpha.6
21.0.0-beta.3

View File

@@ -5,7 +5,7 @@
[![Electron Discord Invite](https://img.shields.io/discord/745037351163527189?color=%237289DA&label=chat&logo=discord&logoColor=white)](https://discord.gg/electronjs)
:memo: Available Translations: 🇨🇳 🇧🇷 🇪🇸 🇯🇵 🇷🇺 🇫🇷 🇺🇸 🇩🇪.
View these docs in other languages on our [Crowdin](https://crowdin.com/project/electron) project.
View these docs in other languages at [electron/i18n](https://github.com/electron/i18n/tree/master/content/).
The Electron framework lets you write cross-platform desktop applications
using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org/) and
@@ -38,7 +38,7 @@ For more installation options and troubleshooting tips, see
Each Electron release provides binaries for macOS, Windows, and Linux.
* macOS (High Sierra and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
* macOS (El Capitan and up): Electron provides 64-bit Intel and ARM binaries for macOS. Apple Silicon support was added in Electron 11.
* Windows (Windows 7 and up): Electron provides `ia32` (`x86`), `x64` (`amd64`), and `arm64` binaries for Windows. Windows on ARM support was added in Electron 5.0.8.
* Linux: The prebuilt binaries of Electron are built on Ubuntu 20.04. They have also been verified to work on:
* Ubuntu 14.04 and newer

View File

@@ -34,281 +34,213 @@ environment:
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
GOMA_FALLBACK_ON_AUTH_FAILURE: true
matrix:
- job_name: Build
- job_name: Test
job_depends_on: Build
clone_folder: C:\projects\src\electron
# the first failed job cancels other jobs and fails entire build
matrix:
fast_finish: true
for:
-
matrix:
only:
- job_name: Build
init:
- ps: >-
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
}
build_script:
- ps: |
build_script:
- ps: >-
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
} else {
node script/yarn.js install --frozen-lockfile
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
if ($LASTEXITCODE -eq 0) {
Write-warning "Skipping tests for doc only change"; Exit-AppveyorBuild
$result = node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
Write-Output $result
if ($result.ExitCode -eq 0) {
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
}
$global:LASTEXITCODE = 0
- cd ..
- ps: Write-Host "Building $env:GN_CONFIG build"
- git config --global core.longpaths true
- update_depot_tools.bat
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
- git clone https://github.com/electron/build-tools.git
- cd build-tools
- npm install
- mkdir third_party
- ps: >-
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
- cd ..\..
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
if ($goma_login -eq 'Login as Fermi Planck') {
Write-warning "Goma authentication is correct";
} else {
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
$host.SetShouldExit(1)
}
}
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
- ps: >-
if ($env:GN_CONFIG -ne 'release') {
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
}
- >-
gclient config
--name "src\electron"
--unmanaged
%GCLIENT_EXTRA_ARGS%
"https://github.com/electron/electron"
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
$env:RUN_GCLIENT_SYNC="true"
}
- echo "Building $env:GN_CONFIG build"
- git config --global core.longpaths true
- cd ..
- mkdir src
- update_depot_tools.bat
- ps: Move-Item $env:APPVEYOR_BUILD_FOLDER -Destination src\electron
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
- git clone https://github.com/electron/build-tools.git
- cd build-tools
- npm install
- mkdir third_party
- ps: >-
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
- ps: $env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
- ps: $env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
- cd ..
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
- ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') {
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
if ($goma_login -eq 'Login as Fermi Planck') {
Write-warning "Goma authentication is correct";
} else {
cd src\electron
node script\generate-deps-hash.js
$depshash = Get-Content .\.depshash -Raw
$zipfile = "Z:\$depshash.7z"
cd ..\..
if (Test-Path -Path $zipfile) {
# file exists, unzip and then gclient sync
7z x -y $zipfile -mmt=14 -aoa
if (-not (Test-Path -Path "src\buildtools")) {
# the zip file must be corrupt - resync
$env:RUN_GCLIENT_SYNC="true"
if ($env:TARGET_ARCH -ne 'ia32') {
# only save on x64/woa to avoid contention saving
$env:SAVE_GCLIENT_SRC="true"
}
} else {
# update angle
cd src\third_party\angle
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
git fetch
cd ..\..\..
}
} else {
# file does not exist, gclient sync, then zip
Write-warning "WARNING!!!!!! Goma authentication is incorrect; please update Goma auth token.";
$host.SetShouldExit(1)
}
}
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
- ps: >-
if ($env:GN_CONFIG -ne 'release') {
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
}
- >-
gclient config
--name "src\electron"
--unmanaged
%GCLIENT_EXTRA_ARGS%
"https://github.com/electron/electron"
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
$env:RUN_GCLIENT_SYNC="true"
} else {
cd src\electron
node script\generate-deps-hash.js
$depshash = Get-Content .\.depshash -Raw
$zipfile = "Z:\$depshash.7z"
cd ..\..
if (Test-Path -Path $zipfile) {
# file exists, unzip and then gclient sync
7z x -y $zipfile -mmt=30 -aoa
if (-not (Test-Path -Path "src\buildtools")) {
# the zip file must be corrupt - resync
$env:RUN_GCLIENT_SYNC="true"
if ($env:TARGET_ARCH -ne 'ia32') {
# only save on x64/woa to avoid contention saving
$env:SAVE_GCLIENT_SRC="true"
}
} else {
# update angle
cd src\third_party\angle
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
git fetch
cd ..\..\..
}
} else {
# file does not exist, gclient sync, then zip
$env:RUN_GCLIENT_SYNC="true"
if ($env:TARGET_ARCH -ne 'ia32') {
# only save on x64/woa to avoid contention saving
$env:SAVE_GCLIENT_SRC="true"
}
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync )
- ps: >-
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
# archive current source for future use
# only run on x64/woa to avoid contention saving
$(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30)
if ($LASTEXITCODE -ne 0) {
Write-warning "Could not save source to shared drive; continuing anyway"
}
# build time generation of file gen/angle/angle_commit.h depends on
# third_party/angle/.git
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
$(7z a $zipfile src\third_party\angle\.git)
if ($LASTEXITCODE -ne 0) {
Write-warning "Failed to add third_party\angle\.git; continuing anyway"
}
# build time generation of file dawn/common/Version_autogen.h depends on third_party/dawn/.git/HEAD
# https://dawn-review.googlesource.com/c/dawn/+/83901
$(7z a $zipfile src\third_party\dawn\.git)
if ($LASTEXITCODE -ne 0) {
Write-warning "Failed to add third_party\dawn\.git; continuing anyway"
}
}
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync )
- ps: >-
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
# archive current source for future use
# only run on x64/woa to avoid contention saving
$(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30)
if ($LASTEXITCODE -ne 0) {
Write-warning "Could not save source to shared drive; continuing anyway"
}
- cd src
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
- gn check out/Default //electron:electron_lib
- gn check out/Default //electron:electron_app
- gn check out/Default //electron/shell/common/api:mojo
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
- ninja -C out/Default electron:electron_dist_zip
- ninja -C out/Default shell_browser_ui_unittests
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
- ninja -C out/Default electron:electron_mksnapshot_zip
- cd out\Default
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
- cd ..\..
- ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
- 7z a node_headers.zip out\Default\gen\node_headers
- 7z a builtins-pgo.zip v8\tools\builtins-pgo
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
ninja -C out/Default electron:electron_symbols
# build time generation of file gen/angle/angle_commit.h depends on
# third_party/angle/.git
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
$(7z a $zipfile src\third_party\angle\.git)
if ($LASTEXITCODE -ne 0) {
Write-warning "Failed to add third_party\angle\.git; continuing anyway"
}
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python electron\script\zip-symbols.py
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
# build time generation of file dawn/common/Version_autogen.h depends on third_party/dawn/.git/HEAD
# https://dawn-review.googlesource.com/c/dawn/+/83901
$(7z a $zipfile src\third_party\dawn\.git)
if ($LASTEXITCODE -ne 0) {
Write-warning "Failed to add third_party\dawn\.git; continuing anyway"
}
}
- cd src
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% "
- gn check out/Default //electron:electron_lib
- gn check out/Default //electron:electron_app
- gn check out/Default //electron/shell/common/api:mojo
- if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip
- ninja -C out/Default electron:electron_dist_zip
- ninja -C out/Default shell_browser_ui_unittests
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
- ninja -C out/Default electron:electron_mksnapshot_zip
- cd out\Default
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
- cd ..\..
- ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
- 7z a node_headers.zip out\Default\gen\node_headers
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
ninja -C out/Default electron:electron_symbols
}
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python electron\script\zip-symbols.py
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
} else {
# It's useful to have pdb files when debugging testing builds that are
# built on CI.
7z a pdb.zip out\Default\*.pdb
}
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
test_script:
# Workaround for https://github.com/appveyor/ci/issues/2420
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
- ps: >-
if ((-Not (Test-Path Env:\TEST_WOA)) -And (-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {
$env:RUN_TESTS="true"
}
- ps: >-
if ($env:RUN_TESTS -eq 'true') {
New-Item .\out\Default\gen\node_headers\Release -Type directory
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
} else {
echo "Skipping tests for $env:GN_CONFIG build"
}
- cd electron
- if "%RUN_TESTS%"=="true" ( echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging=file --log-file=%cd%\electron.log )
- if "%RUN_TESTS%"=="true" ( echo Running remote test suite & node script/yarn test -- --trace-uncaught --runners=remote --runTestFilesSeparately --enable-logging=file --log-file=%cd%\electron.log )
- if "%RUN_TESTS%"=="true" ( echo Running native test suite & node script/yarn test -- --trace-uncaught --runners=native --enable-logging=file --log-file=%cd%\electron.log )
- cd ..
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
- echo "About to verify mksnapshot"
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
- echo "Done verifying mksnapshot"
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )
- echo "Done verifying chromedriver"
deploy_script:
- cd electron
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
Write-Output "Uploading Electron release distribution to azure"
& python script\release\uploaders\upload.py --verbose --upload_to_storage
} else {
# It's useful to have pdb files when debugging testing builds that are
# built on CI.
7z a pdb.zip out\Default\*.pdb
Write-Output "Uploading Electron release distribution to github releases"
& python script\release\uploaders\upload.py --verbose
}
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
deploy_script:
- cd electron
- ps: >-
if (Test-Path Env:\ELECTRON_RELEASE) {
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
Write-Output "Uploading Electron release distribution to azure"
& python script\release\uploaders\upload.py --verbose --upload_to_storage
} else {
Write-Output "Uploading Electron release distribution to github releases"
& python script\release\uploaders\upload.py --verbose
}
} elseif (Test-Path Env:\TEST_WOA) {
node script/release/ci-release-build.js --job=electron-woa-testing --ci=GHA --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
}
on_finish:
# Uncomment this lines to enable RDP
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
- cd C:\projects\src
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
- if exist builtins-pgo.zip (appveyor-retry appveyor PushArtifact builtins-pgo.zip)
- ps: >-
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
appveyor-retry appveyor PushArtifact pdb.zip
}
} elseif (Test-Path Env:\TEST_WOA) {
node script/release/ci-release-build.js --job=electron-woa-testing --ci=GHA --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
}
on_finish:
# Uncomment this lines to enable RDP
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
- cd ..
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
- if exist out\Default\shell_browser_ui_unittests.exe (appveyor-retry appveyor PushArtifact out\Default\shell_browser_ui_unittests.exe)
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
- ps: >-
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
appveyor-retry appveyor PushArtifact pdb.zip
}
-
matrix:
only:
- job_name: Test
init:
- ps: |
if ($env:RUN_TESTS -ne 'true') {
Write-warning "Skipping tests for $env:APPVEYOR_PROJECT_NAME"; Exit-AppveyorBuild
}
if(($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -split "/")[0] -eq ($env:APPVEYOR_REPO_NAME -split "/")[0]) {
Write-warning "Skipping PR build for branch"; Exit-AppveyorBuild
}
build_script:
- ps: |
node script/yarn.js install --frozen-lockfile
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
if ($LASTEXITCODE -eq 0) {
Write-warning "Skipping tests for doc only change"; Exit-AppveyorBuild
}
$global:LASTEXITCODE = 0
- ps: |
cd ..
mkdir out\Default
cd ..
# Download build artifacts
$apiUrl = 'https://ci.appveyor.com/api'
$build_info = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/builds/$env:APPVEYOR_BUILD_ID"
$artifacts_to_download = @('dist.zip','shell_browser_ui_unittests.exe','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','builtins-pgo.zip')
foreach ($job in $build_info.build.jobs) {
if ($job.name -eq "Build") {
$jobId = $job.jobId
foreach($artifact_name in $artifacts_to_download) {
if ($artifact_name -eq 'shell_browser_ui_unittests.exe' -Or $artifact_name -eq 'electron.lib') {
$outfile = "src\out\Default\$artifact_name"
} else {
$outfile = $artifact_name
}
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
}
}
}
- ps: |
$out_default_zips = @('dist.zip','chromedriver.zip','mksnapshot.zip')
foreach($zip_name in $out_default_zips) {
7z x -y -osrc\out\Default $zip_name
}
- ps: 7z x -y -osrc\out\ffmpeg ffmpeg.zip
- ps: 7z x -y -osrc node_headers.zip
- ps: 7z x -y -osrc builtins-pgo.zip
test_script:
# Workaround for https://github.com/appveyor/ci/issues/2420
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
- ps: |
cd src
New-Item .\out\Default\gen\node_headers\Release -Type directory
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
- cd electron
- echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging=file --log-file=%cd%\electron.log
- echo Running native test suite & node script/yarn test -- --trace-uncaught --runners=native --enable-logging=file --log-file=%cd%\electron.log
- cd ..
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
- echo "About to verify mksnapshot"
- echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd%
- echo "Done verifying mksnapshot"
- echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd%
- echo "Done verifying chromedriver"
on_finish:
- if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )
- if exist electron\electron.log ( appveyor-retry appveyor PushArtifact electron\electron.log )

View File

@@ -2,7 +2,7 @@ is_electron_build = true
root_extra_deps = [ "//electron" ]
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
node_module_version = 110
node_module_version = 109
v8_promise_internal_field_count = 1
v8_embedder_string = "-electron.0"
@@ -45,6 +45,3 @@ enable_cet_shadow_stack = false
# V8 in the browser process.
# Ref: https://source.chromium.org/chromium/chromium/src/+/45fba672185aae233e75d6ddc81ea1e0b30db050:v8/BUILD.gn;l=281
is_cfi = false
# TODO: fix this once sysroots have been updated.
use_qt = false

View File

@@ -1,4 +1,4 @@
root_extra_deps = [ "//electron/spec-chromium:spec" ]
root_extra_deps = [ "//electron/spec" ]
dcheck_always_on = true
is_debug = false

View File

@@ -7,6 +7,5 @@
"node_options": "1",
"node_cli_inspect": "1",
"embedded_asar_integrity_validation": "0",
"only_load_app_from_asar": "0",
"load_browser_process_specific_v8_snapshot": "0"
"only_load_app_from_asar": "0"
}

View File

@@ -75,17 +75,9 @@ module.exports = ({
if (targetDeletesNodeGlobals) {
plugins.push(new webpack.ProvidePlugin({
Buffer: ['@electron/internal/common/webpack-provider', 'Buffer'],
process: ['@electron/internal/common/webpack-provider', 'process'],
global: ['@electron/internal/common/webpack-provider', '_global'],
process: ['@electron/internal/common/webpack-provider', 'process']
}));
}
// Webpack 5 no longer polyfills process or Buffer.
if (!alwaysHasNode) {
plugins.push(new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser'
Buffer: ['@electron/internal/common/webpack-provider', 'Buffer']
}));
}
@@ -137,12 +129,7 @@ if ((globalThis.process || binding.process).argv.includes("--profile-electron-in
// Force timers to resolve to our dependency that doesn't use window.postMessage
timers: path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
},
extensions: ['.ts', '.js'],
fallback: {
// We provide our own "timers" import above, any usage of setImmediate inside
// one of our renderer bundles should import it from the 'timers' package
setImmediate: false
}
extensions: ['.ts', '.js']
},
module: {
rules: [{
@@ -163,7 +150,10 @@ if ((globalThis.process || binding.process).argv.includes("--profile-electron-in
},
node: {
__dirname: false,
__filename: false
__filename: false,
// We provide our own "timers" import above, any usage of setImmediate inside
// one of our renderer bundles should import it from the 'timers' package
setImmediate: false
},
optimization: {
minimize: env.mode === 'production',

View File

@@ -30,14 +30,11 @@ template("webpack_build") {
args = [
"--config",
rebase_path(invoker.config_file),
"--output-filename",
get_path_info(invoker.out_file, "file"),
"--output-path",
rebase_path(get_path_info(invoker.out_file, "dir")),
"--env",
"buildflags=" + rebase_path("$target_gen_dir/buildflags/buildflags.h"),
"--env",
"mode=" + mode,
"--output-filename=" + get_path_info(invoker.out_file, "file"),
"--output-path=" + rebase_path(get_path_info(invoker.out_file, "dir")),
"--env.buildflags=" +
rebase_path("$target_gen_dir/buildflags/buildflags.h"),
"--env.mode=" + mode,
]
deps += [ "//electron/buildflags" ]

View File

@@ -6,7 +6,6 @@ import("//build/config/ozone.gni")
import("//build/config/ui.gni")
import("//components/spellcheck/spellcheck_build_features.gni")
import("//electron/buildflags/buildflags.gni")
import("//ppapi/buildflags/buildflags.gni")
import("//printing/buildflags/buildflags.gni")
import("//third_party/widevine/cdm/widevine.gni")
@@ -157,7 +156,10 @@ static_library("chrome") {
"//services/strings",
]
deps = [ "//chrome/browser:resource_prefetch_predictor_proto" ]
deps = [
"//chrome/browser:resource_prefetch_predictor_proto",
"//components/optimization_guide/proto:optimization_guide_proto",
]
if (is_linux) {
sources += [ "//chrome/browser/icon_loader_auralinux.cc" ]
@@ -230,8 +232,6 @@ static_library("chrome") {
"//chrome/browser/printing/printer_query.h",
"//chrome/browser/printing/printing_service.cc",
"//chrome/browser/printing/printing_service.h",
"//components/printing/browser/print_to_pdf/pdf_print_job.cc",
"//components/printing/browser/print_to_pdf/pdf_print_job.h",
"//components/printing/browser/print_to_pdf/pdf_print_utils.cc",
"//components/printing/browser/print_to_pdf/pdf_print_utils.h",
]
@@ -373,20 +373,15 @@ source_set("plugins") {
deps += [
"//components/strings",
"//media:media_buildflags",
"//ppapi/buildflags",
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/proxy:ipc",
"//ppapi/shared_impl",
"//services/device/public/mojom",
"//skia",
"//storage/browser",
]
if (enable_ppapi) {
deps += [
"//ppapi/buildflags",
"//ppapi/host",
"//ppapi/proxy",
"//ppapi/proxy:ipc",
"//ppapi/shared_impl",
]
}
}
# This source set is just so we don't have to depend on all of //chrome/browser
@@ -400,10 +395,6 @@ source_set("chrome_spellchecker") {
if (enable_builtin_spellchecker) {
sources += [
"//chrome/browser/profiles/profile_keyed_service_factory.cc",
"//chrome/browser/profiles/profile_keyed_service_factory.h",
"//chrome/browser/profiles/profile_selections.cc",
"//chrome/browser/profiles/profile_selections.h",
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.cc",
"//chrome/browser/spellchecker/spell_check_host_chrome_impl.h",
"//chrome/browser/spellchecker/spellcheck_custom_dictionary.cc",

View File

@@ -83,7 +83,7 @@ function loadApplicationPackage (packagePath: string) {
});
try {
// Override app's package.json data.
// Override app name and version.
packagePath = path.resolve(packagePath);
const packageJsonPath = path.join(packagePath, 'package.json');
let appPath;
@@ -104,16 +104,6 @@ function loadApplicationPackage (packagePath: string) {
} else if (packageJson.name) {
app.name = packageJson.name;
}
if (packageJson.desktopName) {
app.setDesktopName(packageJson.desktopName);
} else {
app.setDesktopName(`${app.name}.desktop`);
}
// Set v8 flags, deliberately lazy load so that apps that do not use this
// feature do not pay the price
if (packageJson.v8Flags) {
require('v8').setFlagsFromString(packageJson.v8Flags);
}
appPath = packagePath;
}

View File

@@ -68,7 +68,6 @@ an issue:
* [Mac App Store](tutorial/mac-app-store-submission-guide.md)
* [Windows Store](tutorial/windows-store-guide.md)
* [Snapcraft](tutorial/snapcraft.md)
* [ASAR Archives](tutorial/asar-archives.md)
* [Updates](tutorial/updates.md)
* [Getting Support](tutorial/support.md)
@@ -83,6 +82,7 @@ These individual tutorials expand on topics discussed in the guide above.
* Electron Releases & Developer Feedback
* [Versioning Policy](tutorial/electron-versioning.md)
* [Release Timelines](tutorial/electron-timelines.md)
* [Testing Widevine CDM](tutorial/testing-widevine-cdm.md)
---

View File

@@ -715,7 +715,7 @@ To set the locale, you'll want to use a command line switch at app startup, whic
**Note:** When distributing your packaged app, you have to also ship the
`locales` folder.
**Note:** This API must be called after the `ready` event is emitted.
**Note:** On Windows, you have to call it after the `ready` events gets emitted.
### `app.getLocaleCountryCode()`
@@ -723,12 +723,6 @@ Returns `string` - User operating system's locale two-letter [ISO 3166](https://
**Note:** When unable to detect locale country code, it returns empty string.
### `app.getSystemLocale()`
Returns `string` - The current system locale. On Windows and Linux, it is fetched using Chromium's `i18n` library. On macOS, the `NSLocale` object is used instead.
**Note:** This API must be called after the `ready` event is emitted.
### `app.addRecentDocument(path)` _macOS_ _Windows_
* `path` string

View File

@@ -652,36 +652,18 @@ The following app commands are explicitly supported on Linux:
* `browser-backward`
* `browser-forward`
#### Event: 'scroll-touch-begin' _macOS_ _Deprecated_
#### Event: 'scroll-touch-begin' _macOS_
Emitted when scroll wheel event phase has begun.
> **Note**
> This event is deprecated beginning in Electron 22.0.0. See [Breaking
> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> for details of how to migrate to using the [WebContents
> `input-event`](api/web-contents.md#event-input-event) event.
#### Event: 'scroll-touch-end' _macOS_ _Deprecated_
#### Event: 'scroll-touch-end' _macOS_
Emitted when scroll wheel event phase has ended.
> **Note**
> This event is deprecated beginning in Electron 22.0.0. See [Breaking
> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> for details of how to migrate to using the [WebContents
> `input-event`](api/web-contents.md#event-input-event) event.
#### Event: 'scroll-touch-edge' _macOS_ _Deprecated_
#### Event: 'scroll-touch-edge' _macOS_
Emitted when scroll wheel event phase filed upon reaching the edge of element.
> **Note**
> This event is deprecated beginning in Electron 22.0.0. See [Breaking
> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events)
> for details of how to migrate to using the [WebContents
> `input-event`](api/web-contents.md#event-input-event) event.
#### Event: 'swipe' _macOS_
Returns:

View File

@@ -46,12 +46,6 @@ The `contextBridge` module has the following methods:
* `apiKey` string - The key to inject the API onto `window` with. The API will be accessible on `window[apiKey]`.
* `api` any - Your API, more information on what this API can be and how it works is available below.
### `contextBridge.exposeInIsolatedWorld(worldId, apiKey, api)`
* `worldId` Integer - The ID of the world to inject the API into. `0` is the default world, `999` is the world used by Electron's `contextIsolation` feature. Using 999 would expose the object for preload context. We recommend using 1000+ while creating isolated world.
* `apiKey` string - The key to inject the API onto `window` with. The API will be accessible on `window[apiKey]`.
* `api` any - Your API, more information on what this API can be and how it works is available below.
## Usage
### API
@@ -90,26 +84,6 @@ contextBridge.exposeInMainWorld(
)
```
An example of `exposeInIsolatedWorld` is shown below:
```javascript
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInIsolatedWorld(
1004,
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
```
```javascript
// Renderer (In isolated world id1004)
window.electron.doThing()
```
### API Functions
`Function` values that you bind through the `contextBridge` are proxied through Electron to ensure that contexts remain isolated. This

View File

@@ -10,12 +10,11 @@ An example of implementing a protocol that has the same effect as the
```javascript
const { app, protocol } = require('electron')
const path = require('path')
const url = require('url')
app.whenReady().then(() => {
protocol.registerFileProtocol('atom', (request, callback) => {
const filePath = url.fileURLToPath('file://' + request.url.slice('atom://'.length))
callback(filePath)
const url = request.url.substr(7)
callback({ path: path.normalize(`${__dirname}/${url}`) })
})
})
```
@@ -176,7 +175,7 @@ property.
* `handler` Function
* `request` [ProtocolRequest](structures/protocol-request.md)
* `callback` Function
* `response` [ProtocolResponse](structures/protocol-response.md)
* `response` ProtocolResponse
Returns `boolean` - Whether the protocol was successfully registered

View File

@@ -698,60 +698,6 @@ session.fromPartition('some-partition').setPermissionCheckHandler((webContents,
})
```
#### `ses.setDisplayMediaRequestHandler(handler)`
* `handler` Function | null
* `request` Object
* `frame` [WebFrameMain](web-frame-main.md) - Frame that is requesting access to media.
* `securityOrigin` String - Origin of the page making the request.
* `videoRequested` Boolean - true if the web content requested a video stream.
* `audioRequested` Boolean - true if the web content requested an audio stream.
* `userGesture` Boolean - Whether a user gesture was active when this request was triggered.
* `callback` Function
* `streams` Object
* `video` Object | [WebFrameMain](web-frame-main.md) (optional)
* `id` String - The id of the stream being granted. This will usually
come from a [DesktopCapturerSource](structures/desktop-capturer-source.md)
object.
* `name` String - The name of the stream being granted. This will
usually come from a [DesktopCapturerSource](structures/desktop-capturer-source.md)
object.
* `audio` String | [WebFrameMain](web-frame-main.md) (optional) - If
a string is specified, can be `loopback` or `loopbackWithMute`.
Specifying a loopback device will capture system audio, and is
currently only supported on Windows. If a WebFrameMain is specified,
will capture audio from that frame.
This handler will be called when web content requests access to display media
via the `navigator.mediaDevices.getDisplayMedia` API. Use the
[desktopCapturer](desktop-capturer.md) API to choose which stream(s) to grant
access to.
```javascript
const { session, desktopCapturer } = require('electron')
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
desktopCapturer.getSources({ types: ['screen'] }).then((sources) => {
// Grant access to the first screen found.
callback({ video: sources[0] })
})
})
```
Passing a [WebFrameMain](web-frame-main.md) object as a video or audio stream
will capture the video or audio stream from that frame.
```javascript
const { session } = require('electron')
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
// Allow the tab to capture itself.
callback({ video: request.frame })
})
```
Passing `null` instead of a function resets the handler to its default state.
#### `ses.setDevicePermissionHandler(handler)`
* `handler` Function\<boolean> | null
@@ -823,71 +769,6 @@ app.whenReady().then(() => {
})
```
#### `ses.setBluetoothPairingHandler(handler)` _Windows_ _Linux_
* `handler` Function | null
* `details` Object
* `deviceId` string
* `pairingKind` string - The type of pairing prompt being requested.
One of the following values:
* `confirm`
This prompt is requesting confirmation that the Bluetooth device should
be paired.
* `confirmPin`
This prompt is requesting confirmation that the provided PIN matches the
pin displayed on the device.
* `providePin`
This prompt is requesting that a pin be provided for the device.
* `frame` [WebFrameMain](web-frame-main.md)
* `pin` string (optional) - The pin value to verify if `pairingKind` is `confirmPin`.
* `callback` Function
* `response` Object
* `confirmed` boolean - `false` should be passed in if the dialog is canceled.
If the `pairingKind` is `confirm` or `confirmPin`, this value should indicate
if the pairing is confirmed. If the `pairingKind` is `providePin` the value
should be `true` when a value is provided.
* `pin` string | null (optional) - When the `pairingKind` is `providePin`
this value should be the required pin for the Bluetooth device.
Sets a handler to respond to Bluetooth pairing requests. This handler
allows developers to handle devices that require additional validation
before pairing. When a handler is not defined, any pairing on Linux or Windows
that requires additional validation will be automatically cancelled.
macOS does not require a handler because macOS handles the pairing
automatically. To clear the handler, call `setBluetoothPairingHandler(null)`.
```javascript
const { app, BrowserWindow, ipcMain, session } = require('electron')
let bluetoothPinCallback = null
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
}
// Listen for an IPC message from the renderer to get the response for the Bluetooth pairing.
ipcMain.on('bluetooth-pairing-response', (event, response) => {
bluetoothPinCallback(response)
})
mainWindow.webContents.session.setBluetoothPairingHandler((details, callback) => {
bluetoothPinCallback = callback
// Send a IPC message to the renderer to prompt the user to confirm the pairing.
// Note that this will require logic in the renderer to handle this message and
// display a prompt to the user.
mainWindow.webContents.send('bluetooth-pairing-request', details)
})
app.whenReady().then(() => {
createWindow()
})
```
#### `ses.clearHostResolverCache()`
Returns `Promise<void>` - Resolves when the operation is complete.
@@ -1051,7 +932,7 @@ Returns `string[]` - An array of language codes the spellchecker is enabled for.
will fallback to using `en-US`. By default on launch if this setting is an empty list Electron will try to populate this
setting with the current OS locale. This setting is persisted across restarts.
**Note:** On macOS the OS spellchecker is used and has its own list of languages. On macOS, this API will return whichever languages have been configured by the OS.
**Note:** On macOS the OS spellchecker is used and has its own list of languages. This API is a no-op on macOS.
#### `ses.setSpellCheckerDictionaryDownloadURL(url)`

View File

@@ -1,16 +1,5 @@
# InputEvent Object
* `type` string - Can be `undefined`, `mouseDown`, `mouseUp`, `mouseMove`,
`mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`, `rawKeyDown`,
`keyDown`, `keyUp`, `char`, `gestureScrollBegin`, `gestureScrollEnd`,
`gestureScrollUpdate`, `gestureFlingStart`, `gestureFlingCancel`,
`gesturePinchBegin`, `gesturePinchEnd`, `gesturePinchUpdate`,
`gestureTapDown`, `gestureShowPress`, `gestureTap`, `gestureTapCancel`,
`gestureShortPress`, `gestureLongPress`, `gestureLongTap`,
`gestureTwoFingerTap`, `gestureTapUnconfirmed`, `gestureDoubleTap`,
`touchStart`, `touchMove`, `touchEnd`, `touchCancel`, `touchScrollStarted`,
`pointerDown`, `pointerUp`, `pointerMove`, `pointerRawUpdate`,
`pointerCancel` or `pointerCausedUaAction`.
* `modifiers` string[] (optional) - An array of modifiers of the event, can
be `shift`, `control`, `ctrl`, `alt`, `meta`, `command`, `cmd`, `isKeypad`,
`isAutoRepeat`, `leftButtonDown`, `middleButtonDown`, `rightButtonDown`,

View File

@@ -1,6 +1,6 @@
# KeyboardInputEvent Object extends `InputEvent`
* `type` string - The type of the event, can be `rawKeyDown`, `keyDown`, `keyUp` or `char`.
* `type` string - The type of the event, can be `keyDown`, `keyUp` or `char`.
* `keyCode` string - The character that will be sent
as the keyboard event. Should only use the valid key codes in
[Accelerator](../accelerator.md).

View File

@@ -0,0 +1,3 @@
# NewWindowWebContentsEvent Object extends `Event`
* `newGuest` BrowserWindow (optional)

View File

@@ -45,13 +45,6 @@ returns `null`.
Returns `WebContents` | undefined - A WebContents instance with the given ID, or
`undefined` if there is no WebContents associated with the given ID.
### `webContents.fromFrame(frame)`
* `frame` WebFrameMain
Returns `WebContents` | undefined - A WebContents instance with the given WebFrameMain, or
`undefined` if there is no WebContents associated with the given WebFrameMain.
### `webContents.fromDevToolsTargetId(targetId)`
* `targetId` string - The Chrome DevTools Protocol [TargetID](https://chromedevtools.github.io/devtools-protocol/tot/Target/#type-TargetID) associated with the WebContents instance.
@@ -137,6 +130,10 @@ Corresponds to the points in time when the spinner of the tab stopped spinning.
#### Event: 'dom-ready'
Returns:
* `event` Event
Emitted when the document in the top-level frame is loaded.
#### Event: 'page-title-updated'
@@ -159,17 +156,63 @@ Returns:
Emitted when page receives favicon urls.
#### Event: 'content-bounds-updated'
#### Event: 'new-window' _Deprecated_
Returns:
* `event` Event
* `bounds` [Rectangle](structures/rectangle.md) - requested new content bounds
* `event` NewWindowWebContentsEvent
* `url` string
* `frameName` string
* `disposition` string - Can be `default`, `foreground-tab`, `background-tab`,
`new-window`, `save-to-disk` and `other`.
* `options` BrowserWindowConstructorOptions - The options which will be used for creating the new
[`BrowserWindow`](browser-window.md).
* `additionalFeatures` string[] - The non-standard features (features not handled
by Chromium or Electron) given to `window.open()`. Deprecated, and will now
always be the empty array `[]`.
* `referrer` [Referrer](structures/referrer.md) - The referrer that will be
passed to the new window. May or may not result in the `Referer` header being
sent, depending on the referrer policy.
* `postBody` [PostBody](structures/post-body.md) (optional) - The post data that
will be sent to the new window, along with the appropriate headers that will
be set. If no post data is to be sent, the value will be `null`. Only defined
when the window is being created by a form that set `target=_blank`.
Emitted when the page calls `window.moveTo`, `window.resizeTo` or related APIs.
Deprecated in favor of [`webContents.setWindowOpenHandler`](web-contents.md#contentssetwindowopenhandlerhandler).
By default, this will move the window. To prevent that behavior, call
`event.preventDefault()`.
Emitted when the page requests to open a new window for a `url`. It could be
requested by `window.open` or an external link like `<a target='_blank'>`.
By default a new `BrowserWindow` will be created for the `url`.
Calling `event.preventDefault()` will prevent Electron from automatically creating a
new [`BrowserWindow`](browser-window.md). If you call `event.preventDefault()` and manually create a new
[`BrowserWindow`](browser-window.md) then you must set `event.newGuest` to reference the new [`BrowserWindow`](browser-window.md)
instance, failing to do so may result in unexpected behavior. For example:
```javascript
myBrowserWindow.webContents.on('new-window', (event, url, frameName, disposition, options, additionalFeatures, referrer, postBody) => {
event.preventDefault()
const win = new BrowserWindow({
webContents: options.webContents, // use existing webContents if provided
show: false
})
win.once('ready-to-show', () => win.show())
if (!options.webContents) {
const loadOptions = {
httpReferrer: referrer
}
if (postBody != null) {
const { data, contentType, boundary } = postBody
loadOptions.postData = postBody.data
loadOptions.extraHeaders = `content-type: ${contentType}; boundary=${boundary}`
}
win.loadURL(url, loadOptions) // existing webContents will be navigated automatically
}
event.newGuest = win
})
```
#### Event: 'did-create-window'
@@ -411,16 +454,6 @@ Emitted when a plugin process has crashed.
Emitted when `webContents` is destroyed.
#### Event: 'input-event'
Returns:
* `event` Event
* `inputEvent` [InputEvent](structures/input-event.md)
Emitted when an input event is sent to the WebContents. See
[InputEvent](structures/input-event.md) for details.
#### Event: 'before-input-event'
Returns:
@@ -951,21 +984,6 @@ Returns `string` - The title of the current web page.
Returns `boolean` - Whether the web page is destroyed.
#### `contents.close([opts])`
* `opts` Object (optional)
* `waitForBeforeUnload` boolean - if true, fire the `beforeunload` event
before closing the page. If the page prevents the unload, the WebContents
will not be closed. The [`will-prevent-unload`](#event-will-prevent-unload)
will be fired if the page requests prevention of unload.
Closes the page, as if the web content had called `window.close()`.
If the page is successfully closed (i.e. the unload is not prevented by the
page, or `waitForBeforeUnload` is false or unspecified), the WebContents will
be destroyed and no longer usable. The [`destroyed`](#event-destroyed) event
will be emitted.
#### `contents.focus()`
Focuses the web page.
@@ -1608,8 +1626,6 @@ Opens the devtools.
When `contents` is a `<webview>` tag, the `mode` would be `detach` by default,
explicitly passing an empty `mode` can force using last used dock state.
On Windows, if Windows Control Overlay is enabled, Devtools will be opened with `mode: 'detach'`.
#### `contents.closeDevTools()`
Closes the devtools.
@@ -2061,11 +2077,6 @@ when the page becomes backgrounded. This also affects the Page Visibility API.
A [`WebFrameMain`](web-frame-main.md) property that represents the top frame of the page's frame hierarchy.
#### `contents.opener` _Readonly_
A [`WebFrameMain`](web-frame-main.md) property that represents the frame that opened this WebContents, either
with open(), or by navigating a link with a target attribute.
[keyboardevent]: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm

View File

@@ -169,16 +169,6 @@ convenient when `nodeIntegrationInSubFrames` is not enabled.
A `string` representing the current URL of the frame.
#### `frame.origin` _Readonly_
A `string` representing the current origin of the frame, serialized according
to [RFC 6454](https://www.rfc-editor.org/rfc/rfc6454). This may be different
from the URL. For instance, if the frame is a child window opened to
`about:blank`, then `frame.origin` will return the parent frame's origin, while
`frame.url` will return the empty string. Pages without a scheme/host/port
triple origin will have the serialized origin of `"null"` (that is, the string
containing the letters n, u, l, l).
#### `frame.top` _Readonly_
A `WebFrameMain | null` representing top frame in the frame hierarchy to which `frame`

View File

@@ -805,6 +805,33 @@ const requestId = webview.findInPage('test')
console.log(requestId)
```
### Event: 'new-window'
Returns:
* `url` string
* `frameName` string
* `disposition` string - Can be `default`, `foreground-tab`, `background-tab`,
`new-window`, `save-to-disk` and `other`.
* `options` BrowserWindowConstructorOptions - The options which should be used for creating the new
[`BrowserWindow`](browser-window.md).
Fired when the guest page attempts to open a new browser window.
The following example code opens the new url in system's default browser.
```javascript
const { shell } = require('electron')
const webview = document.querySelector('webview')
webview.addEventListener('new-window', async (e) => {
const protocol = (new URL(e.url)).protocol
if (protocol === 'http:' || protocol === 'https:') {
await shell.openExternal(e.url)
}
})
```
### Event: 'will-navigate'
Returns:

View File

@@ -12,75 +12,7 @@ This document uses the following convention to categorize breaking changes:
* **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
* **Removed:** An API or feature was removed, and is no longer supported by Electron.
## Planned Breaking API Changes (23.0)
### Removed: BrowserWindow `scroll-touch-*` events
The deprecated `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge`
events on BrowserWindow have been removed. Instead, use the newly available
[`input-event` event](api/web-contents.md#event-input-event) on WebContents.
```js
// Removed in Electron 23.0
win.on('scroll-touch-begin', scrollTouchBegin)
win.on('scroll-touch-edge', scrollTouchEdge)
win.on('scroll-touch-end', scrollTouchEnd)
// Replace with
win.webContents.on('input-event', (_, event) => {
if (event.type === 'gestureScrollBegin') {
scrollTouchBegin()
} else if (event.type === 'gestureScrollUpdate') {
scrollTouchEdge()
} else if (event.type === 'gestureScrollEnd') {
scrollTouchEnd()
}
})
```
## Planned Breaking API Changes (22.0)
### Removed: WebContents `new-window` event
The `new-window` event of WebContents has been removed. It is replaced by [`webContents.setWindowOpenHandler()`](api/web-contents.md#contentssetwindowopenhandlerhandler).
```js
// Removed in Electron 21
webContents.on('new-window', (event) => {
event.preventDefault()
})
// Replace with
webContents.setWindowOpenHandler((details) => {
return { action: 'deny' }
})
```
### Deprecated: BrowserWindow `scroll-touch-*` events
The `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge` events on
BrowserWindow are deprecated. Instead, use the newly available [`input-event`
event](api/web-contents.md#event-input-event) on WebContents.
```js
// Deprecated
win.on('scroll-touch-begin', scrollTouchBegin)
win.on('scroll-touch-edge', scrollTouchEdge)
win.on('scroll-touch-end', scrollTouchEnd)
// Replace with
win.webContents.on('input-event', (_, event) => {
if (event.type === 'gestureScrollBegin') {
scrollTouchBegin()
} else if (event.type === 'gestureScrollUpdate') {
scrollTouchEdge()
} else if (event.type === 'gestureScrollEnd') {
scrollTouchEnd()
}
})
```
## Planned Breaking API Changes (21.0)
## Planned Breaking API Changes (20.0)
### Behavior Changed: V8 Memory Cage enabled
@@ -144,8 +76,6 @@ webContents.printToPDF({
})
```
## Planned Breaking API Changes (20.0)
### Default Changed: renderers without `nodeIntegration: true` are sandboxed by default
Previously, renderers that specified a preload script defaulted to being

View File

@@ -54,7 +54,7 @@ See [issues](issues.md) for more information.
Most pull requests opened against the `electron/electron` repository include
changes to either the C/C++ code in the `shell/` folder,
the TypeScript code in the `lib/` folder, the documentation in `docs/`,
or tests in the `spec/` folder.
or tests in the `spec/` and `spec-main/` folders.
See [pull requests](pull-requests.md) for more information.

View File

@@ -281,22 +281,9 @@ $ cd electron
$ gclient sync -f
```
This may also happen if you have checked out a branch (as opposed to having a detached head) in `electron/src/`
or some other dependencys repository. If that is the case, a `git checkout --detach HEAD` in the appropriate repository should do the trick.
### I'm being asked for a username/password for chromium-internal.googlesource.com
If you see a prompt for `Username for 'https://chrome-internal.googlesource.com':` when running `gclient sync` on Windows, it's probably because the `DEPOT_TOOLS_WIN_TOOLCHAIN` environment variable is not set to 0. Open `Control Panel``System and Security``System``Advanced system settings` and add a system variable
`DEPOT_TOOLS_WIN_TOOLCHAIN` with value `0`. This tells `depot_tools` to use
your locally installed version of Visual Studio (by default, `depot_tools` will
try to download a Google-internal version that only Googlers have access to).
### `e` Module not found
If `e` is not recognized despite running `npm i -g @electron/build-tools`, ie:
```sh
Error: Cannot find module '/Users/<user>/.electron_build_tools/src/e'
```
We recommend installing Node through [nvm](https://github.com/nvm-sh/nvm). This allows for easier Node version management, and is often a fix for missing `e` modules.

View File

@@ -13,46 +13,6 @@ Follow the guidelines below for building **Electron itself** on macOS, for the p
* [node.js](https://nodejs.org) (external)
* Python >= 3.7
### Arm64-specific prerequisites
* Rosetta 2
* We recommend installing Rosetta if using dependencies that need to cross-compile on x64 and arm64 machines. Rosetta can be installed by using the softwareupdate command line tool.
* `$ softwareupdate --install-rosetta`
## Building Electron
See [Build Instructions: GN](build-instructions-gn.md).
## Troubleshooting
### Xcode "incompatible architecture" errors (MacOS arm64-specific)
If both Xcode and Xcode command line tools are installed (`$ xcode -select --install`, or directly download the correct version [here](https://developer.apple.com/download/all/?q=command%20line%20tools)), but the stack trace says otherwise like so:
```sh
xcrun: error: unable to load libxcrun
(dlopen(/Users/<user>/.electron_build_tools/third_party/Xcode/Xcode.app/Contents/Developer/usr/lib/libxcrun.dylib (http://xcode.app/Contents/Developer/usr/lib/libxcrun.dylib), 0x0005):
tried: '/Users/<user>/.electron_build_tools/third_party/Xcode/Xcode.app/Contents/Developer/usr/lib/libxcrun.dylib (http://xcode.app/Contents/Developer/usr/lib/libxcrun.dylib)'
(mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e))), '/Users/<user>/.electron_build_tools/third_party/Xcode/Xcode-11.1.0.app/Contents/Developer/usr/lib/libxcrun.dylib (http://xcode-11.1.0.app/Contents/Developer/usr/lib/libxcrun.dylib)' (mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e)))).`
```
If you are on arm64 architecture, the build script may be pointing to the wrong Xcode version (11.x.y doesn't support arm64). Navigate to `/Users/<user>/.electron_build_tools/third_party/Xcode/` and rename `Xcode-13.3.0.app` to `Xcode.app` to ensure the right Xcode version is used.
### Certificates fail to verify
installing [`certifi`](https://pypi.org/project/certifi/) will fix the following error:
```sh
________ running 'python3 src/tools/clang/scripts/update.py' in '/Users/<user>/electron'
Downloading https://commondatastorage.googleapis.com/chromium-browser-clang/Mac_arm64/clang-llvmorg-15-init-15652-g89a99ec9-1.tgz
<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
Retrying in 5 s ...
Downloading https://commondatastorage.googleapis.com/chromium-browser-clang/Mac_arm64/clang-llvmorg-15-init-15652-g89a99ec9-1.tgz
<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
Retrying in 10 s ...
Downloading https://commondatastorage.googleapis.com/chromium-browser-clang/Mac_arm64/clang-llvmorg-15-init-15652-g89a99ec9-1.tgz
<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
Retrying in 20 s ...
```
This issue has to do with Python 3.6 using its [own](https://github.com/python/cpython/blob/560ea272b01acaa6c531cc7d94331b2ef0854be6/Mac/BuildScript/resources/ReadMe.rtf#L35) copy of OpenSSL in lieu of the deprecated Apple-supplied OpenSSL libraries. `certifi` adds a curated bundle of default root certificates. This issue is documented in the Electron repo [here](https://github.com/electron/build-tools/issues/55). Further information about this issue can be found [here](https://stackoverflow.com/questions/27835619/urllib-and-ssl-certificate-verify-failed-error) and [here](https://stackoverflow.com/questions/40684543/how-to-make-python-use-ca-certificates-from-mac-os-truststore).

View File

@@ -72,7 +72,8 @@ Electron
| | message loop into Chromium's message loop.
| └── api/ - The implementation of common APIs, and foundations of
| Electron's built-in modules.
├── spec/ - Components of Electron's test suite run in the main process.
├── spec/ - Components of Electron's test suite run in the renderer process.
├── spec-main/ - Components of Electron's test suite run in the main process.
└── BUILD.gn - Building rules of Electron.
```

View File

@@ -32,6 +32,9 @@ app (surprise!) that can be found in the `spec` folder. Note that it has
its own `package.json` and that its dependencies are therefore not defined
in the top-level `package.json`.
To run only tests in a specific process, run `npm run test --runners=PROCESS`
where `PROCESS` is one of `main` or `remote`.
To run only specific tests matching a pattern, run `npm run test --
-g=PATTERN`, replacing the `PATTERN` with a regex that matches the tests
you would like to run. As an example: If you want to run only IPC tests, you

View File

@@ -20,4 +20,4 @@ happen at an API WG meeting. Things to consider when discussing / nominating:
* During that time no major bugs / issues should have been caused by the adoption of this feature
* The API is stable enough and hasn't been heavily impacted by Chromium upgrades
* Is anyone using the API?
* Is the API fulfilling the original proposed use cases, does it have any gaps?
* Is the API fulfilling the original proposed usecases, does it have any gaps?

View File

@@ -135,7 +135,7 @@ is only available in renderer processes.
If [sub-pixel anti-aliasing](https://alienryderflex.com/sub_pixel/) is deactivated, then fonts on LCD screens can look blurry. Example:
![Subpixel rendering example](images/subpixel-rendering-screenshot.gif)
![subpixel rendering example]
Sub-pixel anti-aliasing needs a non-transparent background of the layer containing the font glyphs. (See [this issue](https://github.com/electron/electron/issues/6344#issuecomment-420371918) for more info).
@@ -161,3 +161,4 @@ Notice that just setting the background in the CSS does not have the desired eff
[indexed-db]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
[message-port]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
[browser-window]: api/browser-window.md
[subpixel rendering example]: images/subpixel-rendering-screenshot.gif

View File

@@ -1,13 +1,10 @@
const {app, BrowserWindow, ipcMain} = require('electron')
const {app, BrowserWindow} = require('electron')
const path = require('path')
function createWindow () {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
height: 600
})
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
@@ -17,18 +14,6 @@ function createWindow () {
}
})
// Listen for a message from the renderer to get the response for the Bluetooth pairing.
ipcMain.on('bluetooth-pairing-response', (event, response) => {
bluetoothPinCallback(response)
})
mainWindow.webContents.session.setBluetoothPairingHandler((details, callback) => {
bluetoothPinCallback = callback
// Send a message to the renderer to prompt the user to confirm the pairing.
mainWindow.webContents.send('bluetooth-pairing-request', details)
})
mainWindow.loadFile('index.html')
}

View File

@@ -1,6 +0,0 @@
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
bluetoothPairingRequest: (callback) => ipcRenderer.on('bluetooth-pairing-request', callback),
bluetoothPairingResponse: (response) => ipcRenderer.send('bluetooth-pairing-response', response)
})

View File

@@ -5,30 +5,4 @@ async function testIt() {
document.getElementById('device-name').innerHTML = device.name || `ID: ${device.id}`
}
document.getElementById('clickme').addEventListener('click',testIt)
window.electronAPI.bluetoothPairingRequest((event, details) => {
const response = {}
switch (details.pairingKind) {
case 'confirm': {
response.confirmed = confirm(`Do you want to connect to device ${details.deviceId}?`)
break
}
case 'confirmPin': {
response.confirmed = confirm(`Does the pin ${details.pin} match the pin displayed on device ${details.deviceId}?`)
break
}
case 'providePin': {
const pin = prompt(`Please provide a pin for ${details.deviceId}.`)
if (pin) {
response.pin = pin
response.confirmed = true
} else {
response.confirmed = false
}
}
}
window.electronAPI.bluetoothPairingResponse(response)
})
document.getElementById('clickme').addEventListener('click',testIt)

View File

@@ -33,16 +33,12 @@ function createWindow () {
if (permission === 'serial' && details.securityOrigin === 'file:///') {
return true
}
return false
})
mainWindow.webContents.session.setDevicePermissionHandler((details) => {
if (details.deviceType === 'serial' && details.origin === 'file://') {
return true
}
return false
})
mainWindow.loadFile('index.html')

View File

@@ -44,4 +44,6 @@ CFStringRef kAXManualAccessibility = CFSTR("AXManualAccessibility");
```
[a11y-docs]: https://www.chromium.org/developers/design-documents/accessibility#TOC-How-Chrome-detects-the-presence-of-Assistive-Technology
[a11y-devtools]: https://github.com/GoogleChrome/accessibility-developer-tools
[a11y-devtools-wiki]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules
[setAccessibilitySupportEnabled]: ../api/app.md#appsetaccessibilitysupportenabledenabled-macos-windows

View File

@@ -11,8 +11,8 @@ can either use specialized tooling or manual approaches.
## With tooling
There are a couple tools out there that exist to package and distribute your Electron app.
We recommend using [Electron Forge](./forge-overview.md). You can check out
its [documentation](https://www.electronforge.io) directly, or refer to the [Packaging and Distribution](./tutorial-5-packaging.md)
We recommend using [Electron Forge](https://www.electronforge.io). You can check out
its documentation directly, or refer to the [Packaging and Distribution](./tutorial-5-packaging.md)
part of the Electron tutorial.
## Manual packaging

View File

@@ -1,175 +0,0 @@
---
title: ASAR Archives
description: What is ASAR archive and how does it affect the application.
slug: asar-archives
hide_title: false
---
After creating an [application distribution](application-distribution.md), the
app's source code are usually bundled into an [ASAR
archive](https://github.com/electron/asar), which is a simple extensive archive
format designed for Electron apps. By bundling the app we can mitigate issues
around long path names on Windows, speed up `require` and conceal your source
code from cursory inspection.
The bundled app runs in a virtual file system and most APIs would just work
normally, but for some cases you might want to work on ASAR archives explicitly
due to a few caveats.
## Using ASAR Archives
In Electron there are two sets of APIs: Node APIs provided by Node.js and Web
APIs provided by Chromium. Both APIs support reading files from ASAR archives.
### Node API
With special patches in Electron, Node APIs like `fs.readFile` and `require`
treat ASAR archives as virtual directories, and the files in it as normal
files in the filesystem.
For example, suppose we have an `example.asar` archive under `/path/to`:
```sh
$ asar list /path/to/example.asar
/app.js
/file.txt
/dir/module.js
/static/index.html
/static/main.css
/static/jquery.min.js
```
Read a file in the ASAR archive:
```javascript
const fs = require('fs')
fs.readFileSync('/path/to/example.asar/file.txt')
```
List all files under the root of the archive:
```javascript
const fs = require('fs')
fs.readdirSync('/path/to/example.asar')
```
Use a module from the archive:
```javascript
require('./path/to/example.asar/dir/module.js')
```
You can also display a web page in an ASAR archive with `BrowserWindow`:
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.loadURL('file:///path/to/example.asar/static/index.html')
```
### Web API
In a web page, files in an archive can be requested with the `file:` protocol.
Like the Node API, ASAR archives are treated as directories.
For example, to get a file with `$.get`:
```html
<script>
let $ = require('./jquery.min.js')
$.get('file:///path/to/example.asar/file.txt', (data) => {
console.log(data)
})
</script>
```
### Treating an ASAR archive as a Normal File
For some cases like verifying the ASAR archive's checksum, we need to read the
content of an ASAR archive as a file. For this purpose you can use the built-in
`original-fs` module which provides original `fs` APIs without `asar` support:
```javascript
const originalFs = require('original-fs')
originalFs.readFileSync('/path/to/example.asar')
```
You can also set `process.noAsar` to `true` to disable the support for `asar` in
the `fs` module:
```javascript
const fs = require('fs')
process.noAsar = true
fs.readFileSync('/path/to/example.asar')
```
## Limitations of the Node API
Even though we tried hard to make ASAR archives in the Node API work like
directories as much as possible, there are still limitations due to the
low-level nature of the Node API.
### Archives Are Read-only
The archives can not be modified so all Node APIs that can modify files will not
work with ASAR archives.
### Working Directory Can Not Be Set to Directories in Archive
Though ASAR archives are treated as directories, there are no actual
directories in the filesystem, so you can never set the working directory to
directories in ASAR archives. Passing them as the `cwd` option of some APIs
will also cause errors.
### Extra Unpacking on Some APIs
Most `fs` APIs can read a file or get a file's information from ASAR archives
without unpacking, but for some APIs that rely on passing the real file path to
underlying system calls, Electron will extract the needed file into a
temporary file and pass the path of the temporary file to the APIs to make them
work. This adds a little overhead for those APIs.
APIs that requires extra unpacking are:
* `child_process.execFile`
* `child_process.execFileSync`
* `fs.open`
* `fs.openSync`
* `process.dlopen` - Used by `require` on native modules
### Fake Stat Information of `fs.stat`
The `Stats` object returned by `fs.stat` and its friends on files in `asar`
archives is generated by guessing, because those files do not exist on the
filesystem. So you should not trust the `Stats` object except for getting file
size and checking file type.
### Executing Binaries Inside ASAR archive
There are Node APIs that can execute binaries like `child_process.exec`,
`child_process.spawn` and `child_process.execFile`, but only `execFile` is
supported to execute binaries inside ASAR archive.
This is because `exec` and `spawn` accept `command` instead of `file` as input,
and `command`s are executed under shell. There is no reliable way to determine
whether a command uses a file in asar archive, and even if we do, we can not be
sure whether we can replace the path in command without side effects.
## Adding Unpacked Files to ASAR archives
As stated above, some Node APIs will unpack the file to the filesystem when
called. Apart from the performance issues, various anti-virus scanners might
be triggered by this behavior.
As a workaround, you can leave various files unpacked using the `--unpack` option.
In the following example, shared libraries of native Node.js modules will not be
packed:
```sh
$ asar pack app app.asar --unpack *.node
```
After running the command, you will notice that a folder named `app.asar.unpacked`
was created together with the `app.asar` file. It contains the unpacked files
and should be shipped together with the `app.asar` archive.

View File

@@ -1,53 +0,0 @@
---
title: 'ASAR Integrity'
description: 'An experimental feature that ensures the validity of ASAR contents at runtime.'
slug: asar-integrity
hide_title: false
---
## Platform Support
Currently ASAR integrity checking is only supported on macOS.
## Requirements
### Electron Forge / Electron Packager
If you are using `>= electron-packager@15.4.0` or `>= @electron-forge/core@6.0.0-beta.61` then all these requirements are met for you automatically and you can skip to [Toggling the Fuse](#toggling-the-fuse).
### Other build systems
In order to enable ASAR integrity checking you need to ensure that your `app.asar` file was generated by a version of the `asar` npm package that supports asar integrity. Support was introduced in version `3.1.0`.
Your must then populate a valid `ElectronAsarIntegrity` dictionary block in your packaged apps `Info.plist`. An example is included below.
```plist
<key>ElectronAsarIntegrity</key>
<dict>
<key>Resources/app.asar</key>
<dict>
<key>algorithm</key>
<string>SHA256</string>
<key>hash</key>
<string>9d1f61ea03c4bb62b4416387a521101b81151da0cfbe18c9f8c8b818c5cebfac</string>
</dict>
</dict>
```
Valid `algorithm` values are currently `SHA256` only. The `hash` is a hash of the ASAR header using the given algorithm. The `asar` package exposes a `getRawHeader` method whose result can then be hashed to generate this value.
## Toggling the Fuse
ASAR integrity checking is currently disabled by default and can be enabled by toggling a fuse. See [Electron Fuses](fuses.md) for more information on what Electron Fuses are and how they work. When enabling this fuse you typically also want to enable the `onlyLoadAppFromAsar` fuse otherwise the validity checking can be bypassed via the Electron app code search path.
```js
require('@electron/fuses').flipFuses(
// E.g. /a/b/Foo.app
pathToPackagedApp,
{
version: FuseVersion.V1,
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
[FuseV1Options.OnlyLoadAppFromAsar]: true
}
)
```

View File

@@ -22,7 +22,7 @@ There are a few ways that you can set up testing using WebDriver.
Node.js package for testing with WebDriver. Its ecosystem also includes various plugins
(e.g. reporter and services) that can help you put together your test setup.
#### Install the test runner
#### Install the testrunner
First you need to run the WebdriverIO starter toolkit in your project root directory:

View File

@@ -26,8 +26,10 @@ beginners, using a command line tool is likely to be helpful*.
## electron-forge
Electron Forge is a tool for packaging and publishing Electron applications. It unifies Electron's tooling ecosystem
into a single extensible interface so that anyone can jump right into making Electron apps.
A "complete tool for building modern Electron applications". Electron Forge
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
greater Electron community (like [`electron-packager`](https://github.com/electron/electron-packager))

View File

@@ -54,11 +54,85 @@ and notarized requires a few additions to your configuration. [Forge](https://el
collection of the official Electron tools, using [`electron-packager`],
[`electron-osx-sign`], and [`electron-notarize`] under the hood.
Detailed instructions on how to configure your application can be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-macos).
Let's take a look at an example `package.json` configuration with all required fields. Not all of them are
required: the tools will be clever enough to automatically find a suitable `identity`, for instance,
but we recommend that you are explicit.
```json title="package.json" {7}
{
"name": "my-app",
"version": "0.0.1",
"config": {
"forge": {
"packagerConfig": {
"osxSign": {
"identity": "Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)",
"hardened-runtime": true,
"entitlements": "entitlements.plist",
"entitlements-inherit": "entitlements.plist",
"signature-flags": "library"
},
"osxNotarize": {
"appleId": "felix@felix.fun",
"appleIdPassword": "my-apple-id-password"
}
}
}
}
}
```
The `entitlements.plist` file referenced here needs the following macOS-specific entitlements
to assure the Apple security mechanisms that your app is doing these things
without meaning any harm:
```xml title="entitlements.plist"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.debugger</key>
<true/>
</dict>
</plist>
```
Note that up until Electron 12, the `com.apple.security.cs.allow-unsigned-executable-memory` entitlement was required
as well. However, it should not be used anymore if it can be avoided.
To see all of this in action, check out Electron Fiddle's source code,
[especially its `electron-forge` configuration
file](https://github.com/electron/fiddle/blob/master/forge.config.js).
If you plan to access the microphone or camera within your app using Electron's APIs, you'll also
need to add the following entitlements:
```xml title="entitlements.plist"
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
```
If these are not present in your app's entitlements when you invoke, for example:
```js title="main.js"
const { systemPreferences } = require('electron')
const microphone = systemPreferences.askForMediaAccess('microphone')
```
Your app may crash. See the Resource Access section in [Hardened Runtime](https://developer.apple.com/documentation/security/hardened_runtime) for more information and entitlements you may need.
### Using Electron Builder
Electron Builder comes with a custom solution for signing your application. You
can find [its documentation here](https://www.electron.build/code-signing).
### Using Electron Packager
If you're not using an integrated build pipeline like Forge, you
If you're not using an integrated build pipeline like Forge or Builder, you
are likely using [`electron-packager`], which includes [`electron-osx-sign`] and
[`electron-notarize`].
@@ -130,7 +204,36 @@ commit it to your source code.
### Using Electron Forge
Electron Forge is the recommended way to sign your `Squirrel.Windows` and `WiX MSI` installers. Detailed instructions on how to configure your application can be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-macos).
Once you have a code signing certificate file (`.pfx`), you can sign
[Squirrel.Windows][maker-squirrel] and [MSI][maker-msi] installers in Electron Forge
with the `certificateFile` and `certificatePassword` fields in their respective
configuration objects.
For example, if you keep your Forge config in your `package.json` file and are
creating a Squirrel.Windows installer:
```json {9-15} title='package.json'
{
"name": "my-app",
"version": "0.0.1",
//...
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"certificateFile": "./cert.pfx",
"certificatePassword": "this-is-a-secret"
}
}
]
}
}
//...
}
```
### Using electron-winstaller (Squirrel.Windows)

View File

@@ -16,10 +16,6 @@ with bluetooth devices. In order to use this API in Electron, developers will
need to handle the [`select-bluetooth-device` event on the webContents](../api/web-contents.md#event-select-bluetooth-device)
associated with the device request.
Additionally, [`ses.setBluetoothPairingHandler(handler)`](../api/session.md#sessetbluetoothpairinghandlerhandler-windows-linux)
can be used to handle pairing to bluetooth devices on Windows or Linux when
additional validation such as a pin is needed.
### Example
This example demonstrates an Electron application that automatically selects

View File

@@ -11,7 +11,7 @@ you can deliver it to your users.
## Packaging
To distribute your app with Electron, you need to package all your resources and assets
into an executable and rebrand it. To do this, you can either use specialized tooling like Electron Forge
into an executable and rebrand it. To do this, you can either use specialized tooling
or do it manually. See the [Application Packaging][application-packaging] tutorial
for more information.

View File

@@ -9,27 +9,26 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
| Electron | Alpha | Beta | Stable | Chrome | Node | Supported |
| ------- | ----- | ------- | ------ | ------ | ---- | ---- |
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | M108 | TBD | ✅ |
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | M106 | v16.17 | ✅ |
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | M104 | v16.15 | ✅ |
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | M102 | v16.14 | ✅ |
| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | M100 | v16.13 | 🚫 |
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 | 🚫 |
| 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | M96 | v16.9 | 🚫 |
| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | v16.5 | 🚫 |
| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | M93 | v14.17 | 🚫 |
| 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | M91 | v14.16 | 🚫 |
| 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | M89 | v14.16 | 🚫 |
| 11.0.0 | -- | 2020-Aug-27 | 2020-Nov-17 | M87 | v12.18 | 🚫 |
| 10.0.0 | -- | 2020-May-21 | 2020-Aug-25 | M85 | v12.16 | 🚫 |
| 9.0.0 | -- | 2020-Feb-06 | 2020-May-19 | M83 | v12.14 | 🚫 |
| 8.0.0 | -- | 2019-Oct-24 | 2020-Feb-04 | M80 | v12.13 | 🚫 |
| 7.0.0 | -- | 2019-Aug-01 | 2019-Oct-22 | M78 | v12.8 | 🚫 |
| 6.0.0 | -- | 2019-May-01 | 2019-Jul-30 | M76 | v12.4 | 🚫 |
| 5.0.0 | -- | 2019-Jan-22 | 2019-Apr-24 | M73 | v12.0 | 🚫 |
| 4.0.0 | -- | 2018-Oct-11 | 2018-Dec-20 | M69 | v10.11 | 🚫 |
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | M66 | v10.2 | 🚫 |
| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | M61 | v8.9 | 🚫 |
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | M66 | v10.2 | 🚫 |
| 4.0.0 | -- | 2018-Oct-11 | 2018-Dec-20 | M69 | v10.11 | 🚫 |
| 5.0.0 | -- | 2019-Jan-22 | 2019-Apr-24 | M73 | v12.0 | 🚫 |
| 6.0.0 | -- | 2019-May-01 | 2019-Jul-30 | M76 | v12.4 | 🚫 |
| 7.0.0 | -- | 2019-Aug-01 | 2019-Oct-22 | M78 | v12.8 | 🚫 |
| 8.0.0 | -- | 2019-Oct-24 | 2020-Feb-04 | M80 | v12.13 | 🚫 |
| 9.0.0 | -- | 2020-Feb-06 | 2020-May-19 | M83 | v12.14 | 🚫 |
| 10.0.0 | -- | 2020-May-21 | 2020-Aug-25 | M85 | v12.16 | 🚫 |
| 11.0.0 | -- | 2020-Aug-27 | 2020-Nov-17 | M87 | v12.18 | 🚫 |
| 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | M89 | v14.16 | 🚫 |
| 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | M91 | v14.16 | 🚫 |
| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | M93 | v14.17 | 🚫 |
| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | v16.5 | 🚫 |
| 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | M96 | v16.9 | 🚫 |
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | M98 | v16.13 | 🚫 |
| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | M100 | v16.13 | ✅ |
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | M102 | v16.14 | ✅ |
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | M104 | v16.15 | ✅ |
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | M106 | TBD | ✅ |
**Notes:**

View File

@@ -1,36 +0,0 @@
# Distributing Apps With Electron Forge
Electron Forge is a tool for packaging and publishing Electron applications.
It unifies Electron's build tooling ecosystem into
a single extensible interface so that anyone can jump right into making Electron apps.
## Getting started
The [Electron Forge docs] contain detailed information on taking your application
from source code to your end users' machines.
This includes:
* Packaging your application [(package)]
* Generating executables and installers for each OS [(make)], and,
* Publishing these files to online platforms to download [(publish)].
For beginners, we recommend following through Electron's [tutorial] to develop, build,
package and publish your first Electron app. If you have already developed an app on your machine
and want to start on packaging and distribution, start from [step 5] of the tutorial.
## Getting help
* If you need help with developing your app, our [community Discord server][discord] is a great place
to get advice from other Electron app developers.
* If you suspect you're running into a bug with Forge, please check the [GitHub issue tracker]
to see if any existing issues match your problem. If not, feel free to fill out our bug report
template and submit a new issue.
[Electron Forge Docs]: https://www.electronforge.io/
[step 5]: ./tutorial-5-packaging.md
[(package)]: https://www.electronforge.io/cli#package
[(make)]: https://www.electronforge.io/cli#make
[(publish)]: https://www.electronforge.io/cli#publish
[GitHub issue tracker]: https://github.com/electron-userland/electron-forge/issues
[discord]: https://discord.gg/APGC3k5yaH
[tutorial]: https://www.electronjs.org/docs/latest/tutorial/tutorial-prerequisites

View File

@@ -8,59 +8,6 @@ For a subset of Electron functionality it makes sense to disable certain feature
Fuses are the solution to this problem, at a high level they are "magic bits" in the Electron binary that can be flipped when packaging your Electron app to enable / disable certain features / restrictions. Because they are flipped at package time before you code sign your app the OS becomes responsible for ensuring those bits aren't flipped back via OS level code signing validation (Gatekeeper / App Locker).
## Current Fuses
### `runAsNode`
**Default:** Enabled
**@electron/fuses:** `FuseV1Options.RunAsNode`
The runAsNode fuse toggles whether the `ELECTRON_RUN_AS_NODE` environment variable is respected or not. Please note that if this fuse is disabled then `process.fork` in the main process will not function as expected as it depends on this environment variable to function.
### `cookieEncryption`
**Default:** Disabled
**@electron/fuses:** `FuseV1Options.EnableCookieEncryption`
The cookieEncryption fuse toggles whether the cookie store on disk is encrypted using OS level cryptography keys. By default the sqlite database that Chromium uses to store cookies stores the values in plaintext. If you wish to ensure your apps cookies are encrypted in the same way Chrome does then you should enable this fuse. Please note it is a one-way transition, if you enable this fuse existing unencrypted cookies will be encrypted-on-write but if you then disable the fuse again your cookie store will effectively be corrupt and useless. Most apps can safely enable this fuse.
### `nodeOptions`
**Default:** Enabled
**@electron/fuses:** `FuseV1Options.EnableNodeOptionsEnvironmentVariable`
The nodeOptions fuse toggles whether the [`NODE_OPTIONS`](https://nodejs.org/api/cli.html#node_optionsoptions) environment variable is respected or not. This environment variable can be used to pass all kinds of custom options to the Node.js runtime and isn't typically used by apps in production. Most apps can safely disable this fuse.
### `nodeCliInspect`
**Default:** Enabled
**@electron/fuses:** `FuseV1Options.EnableNodeCliInspectArguments`
The nodeCliInspect fuse toggles whether the `--inspect`, `--inspect-brk`, etc. flags are respected or not. When disabled it also ensures that `SIGUSR1` signal does not initialize the main process inspector. Most apps can safely disable this fuse.
### `embeddedAsarIntegrityValidation`
**Default:** Disabled
**@electron/fuses:** `FuseV1Options.EnableEmbeddedAsarIntegrityValidation`
The embeddedAsarIntegrityValidation fuse toggles an experimental feature on macOS that validates the content of the `app.asar` file when it is loaded. This feature is designed to have a minimal performance impact but may marginally slow down file reads from inside the `app.asar` archive.
For more information on how to use asar integrity validation please read the [Asar Integrity](asar-integrity.md) documentation.
### `onlyLoadAppFromAsar`
**Default:** Disabled
**@electron/fuses:** `FuseV1Options.OnlyLoadAppFromAsar`
The onlyLoadAppFromAsar fuse changes the search system that Electron uses to locate your app code. By default Electron will search in the following order `app.asar` -> `app` -> `default_app.asar`. When this fuse is enabled the search order becomes a single entry `app.asar` thus ensuring that when combined with the `embeddedAsarIntegrityValidation` fuse it is impossible to load non-validated code.
### `loadBrowserProcessSpecificV8Snapshot`
**Default:** Disabled
**@electron/fuses:** `FuseV1Options.LoadBrowserProcessSpecificV8Snapshot`
The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is used for the browser process. By default Electron's processes will all use the same V8 snapshot file. When this fuse is enabled the browser process uses the file called `browser_v8_context_snapshot.bin` for its V8 snapshot. The other processes will use the V8 snapshot file that they normally do.
## How do I flip the fuses?
### The easy way
@@ -73,18 +20,11 @@ require('@electron/fuses').flipFuses(
require('electron'),
// Fuses to flip
{
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false
runAsNode: false
}
)
```
You can validate the fuses have been flipped or check the fuse status of an arbitrary Electron app using the fuses CLI.
```bash
npx @electron/fuses read --app /Applications/Foo.app
```
### The hard way
#### Quick Glossary

View File

@@ -101,7 +101,7 @@ app.whenReady().then(async () => {
}
})
const secondaryWindow = new BrowserWindow({
const secondaryWindow = BrowserWindow({
show: false,
webPreferences: {
contextIsolation: false,
@@ -144,7 +144,7 @@ to use `contextIsolation` and set up specific contextBridge calls for each of yo
expected messages, but for the simplicity of this example we don't. You can find an
example of context isolation further down this page at [Communicating directly between the main process and the main world of a context-isolated page](#communicating-directly-between-the-main-process-and-the-main-world-of-a-context-isolated-page)
That means window.electronMessagePort is globally available and you can call
That means window.messagePort is globally available and you can call
`postMessage` on it from anywhere in your app to send a message to the other
renderer.
@@ -272,7 +272,7 @@ const makeStreamingRequest = (element, callback) => {
}
makeStreamingRequest(42, (data) => {
console.log('got response data:', data)
console.log('got response data:', event.data)
})
// We will see "got response data: 42" 10 times.
```

View File

@@ -20,8 +20,6 @@ const win = new BrowserWindow({
The `nodeIntegrationInWorker` can be used independent of `nodeIntegration`, but
`sandbox` must not be set to `true`.
**Note:** This option is not available in [`SharedWorker`s](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker) or [`Service Worker`s](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker) owing to incompatibilities in sandboxing policies.
## Available APIs
All built-in modules of Node.js are supported in Web Workers, and `asar`

View File

@@ -419,18 +419,6 @@ environment that needs to handle both Node.js and browser environments.
As of writing this article, the popular choices include [Webpack][webpack],
[Parcel][parcel], and [rollup.js][rollup].
### 8. Call `Menu.setApplicationMenu(null)` when you do not need a default menu
Electron will set a default menu on startup with some standard entries. But there are reasons your application might want to change that and it will benefit startup performance.
#### Why?
If you build your own menu or use a frameless window without native menu, you should tell Electron early enough to not setup the default menu.
#### How?
Call `Menu.setApplicationMenu(null)` before `app.on("ready")`. This will prevent Electron from setting a default menu. See also https://github.com/electron/electron/issues/35512 for a related discussion.
[security]: ./security.md
[chrome-devtools-tutorial]: https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/
[worker-threads]: https://nodejs.org/api/worker_threads.html

View File

@@ -12,10 +12,28 @@ the GPU service and the network service.
See Chromium's [Sandbox design document][sandbox] for more information.
Starting from Electron 20, the sandbox is enabled for renderer processes without any
further configuration. If you want to disable the sandbox for a process, see the
[Disabling the sandbox for a single process](#disabling-the-sandbox-for-a-single-process)
section.
## Electron's sandboxing policies
Electron comes with a mixed sandbox environment, meaning sandboxed processes can run
alongside privileged ones. By default, renderer processes are not sandboxed, but
utility processes are. Note that as in Chromium, the main (browser) process is
privileged and cannot be sandboxed.
Historically, this mixed sandbox approach was established because having Node.js available
in the renderer is an extremely powerful tool for app developers. Unfortunately, this
feature is also an equally massive security vulnerability.
Theoretically, unsandboxed renderers are not a problem for desktop applications that
only display trusted code, but they make Electron less secure than Chromium for
displaying untrusted web content. However, even purportedly trusted code may be
dangerous — there are countless attack vectors that malicious actors can use, from
cross-site scripting to content injection to man-in-the-middle attacks on remotely loaded
websites, just to name a few. For this reason, we recommend enabling renderer sandboxing
for the vast majority of cases under an abundance of caution.
<!--TODO: update this guide when #28466 is either solved or closed -->
Note that there is an active discussion in the issue tracker to enable renderer sandboxing
by default. See [#28466][issue-28466]) for details.
## Sandbox behaviour in Electron
@@ -28,17 +46,12 @@ When renderer processes in Electron are sandboxed, they behave in the same way a
regular Chrome renderer would. A sandboxed renderer won't have a Node.js
environment initialized.
<!-- TODO(erickzhao): when we have a solid guide for IPC, link it here -->
Therefore, when the sandbox is enabled, renderer processes can only perform privileged
tasks (such as interacting with the filesystem, making changes to the system, or spawning
subprocesses) by delegating these tasks to the main process via inter-process
communication (IPC).
:::note
For more info on inter-process communication, check out our [IPC guide](./ipc.md).
:::
### Preload scripts
In order to allow renderer processes to communicate with the main process, preload
@@ -53,7 +66,7 @@ but can only import a subset of Electron and Node's built-in modules:
In addition, the preload script also polyfills certain Node.js primitives as globals:
* [`Buffer`](https://nodejs.org/api/buffer.html)
* [`Buffer`](https://nodejs.org/api/Buffer.html)
* [`process`](../api/process.md)
* [`clearImmediate`](https://nodejs.org/api/timers.html#timers_clearimmediate_immediate)
* [`setImmediate`](https://nodejs.org/api/timers.html#timers_setimmediate_callback_args)
@@ -70,17 +83,13 @@ privileged APIs to untrusted code running in the renderer process unless
## Configuring the sandbox
For most apps, sandboxing is the best choice. In certain use cases that are incompatible with
the sandbox (for instance, when using native node modules in the renderer),
it is possible to disable the sandbox for specific processes. This comes with security
risks, especially if any untrusted code or content is present in the unsandboxed process.
### Enabling the sandbox for a single process
### Disabling the sandbox for a single process
In Electron, renderer sandboxing can be enabled on a per-process basis with
the `sandbox: true` preference in the [`BrowserWindow`][browser-window] constructor.
In Electron, renderer sandboxing can be disabled on a per-process basis with
the `sandbox: false` preference in the [`BrowserWindow`][browser-window] constructor.
```js title='main.js'
```js
// main.js
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
@@ -91,30 +100,17 @@ app.whenReady().then(() => {
})
```
Sandboxing is also disabled whenever Node.js integration is enabled in the renderer.
This can be done through the BrowserWindow constructor with the `nodeIntegration: true` flag.
```js title='main.js'
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
})
win.loadURL('https://google.com')
})
```
### Enabling the sandbox globally
If you want to force sandboxing for all renderers, you can also use the
[`app.enableSandbox`][enable-sandbox] API. Note that this API has to be called before the
app's `ready` event.
```js title='main.js'
```js
// main.js
app.enableSandbox()
app.whenReady().then(() => {
// any sandbox:false calls are overridden since `app.enableSandbox()` was called.
// no need to pass `sandbox: true` since `app.enableSandbox()` was called.
const win = new BrowserWindow()
win.loadURL('https://google.com')
})
@@ -143,16 +139,16 @@ issues:
have, to inherit everything we can from Chromium, and to respond quickly to
security issues, but Electron cannot be as secure as Chromium without the
resources that Chromium is able to dedicate.
1. Some security features in Chrome (such as Safe Browsing and Certificate
2. Some security features in Chrome (such as Safe Browsing and Certificate
Transparency) require a centralized authority and dedicated servers, both of
which run counter to the goals of the Electron project. As such, we disable
those features in Electron, at the cost of the associated security they
would otherwise bring.
1. There is only one Chromium, whereas there are many thousands of apps built
3. There is only one Chromium, whereas there are many thousands of apps built
on Electron, all of which behave slightly differently. Accounting for those
differences can yield a huge possibility space, and make it challenging to
ensure the security of the platform in unusual use cases.
1. We can't push security updates to users directly, so we rely on app vendors
4. We can't push security updates to users directly, so we rely on app vendors
to upgrade the version of Electron underlying their app in order for
security updates to reach users.

View File

@@ -113,7 +113,6 @@ You should at least follow these steps to improve the security of your applicati
14. [Disable or limit creation of new windows](#14-disable-or-limit-creation-of-new-windows)
15. [Do not use `shell.openExternal` with untrusted content](#15-do-not-use-shellopenexternal-with-untrusted-content)
16. [Use a current version of Electron](#16-use-a-current-version-of-electron)
17. [Validate the `sender` of all IPC messages](#17-validate-the-sender-of-all-ipc-messages)
To automate the detection of misconfigurations and insecure patterns, it is
possible to use
@@ -131,8 +130,10 @@ like `HTTP`. Similarly, we recommend the use of `WSS` over `WS`, `FTPS` over
#### Why?
`HTTPS` has two main benefits:
`HTTPS` has three main benefits:
1. It authenticates the remote server, ensuring your app connects to the correct
host instead of an impersonator.
1. It ensures data integrity, asserting that the data was not modified while in
transit between your application and the host.
1. It encrypts the traffic between your user and the destination host, making it
@@ -255,7 +256,7 @@ the sandbox in all renderers. Loading, reading or processing any untrusted
content in an unsandboxed process, including the main process, is not advised.
:::info
For more information on what Process Sandboxing is and how to enable it please
For more information on what `contextIsolation` is and how to enable it please
see our dedicated [Process Sandboxing](sandbox.md) document.
:::info

View File

@@ -237,6 +237,8 @@ apps:
desktop: usr/share/applications/desktop.desktop
```
[snapcraft.io]: https://snapcraft.io/
[snapcraft-store]: https://snapcraft.io/store/
[snapcraft-syntax]: https://docs.snapcraft.io/build-snaps/syntax
[electron-packager]: https://github.com/electron/electron-packager
[electron-forge]: https://github.com/electron-userland/electron-forge

View File

@@ -0,0 +1,95 @@
# Testing Widevine CDM
In Electron you can use the Widevine CDM library shipped with Chrome browser.
Widevine Content Decryption Modules (CDMs) are how streaming services protect
content using HTML5 video to web browsers without relying on an NPAPI plugin
like Flash or Silverlight. Widevine support is an alternative solution for
streaming services that currently rely on Silverlight for playback of
DRM-protected video content. It will allow websites to show DRM-protected video
content in Firefox without the use of NPAPI plugins. The Widevine CDM runs in an
open-source CDM sandbox providing better user security than NPAPI plugins.
#### Note on VMP
As of [`Electron v1.8.0 (Chrome v59)`](https://electronjs.org/releases#1.8.1),
the below steps are may only be some of the necessary steps to enable Widevine;
any app on or after that version intending to use the Widevine CDM may need to
be signed using a license obtained from [Widevine](https://www.widevine.com/)
itself.
Per [Widevine](https://www.widevine.com/):
> Chrome 59 (and later) includes support for Verified Media Path (VMP). VMP
> provides a method to verify the authenticity of a device platform. For browser
> deployments, this will provide an additional signal to determine if a
> browser-based implementation is reliable and secure.
>
> The proxy integration guide has been updated with information about VMP and
> how to issue licenses.
>
> Widevine recommends our browser-based integrations (vendors and browser-based
> applications) add support for VMP.
To enable video playback with this new restriction,
[castLabs](https://castlabs.com/open-source/downstream/) has created a
[fork](https://github.com/castlabs/electron-releases) that has implemented the
necessary changes to enable Widevine to be played in an Electron application if
one has obtained the necessary licenses from widevine.
## Getting the library
Open `chrome://components/` in Chrome browser, find `Widevine Content Decryption Module`
and make sure it is up to date, then you can find the library files from the
application directory.
### On Windows
The library file `widevinecdm.dll` will be under
`Program Files(x86)/Google/Chrome/Application/CHROME_VERSION/WidevineCdm/_platform_specific/win_(x86|x64)/`
directory.
### On macOS
The library file `libwidevinecdm.dylib` will be under
`/Applications/Google Chrome.app/Contents/Versions/CHROME_VERSION/Google Chrome Framework.framework/Versions/A/Libraries/WidevineCdm/_platform_specific/mac_(x86|x64)/`
directory.
**Note:** Make sure that chrome version used by Electron is greater than or
equal to the `min_chrome_version` value of Chrome's widevine cdm component.
The value can be found in `manifest.json` under `WidevineCdm` directory.
## Using the library
After getting the library files, you should pass the path to the file
with `--widevine-cdm-path` command line switch, and the library's version
with `--widevine-cdm-version` switch. The command line switches have to be
passed before the `ready` event of `app` module gets emitted.
Example code:
```javascript
const { app, BrowserWindow } = require('electron')
// You have to pass the directory that contains widevine library here, it is
// * `libwidevinecdm.dylib` on macOS,
// * `widevinecdm.dll` on Windows.
app.commandLine.appendSwitch('widevine-cdm-path', '/path/to/widevine_library')
// The version of plugin can be got from `chrome://components` page in Chrome.
app.commandLine.appendSwitch('widevine-cdm-version', '1.4.8.866')
let win = null
app.whenReady().then(() => {
win = new BrowserWindow()
win.show()
})
```
## Verifying Widevine CDM support
To verify whether widevine works, you can use following ways:
* Open https://shaka-player-demo.appspot.com/ and load a manifest that uses
`Widevine`.
* Open http://www.dash-player.com/demo/drm-test-area/, check whether the page
says `bitdash uses Widevine in your browser`, then play the video.

View File

@@ -123,7 +123,7 @@ the list of versions in the [electron/releases] repository.
[homebrew]: https://brew.sh/
[mdn-guide]: https://developer.mozilla.org/en-US/docs/Learn/
[node]: https://nodejs.org/
[node-guide]: https://nodejs.dev/en/learn/
[node-guide]: https://nodejs.dev/learn
[node-download]: https://nodejs.org/en/download/
[nvm]: https://github.com/nvm-sh/nvm
[process-model]: ./process-model.md

View File

@@ -186,7 +186,7 @@ by creating a barebones web page in an `index.html` file in the root folder of y
```
Now that you have a web page, you can load it into an Electron [BrowserWindow][browser-window].
Replace the contents of your `main.js` file with the following code. We will explain each
Replace the contents your `main.js` file with the following code. We will explain each
highlighted block separately.
```js {1,3-10,12-14} title='main.js' showLineNumbers
@@ -369,12 +369,12 @@ run. Create a launch.json configuration in a new `.vscode` folder in your projec
"name": "Renderer",
"port": 9222,
"request": "attach",
"type": "chrome",
"type": "pwa-chrome",
"webRoot": "${workspaceFolder}"
},
{
"name": "Main",
"type": "node",
"type": "pwa-node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
@@ -398,11 +398,11 @@ What we have done in the `launch.json` file is to create 3 configurations:
- `Main` is used to start the main process and also expose port 9222 for remote debugging
(`--remote-debugging-port=9222`). This is the port that we will use to attach the debugger
for the `Renderer`. Because the main process is a Node.js process, the type is set to
`node`.
`pwa-node` (`pwa-` is the prefix that tells VS Code to use the latest JavaScript debugger).
- `Renderer` is used to debug the renderer process. Because the main process is the one
that creates the process, we have to "attach" to it (`"request": "attach"`) instead of
creating a new one.
The renderer process is a web one, so the debugger we have to use is `chrome`.
The renderer process is a web one, so the debugger we have to use is `pwa-chrome`.
- `Main + renderer` is a [compound task] that executes the previous ones simultaneously.
:::caution
@@ -435,7 +435,7 @@ This file controls Electron's **main process**, which runs an instance of Node.j
responsible for your app's lifecycle, displaying native interfaces, performing privileged operations,
and managing renderer processes.
**Renderer processes** (or renderers for short) are responsible for displaying graphical content. You can
**Renderer processes** (or renderers for short) are responsible for display graphical content. You can
load a web page into a renderer by pointing it to either a web address or a local HTML file.
Renderers behave very similarly to regular web pages and have access to the same web APIs.

View File

@@ -38,25 +38,7 @@ called a **preload**.
## Augmenting the renderer with a preload script
A BrowserWindow's preload script runs in a context that has access to both the HTML DOM
and a limited subset of Node.js and Electron APIs.
:::info Preload script sandboxing
From Electron 20 onwards, preload scripts are **sandboxed** by default and no longer have access
to a full Node.js environment. Practically, this means that you have a polyfilled `require`
function that only has access to a limited set of APIs.
| Available API | Details |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Electron modules | Renderer process modules |
| Node.js modules | [`events`](https://nodejs.org/api/events.html), [`timers`](https://nodejs.org/api/timers.html), [`url`](https://nodejs.org/api/url.html) |
| Polyfilled globals | [`Buffer`](https://nodejs.org/api/buffer.html), [`process`](../api/process.md), [`clearImmediate`](https://nodejs.org/api/timers.html#timers_clearimmediate_immediate), [`setImmediate`](https://nodejs.org/api/timers.html#timers_setimmediate_callback_args) |
For more information, check out the [Process Sandboxing](./sandbox.md) guide.
:::
Preload scripts are injected before a web page loads in the renderer,
and a Node.js environment. Preload scripts are injected before a web page loads in the renderer,
similar to a Chrome extension's [content scripts][content-script]. To add features to your renderer
that require privileged access, you can define [global] objects through the
[contextBridge][contextbridge] API.
@@ -203,8 +185,7 @@ loading the HTML file so that the handler is guaranteed to be ready before
you send out the `invoke` call from the renderer.
```js {1,11} title="main.js"
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const { ipcMain } = require('electron')
const createWindow = () => {
const win = new BrowserWindow({
@@ -217,7 +198,6 @@ const createWindow = () => {
ipcMain.handle('ping', () => 'pong')
win.loadFile('index.html')
}
app.whenReady().then(createWindow)
```
Once you have the sender and receiver set up, you can now send messages from the renderer

View File

@@ -111,12 +111,6 @@ Electron Forge can be configured to create distributables in different OS-specif
:::
:::tip Creating and Adding Application Icons
Setting custom application icons requires a few additions to your config. Check out [Forge's icon tutorial] for more information.
:::
:::note Packaging without Electron Forge
If you want to manually package your code, or if you're just interested understanding the
@@ -220,7 +214,6 @@ information.
[electron forge]: https://www.electronforge.io
[electron forge cli documentation]: https://www.electronforge.io/cli#commands
[makers]: https://www.electronforge.io/config/makers
[Forge's icon tutorial]: https://www.electronforge.io/guides/create-and-add-icons
<!-- Tutorial links -->

View File

@@ -98,6 +98,7 @@ auto_filenames = {
"docs/api/structures/mime-typed-buffer.md",
"docs/api/structures/mouse-input-event.md",
"docs/api/structures/mouse-wheel-input-event.md",
"docs/api/structures/new-window-web-contents-event.md",
"docs/api/structures/notification-action.md",
"docs/api/structures/notification-response.md",
"docs/api/structures/payment-discount.md",
@@ -136,11 +137,11 @@ auto_filenames = {
]
sandbox_bundle_deps = [
"lib/common/api/deprecate.ts",
"lib/common/api/native-image.ts",
"lib/common/define-properties.ts",
"lib/common/ipc-messages.ts",
"lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.ts",
"lib/renderer/api/ipc-renderer.ts",
@@ -238,11 +239,11 @@ auto_filenames = {
"lib/browser/rpc-server.ts",
"lib/browser/web-view-events.ts",
"lib/common/api/clipboard.ts",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/native-image.ts",
"lib/common/api/shell.ts",
"lib/common/define-properties.ts",
"lib/common/deprecate.ts",
"lib/common/init.ts",
"lib/common/ipc-messages.ts",
"lib/common/reset-search-paths.ts",
@@ -259,6 +260,7 @@ auto_filenames = {
renderer_bundle_deps = [
"lib/common/api/clipboard.ts",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/native-image.ts",
"lib/common/api/shell.ts",
@@ -297,6 +299,7 @@ auto_filenames = {
worker_bundle_deps = [
"lib/common/api/clipboard.ts",
"lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts",
"lib/common/api/native-image.ts",
"lib/common/api/shell.ts",

View File

@@ -463,6 +463,8 @@ filenames = {
"shell/browser/notifications/platform_notification_service.h",
"shell/browser/plugins/plugin_utils.cc",
"shell/browser/plugins/plugin_utils.h",
"shell/browser/pref_store_delegate.cc",
"shell/browser/pref_store_delegate.h",
"shell/browser/protocol_registry.cc",
"shell/browser/protocol_registry.h",
"shell/browser/relauncher.cc",
@@ -505,6 +507,8 @@ filenames = {
"shell/browser/ui/tray_icon_observer.h",
"shell/browser/ui/webui/accessibility_ui.cc",
"shell/browser/ui/webui/accessibility_ui.h",
"shell/browser/unresponsive_suppressor.cc",
"shell/browser/unresponsive_suppressor.h",
"shell/browser/web_contents_permission_helper.cc",
"shell/browser/web_contents_permission_helper.h",
"shell/browser/web_contents_preferences.cc",
@@ -515,8 +519,6 @@ filenames = {
"shell/browser/web_view_guest_delegate.h",
"shell/browser/web_view_manager.cc",
"shell/browser/web_view_manager.h",
"shell/browser/webauthn/electron_authenticator_request_delegate.cc",
"shell/browser/webauthn/electron_authenticator_request_delegate.h",
"shell/browser/window_list.cc",
"shell/browser/window_list.h",
"shell/browser/window_list_observer.h",
@@ -575,8 +577,6 @@ filenames = {
"shell/common/gin_converters/hid_device_info_converter.h",
"shell/common/gin_converters/image_converter.cc",
"shell/common/gin_converters/image_converter.h",
"shell/common/gin_converters/media_converter.cc",
"shell/common/gin_converters/media_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",
@@ -675,6 +675,8 @@ filenames = {
"shell/renderer/electron_renderer_pepper_host_factory.h",
"shell/renderer/electron_sandboxed_renderer_client.cc",
"shell/renderer/electron_sandboxed_renderer_client.h",
"shell/renderer/guest_view_container.cc",
"shell/renderer/guest_view_container.h",
"shell/renderer/renderer_client_base.cc",
"shell/renderer/renderer_client_base.h",
"shell/renderer/web_worker_observer.cc",

View File

@@ -1,6 +1,7 @@
libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/CMakeLists.txt",
"//buildtools/third_party/libc++/trunk/include/__algorithm/adjacent_find.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/algorithm_family.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/all_of.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/any_of.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/binary_search.h",
@@ -73,7 +74,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_all_of.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_any_of.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_binary_search.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_clamp.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_copy.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_copy_backward.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_copy_if.h",
@@ -98,7 +98,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_is_heap.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_is_heap_until.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_is_partitioned.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_is_permutation.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_is_sorted.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_is_sorted_until.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_iterator_concept.h",
@@ -115,7 +114,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_mismatch.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_move.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_move_backward.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_next_permutation.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_none_of.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_nth_element.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_partial_sort.h",
@@ -124,7 +122,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_partition_copy.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_partition_point.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_pop_heap.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_prev_permutation.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_push_heap.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_remove.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_remove_copy.h",
@@ -136,9 +133,7 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_replace_if.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_reverse.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_reverse_copy.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_rotate.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_rotate_copy.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_sample.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_search.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_search_n.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_set_difference.h",
@@ -184,7 +179,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__algorithm/stable_sort.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/swap_ranges.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/transform.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/uniform_random_bit_generator_adaptor.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/unique.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/unique_copy.h",
"//buildtools/third_party/libc++/trunk/include/__algorithm/unwrap_iter.h",
@@ -205,20 +199,15 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__charconv/to_chars_result.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/calendar.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/convert_to_timespec.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/convert_to_tm.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/day.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/duration.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/file_clock.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/formatter.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/hh_mm_ss.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/high_resolution_clock.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/literals.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/month.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/month_weekday.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/monthday.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/ostream.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/parser_std_format_spec.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/statically_widen.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/steady_clock.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/system_clock.h",
"//buildtools/third_party/libc++/trunk/include/__chrono/time_point.h",
@@ -296,7 +285,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__format/format_args.h",
"//buildtools/third_party/libc++/trunk/include/__format/format_context.h",
"//buildtools/third_party/libc++/trunk/include/__format/format_error.h",
"//buildtools/third_party/libc++/trunk/include/__format/format_functions.h",
"//buildtools/third_party/libc++/trunk/include/__format/format_fwd.h",
"//buildtools/third_party/libc++/trunk/include/__format/format_parse_context.h",
"//buildtools/third_party/libc++/trunk/include/__format/format_string.h",
@@ -340,13 +328,8 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__functional/unary_negate.h",
"//buildtools/third_party/libc++/trunk/include/__functional/unwrap_ref.h",
"//buildtools/third_party/libc++/trunk/include/__functional/weak_result_type.h",
"//buildtools/third_party/libc++/trunk/include/__fwd/array.h",
"//buildtools/third_party/libc++/trunk/include/__fwd/get.h",
"//buildtools/third_party/libc++/trunk/include/__fwd/hash.h",
"//buildtools/third_party/libc++/trunk/include/__fwd/pair.h",
"//buildtools/third_party/libc++/trunk/include/__fwd/span.h",
"//buildtools/third_party/libc++/trunk/include/__fwd/string_view.h",
"//buildtools/third_party/libc++/trunk/include/__fwd/tuple.h",
"//buildtools/third_party/libc++/trunk/include/__hash_table",
"//buildtools/third_party/libc++/trunk/include/__ios/fpos.h",
"//buildtools/third_party/libc++/trunk/include/__iterator/access.h",
@@ -390,7 +373,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__locale",
"//buildtools/third_party/libc++/trunk/include/__mbstate_t.h",
"//buildtools/third_party/libc++/trunk/include/__memory/addressof.h",
"//buildtools/third_party/libc++/trunk/include/__memory/align.h",
"//buildtools/third_party/libc++/trunk/include/__memory/allocate_at_least.h",
"//buildtools/third_party/libc++/trunk/include/__memory/allocation_guard.h",
"//buildtools/third_party/libc++/trunk/include/__memory/allocator.h",
@@ -398,18 +380,15 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__memory/allocator_traits.h",
"//buildtools/third_party/libc++/trunk/include/__memory/assume_aligned.h",
"//buildtools/third_party/libc++/trunk/include/__memory/auto_ptr.h",
"//buildtools/third_party/libc++/trunk/include/__memory/builtin_new_allocator.h",
"//buildtools/third_party/libc++/trunk/include/__memory/compressed_pair.h",
"//buildtools/third_party/libc++/trunk/include/__memory/concepts.h",
"//buildtools/third_party/libc++/trunk/include/__memory/construct_at.h",
"//buildtools/third_party/libc++/trunk/include/__memory/destruct_n.h",
"//buildtools/third_party/libc++/trunk/include/__memory/pointer_traits.h",
"//buildtools/third_party/libc++/trunk/include/__memory/ranges_construct_at.h",
"//buildtools/third_party/libc++/trunk/include/__memory/ranges_uninitialized_algorithms.h",
"//buildtools/third_party/libc++/trunk/include/__memory/raw_storage_iterator.h",
"//buildtools/third_party/libc++/trunk/include/__memory/shared_ptr.h",
"//buildtools/third_party/libc++/trunk/include/__memory/swap_allocator.h",
"//buildtools/third_party/libc++/trunk/include/__memory/temp_value.h",
"//buildtools/third_party/libc++/trunk/include/__memory/temporary_buffer.h",
"//buildtools/third_party/libc++/trunk/include/__memory/uninitialized_algorithms.h",
"//buildtools/third_party/libc++/trunk/include/__memory/unique_ptr.h",
@@ -515,6 +494,7 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__support/solaris/floatingpoint.h",
"//buildtools/third_party/libc++/trunk/include/__support/solaris/wchar.h",
"//buildtools/third_party/libc++/trunk/include/__support/solaris/xlocale.h",
"//buildtools/third_party/libc++/trunk/include/__support/win32/limits_msvc_win32.h",
"//buildtools/third_party/libc++/trunk/include/__support/win32/locale_win32.h",
"//buildtools/third_party/libc++/trunk/include/__support/xlocale/__nop_locale_mgmt.h",
"//buildtools/third_party/libc++/trunk/include/__support/xlocale/__posix_l_fallback.h",
@@ -523,14 +503,7 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__thread/timed_backoff_policy.h",
"//buildtools/third_party/libc++/trunk/include/__threading_support",
"//buildtools/third_party/libc++/trunk/include/__tree",
"//buildtools/third_party/libc++/trunk/include/__tuple/apply_cv.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/make_tuple_types.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/sfinae_helpers.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_element.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_indices.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_like.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_size.h",
"//buildtools/third_party/libc++/trunk/include/__tuple/tuple_types.h",
"//buildtools/third_party/libc++/trunk/include/__tuple",
"//buildtools/third_party/libc++/trunk/include/__type_traits/add_const.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/add_cv.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/add_lvalue_reference.h",
@@ -541,7 +514,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__type_traits/aligned_union.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/alignment_of.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/apply_cv.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/can_extract_key.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/common_reference.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/common_type.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/conditional.h",
@@ -549,7 +521,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__type_traits/copy_cv.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/copy_cvref.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/decay.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/dependent_type.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/disjunction.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/enable_if.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/extent.h",
@@ -558,14 +529,12 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__type_traits/integral_constant.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_abstract.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_aggregate.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_allocator.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_arithmetic.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_array.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_assignable.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_base_of.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_bounded_array.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_callable.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_char_like_type.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_class.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_compound.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_const.h",
@@ -583,7 +552,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_floating_point.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_function.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_fundamental.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_implicitly_default_constructible.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_integral.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_literal_type.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_member_function_pointer.h",
@@ -615,7 +583,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_signed.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_signed_integer.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_standard_layout.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_swappable.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_trivial.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_trivially_assignable.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_trivially_constructible.h",
@@ -635,25 +602,20 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_volatile.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/lazy.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/make_32_64_or_128_bit.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/make_const_lvalue_ref.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/make_signed.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/make_unsigned.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/maybe_const.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/nat.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/negation.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/noexcept_move_assign_container.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/promote.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/rank.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/remove_all_extents.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/remove_const.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/remove_const_ref.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/remove_cv.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/remove_cvref.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/remove_extent.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/remove_pointer.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/remove_reference.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/remove_volatile.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/result_of.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/type_identity.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/type_list.h",
"//buildtools/third_party/libc++/trunk/include/__type_traits/underlying_type.h",
@@ -662,11 +624,9 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__utility/as_const.h",
"//buildtools/third_party/libc++/trunk/include/__utility/auto_cast.h",
"//buildtools/third_party/libc++/trunk/include/__utility/cmp.h",
"//buildtools/third_party/libc++/trunk/include/__utility/convert_to_integral.h",
"//buildtools/third_party/libc++/trunk/include/__utility/declval.h",
"//buildtools/third_party/libc++/trunk/include/__utility/exchange.h",
"//buildtools/third_party/libc++/trunk/include/__utility/forward.h",
"//buildtools/third_party/libc++/trunk/include/__utility/forward_like.h",
"//buildtools/third_party/libc++/trunk/include/__utility/in_place.h",
"//buildtools/third_party/libc++/trunk/include/__utility/integer_sequence.h",
"//buildtools/third_party/libc++/trunk/include/__utility/move.h",
@@ -679,7 +639,6 @@ libcxx_headers = [
"//buildtools/third_party/libc++/trunk/include/__utility/transaction.h",
"//buildtools/third_party/libc++/trunk/include/__utility/unreachable.h",
"//buildtools/third_party/libc++/trunk/include/__variant/monostate.h",
"//buildtools/third_party/libc++/trunk/include/__verbose_abort",
"//buildtools/third_party/libc++/trunk/include/algorithm",
"//buildtools/third_party/libc++/trunk/include/any",
"//buildtools/third_party/libc++/trunk/include/array",

View File

@@ -60,8 +60,8 @@ const splitPath = (archivePathOrBuffer: string | Buffer) => {
// Convert asar archive's Stats object to fs's Stats object.
let nextInode = 0;
const uid = process.getuid?.() ?? 0;
const gid = process.getgid?.() ?? 0;
const uid = process.getuid != null ? process.getuid() : 0;
const gid = process.getgid != null ? process.getgid() : 0;
const fakeTime = new Date();
@@ -263,7 +263,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
};
const { lstat } = fs;
fs.lstat = (pathArgument: string, options: any, callback: any) => {
fs.lstat = function (pathArgument: string, options: any, callback: any) {
const pathInfo = splitPath(pathArgument);
if (typeof options === 'function') {
callback = options;
@@ -382,10 +382,10 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
fs.promises.realpath = util.promisify(fs.realpath.native);
const { exists: nativeExists } = fs;
fs.exists = function exists (pathArgument: string, callback: any) {
const { exists } = fs;
fs.exists = (pathArgument: string, callback: any) => {
const pathInfo = splitPath(pathArgument);
if (!pathInfo.isAsar) return nativeExists(pathArgument, callback);
if (!pathInfo.isAsar) return exists(pathArgument, callback);
const { asarPath, filePath } = pathInfo;
const archive = getOrCreateArchive(asarPath);
@@ -399,9 +399,9 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
nextTick(callback, [pathExists]);
};
fs.exists[util.promisify.custom] = function exists (pathArgument: string) {
fs.exists[util.promisify.custom] = (pathArgument: string) => {
const pathInfo = splitPath(pathArgument);
if (!pathInfo.isAsar) return nativeExists[util.promisify.custom](pathArgument);
if (!pathInfo.isAsar) return exists[util.promisify.custom](pathArgument);
const { asarPath, filePath } = pathInfo;
const archive = getOrCreateArchive(asarPath);

View File

@@ -18,4 +18,4 @@
}
]
}
}
}

View File

@@ -1,7 +1,6 @@
import * as fs from 'fs';
import { Menu } from 'electron/main';
import * as deprecate from '@electron/internal/common/deprecate';
import { Menu, deprecate } from 'electron/main';
const bindings = process._linkedBinding('electron_browser_app');
const commandLine = process._linkedBinding('electron_common_command_line');

View File

@@ -68,7 +68,7 @@ const spawnUpdate = function (args: string[], detached: boolean, callback: Funct
if (code !== 0) {
// Disabled for backwards compatibility:
// eslint-disable-next-line standard/no-callback-literal
return callback(`Command failed: ${signal ?? code}\n${stderr}`);
return callback(`Command failed: ${signal != null ? signal : code}\n${stderr}`);
}
// Success.

View File

@@ -1,6 +1,5 @@
import { BaseWindow, WebContents, Event, BrowserView, TouchBar } from 'electron/main';
import type { BrowserWindow as BWT } from 'electron/main';
import * as deprecate from '@electron/internal/common/deprecate';
const { BrowserWindow } = process._linkedBinding('electron_browser_window') as { BrowserWindow: typeof BWT };
Object.setPrototypeOf(BrowserWindow.prototype, BaseWindow.prototype);
@@ -45,28 +44,6 @@ BrowserWindow.prototype._init = function (this: BWT) {
this.on(event as any, visibilityChanged);
}
const warn = deprecate.warnOnceMessage('\'scroll-touch-{begin,end,edge}\' are deprecated and will be removed. Please use the WebContents \'input-event\' event instead.');
this.webContents.on('input-event', (_, e) => {
if (e.type === 'gestureScrollBegin') {
if (this.listenerCount('scroll-touch-begin') !== 0) {
warn();
this.emit('scroll-touch-edge');
this.emit('scroll-touch-begin');
}
} else if (e.type === 'gestureScrollUpdate') {
if (this.listenerCount('scroll-touch-edge') !== 0) {
warn();
this.emit('scroll-touch-edge');
}
} else if (e.type === 'gestureScrollEnd') {
if (this.listenerCount('scroll-touch-end') !== 0) {
warn();
this.emit('scroll-touch-edge');
this.emit('scroll-touch-end');
}
}
});
// Notify the creation of the window.
const event = process._linkedBinding('electron_browser_event').createEmpty();
app.emit('browser-window-created', event, this);
@@ -95,8 +72,9 @@ BrowserWindow.getAllWindows = () => {
BrowserWindow.getFocusedWindow = () => {
for (const window of BrowserWindow.getAllWindows()) {
if (!window.isDestroyed() && window.webContents && !window.webContents.isDestroyed()) {
if (window.isFocused() || window.webContents.isDevToolsFocused()) return window;
const hasWC = window.webContents && !window.webContents.isDestroyed();
if (!window.isDestroyed() && hasWC) {
if (window.isFocused() || window.isDevToolsFocused()) return window;
}
}
return null;

View File

@@ -1,5 +1,4 @@
import { app } from 'electron/main';
import * as deprecate from '@electron/internal/common/deprecate';
import { app, deprecate } from 'electron/main';
const binding = process._linkedBinding('electron_browser_crash_reporter');

View File

@@ -9,7 +9,8 @@ let currentlyRunning: {
// |options.types| can't be empty and must be an array
function isValid (options: Electron.SourcesOptions) {
return Array.isArray(options?.types);
const types = options ? options.types : undefined;
return Array.isArray(types);
}
export async function getSources (args: Electron.SourcesOptions) {

View File

@@ -395,7 +395,7 @@ class TouchBar extends EventEmitter implements Electron.TouchBar {
this.on('change', changeListener);
const escapeItemListener = (item: Electron.TouchBarItemType | null) => {
window._setEscapeTouchBarItem(item ?? {});
window._setEscapeTouchBarItem(item != null ? item : {});
};
this.on('escape-item-change', escapeItemListener);

View File

@@ -1,4 +1,4 @@
import { app, ipcMain, session, webFrameMain } from 'electron/main';
import { app, ipcMain, session, webFrameMain, deprecate } from 'electron/main';
import type { BrowserWindowConstructorOptions, LoadURLOptions } from 'electron/main';
import * as url from 'url';
@@ -10,7 +10,6 @@ import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-util
import { MessagePortMain } from '@electron/internal/browser/message-port-main';
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
import { IpcMainImpl } from '@electron/internal/browser/ipc-main-impl';
import * as deprecate from '@electron/internal/common/deprecate';
// session is not used here, the purpose is to make sure session is initialized
// before the webContents module.
@@ -174,13 +173,13 @@ WebContents.prototype.printToPDF = async function (options) {
headerTemplate: '',
footerTemplate: '',
printBackground: false,
scale: 1.0,
scale: 1,
paperWidth: 8.5,
paperHeight: 11.0,
marginTop: 0.0,
marginBottom: 0.0,
marginLeft: 0.0,
marginRight: 0.0,
paperHeight: 11,
marginTop: 0,
marginBottom: 0,
marginLeft: 0,
marginRight: 0,
pageRanges: '',
preferCSSPageSize: false
};
@@ -210,7 +209,7 @@ WebContents.prototype.printToPDF = async function (options) {
if (typeof options.scale !== 'number') {
return Promise.reject(new Error('scale must be a Number'));
}
printSettings.scale = options.scale;
printSettings.scaleFactor = options.scale;
}
const { pageSize } = options;
@@ -537,11 +536,6 @@ const addReturnValueToEvent = (event: Electron.IpcMainEvent) => {
});
};
const getWebFrameForEvent = (event: Electron.IpcMainEvent | Electron.IpcMainInvokeEvent) => {
if (!event.processId || !event.frameId) return null;
return webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
};
const commandLine = process._linkedBinding('electron_common_command_line');
const environment = process._linkedBinding('electron_common_environment');
@@ -579,7 +573,7 @@ WebContents.prototype._init = function () {
} else {
addReplyToEvent(event);
this.emit('ipc-message', event, channel, ...args);
const maybeWebFrame = getWebFrameForEvent(event);
const maybeWebFrame = webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
maybeWebFrame && maybeWebFrame.ipc.emit(channel, event, ...args);
ipc.emit(channel, event, ...args);
ipcMain.emit(channel, event, ...args);
@@ -593,8 +587,8 @@ WebContents.prototype._init = function () {
console.error(`Error occurred in handler for '${channel}':`, error);
event.sendReply({ error: error.toString() });
};
const maybeWebFrame = getWebFrameForEvent(event);
const targets: (ElectronInternal.IpcMainInternal| undefined)[] = internal ? [ipcMainInternal] : [maybeWebFrame?.ipc, ipc, ipcMain];
const maybeWebFrame = webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
const targets: (ElectronInternal.IpcMainInternal| undefined)[] = internal ? [ipcMainInternal] : [maybeWebFrame && maybeWebFrame.ipc, ipc, ipcMain];
const target = targets.find(target => target && (target as any)._invokeHandlers.has(channel));
if (target) {
(target as any)._invokeHandlers.get(channel)(event, ...args);
@@ -610,7 +604,7 @@ WebContents.prototype._init = function () {
ipcMainInternal.emit(channel, event, ...args);
} else {
addReplyToEvent(event);
const maybeWebFrame = getWebFrameForEvent(event);
const maybeWebFrame = webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
if (this.listenerCount('ipc-message-sync') === 0 && ipc.listenerCount(channel) === 0 && ipcMain.listenerCount(channel) === 0 && (!maybeWebFrame || maybeWebFrame.ipc.listenerCount(channel) === 0)) {
console.warn(`WebContents #${this.id} called ipcRenderer.sendSync() with '${channel}' channel without listeners.`);
}
@@ -624,7 +618,7 @@ WebContents.prototype._init = function () {
this.on('-ipc-ports' as any, function (event: Electron.IpcMainEvent, internal: boolean, channel: string, message: any, ports: any[]) {
addSenderFrameToEvent(event);
event.ports = ports.map(p => new MessagePortMain(p));
const maybeWebFrame = getWebFrameForEvent(event);
const maybeWebFrame = webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
maybeWebFrame && maybeWebFrame.ipc.emit(channel, event, message);
ipc.emit(channel, event, message);
ipcMain.emit(channel, event, message);
@@ -676,6 +670,7 @@ WebContents.prototype._init = function () {
const options = result.browserWindowConstructorOptions;
if (!event.defaultPrevented) {
openGuestWindow({
event,
embedder: event.sender,
disposition,
referrer,
@@ -722,16 +717,18 @@ WebContents.prototype._init = function () {
transparent: windowOpenOverriddenOptions.transparent,
...windowOpenOverriddenOptions.webPreferences
} : undefined;
// TODO(zcbenz): The features string is parsed twice: here where it is
// passed to C++, and in |makeBrowserWindowOptions| later where it is
// not actually used since the WebContents is created here.
// We should be able to remove the latter once the |new-window| event
// is removed.
const { webPreferences: parsedWebPreferences } = parseFeatures(rawFeatures);
// Parameters should keep same with |makeBrowserWindowOptions|.
const webPreferences = makeWebPreferences({
embedder: event.sender,
insecureParsedWebPreferences: parsedWebPreferences,
secureOverrideWebPreferences
});
windowOpenOverriddenOptions = {
...windowOpenOverriddenOptions,
webPreferences
};
this._setNextChildWebPreferences(webPreferences);
}
});
@@ -753,6 +750,7 @@ WebContents.prototype._init = function () {
}
openGuestWindow({
event,
embedder: event.sender,
guest: webContents,
overrideBrowserWindowOptions: overriddenOptions,
@@ -835,10 +833,6 @@ export function fromId (id: string) {
return binding.fromId(id);
}
export function fromFrame (frame: Electron.WebFrameMain) {
return binding.fromFrame(frame);
}
export function fromDevToolsTargetId (targetId: string) {
return binding.fromDevToolsTargetId(targetId);
}

View File

@@ -22,6 +22,13 @@ const supportedWebViewEvents = Object.keys(webViewEvents);
const guestInstances = new Map<number, GuestInstance>();
const embedderElementsMap = new Map<string, number>();
function sanitizeOptionsForGuest (options: Record<string, any>) {
const ret = { ...options };
// WebContents values can't be sent over IPC.
delete ret.webContents;
return ret;
}
function makeWebPreferences (embedder: Electron.WebContents, params: Record<string, any>) {
// parse the 'webpreferences' attribute string, if set
// this uses the same parsing rules as window.open uses for its features
@@ -31,8 +38,8 @@ function makeWebPreferences (embedder: Electron.WebContents, params: Record<stri
: null;
const webPreferences: Electron.WebPreferences = {
nodeIntegration: params.nodeintegration ?? false,
nodeIntegrationInSubFrames: params.nodeintegrationinsubframes ?? false,
nodeIntegration: params.nodeintegration != null ? params.nodeintegration : false,
nodeIntegrationInSubFrames: params.nodeintegrationinsubframes != null ? params.nodeintegrationinsubframes : false,
plugins: params.plugins,
zoomFactor: embedder.zoomFactor,
disablePopups: !params.allowpopups,
@@ -149,6 +156,15 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
});
}
guest.on('new-window', function (event, url, frameName, disposition, options) {
sendToEmbedder(IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT, 'new-window', {
url,
frameName,
disposition,
options: sanitizeOptionsForGuest(options)
});
});
// Dispatch guest's IPC messages to embedder.
guest.on('ipc-message-host' as any, function (event: Electron.IpcMainEvent, channel: string, args: any[]) {
sendToEmbedder(IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT, 'ipc-message', {

View File

@@ -5,7 +5,7 @@
* out-of-process (cross-origin) are created here. "Embedder" roughly means
* "parent."
*/
import { BrowserWindow } from 'electron/main';
import { BrowserWindow, deprecate } from 'electron/main';
import type { BrowserWindowConstructorOptions, Referrer, WebContents, LoadURLOptions } from 'electron/main';
import { parseFeatures } from '@electron/internal/browser/parse-features-string';
@@ -24,8 +24,13 @@ const getGuestWindowByFrameName = (name: string) => frameNamesToWindow.get(name)
/**
* `openGuestWindow` is called to create and setup event handling for the new
* window.
*
* Until its removal in 12.0.0, the `new-window` event is fired, allowing the
* user to preventDefault() on the passed event (which ends up calling
* DestroyWebContents).
*/
export function openGuestWindow ({ embedder, guest, referrer, disposition, postData, overrideBrowserWindowOptions, windowOpenArgs, outlivesOpener }: {
export function openGuestWindow ({ event, embedder, guest, referrer, disposition, postData, overrideBrowserWindowOptions, windowOpenArgs, outlivesOpener }: {
event: { sender: WebContents, defaultPrevented: boolean },
embedder: WebContents,
guest?: WebContents,
referrer: Referrer,
@@ -36,14 +41,23 @@ export function openGuestWindow ({ embedder, guest, referrer, disposition, postD
outlivesOpener: boolean,
}): BrowserWindow | undefined {
const { url, frameName, features } = windowOpenArgs;
const { options: parsedOptions } = parseFeatures(features);
const browserWindowOptions = {
show: true,
width: 800,
height: 600,
...parsedOptions,
...overrideBrowserWindowOptions
};
const browserWindowOptions = makeBrowserWindowOptions({
embedder,
features,
overrideOptions: overrideBrowserWindowOptions
});
const didCancelEvent = emitDeprecatedNewWindowEvent({
event,
embedder,
guest,
browserWindowOptions,
windowOpenArgs,
disposition,
postData,
referrer
});
if (didCancelEvent) return;
// To spec, subsequent window.open calls with the same frame name (`target` in
// spec parlance) will reuse the previous window.
@@ -120,6 +134,68 @@ const handleWindowLifecycleEvents = function ({ embedder, guest, frameName, outl
}
};
/**
* Deprecated in favor of `webContents.setWindowOpenHandler` and
* `did-create-window` in 11.0.0. Will be removed in 12.0.0.
*/
function emitDeprecatedNewWindowEvent ({ event, embedder, guest, windowOpenArgs, browserWindowOptions, disposition, referrer, postData }: {
event: { sender: WebContents, defaultPrevented: boolean, newGuest?: BrowserWindow },
embedder: WebContents,
guest?: WebContents,
windowOpenArgs: WindowOpenArgs,
browserWindowOptions: BrowserWindowConstructorOptions,
disposition: string,
referrer: Referrer,
postData?: PostData,
}): boolean {
const { url, frameName } = windowOpenArgs;
const isWebViewWithPopupsDisabled = embedder.getType() === 'webview' && embedder.getLastWebPreferences()!.disablePopups;
const postBody = postData ? {
data: postData,
...parseContentTypeFormat(postData)
} : null;
if (embedder.listenerCount('new-window') > 0) {
deprecate.log('The new-window event is deprecated and will be removed. Please use contents.setWindowOpenHandler() instead.');
}
embedder.emit(
'new-window',
event,
url,
frameName,
disposition,
{
...browserWindowOptions,
webContents: guest
},
[], // additionalFeatures
referrer,
postBody
);
const { newGuest } = event;
if (isWebViewWithPopupsDisabled) return true;
if (event.defaultPrevented) {
if (newGuest) {
if (guest === newGuest.webContents) {
// The webContents is not changed, so set defaultPrevented to false to
// stop the callers of this event from destroying the webContents.
event.defaultPrevented = false;
}
handleWindowLifecycleEvents({
embedder: event.sender,
guest: newGuest,
frameName,
outlivesOpener: false
});
}
return true;
}
return false;
}
// Security options that child windows will always inherit from parent windows
const securityWebPreferences: { [key: string]: boolean } = {
contextIsolation: true,
@@ -131,6 +207,31 @@ const securityWebPreferences: { [key: string]: boolean } = {
enableWebSQL: false
};
function makeBrowserWindowOptions ({ embedder, features, overrideOptions }: {
embedder: WebContents,
features: string,
overrideOptions?: BrowserWindowConstructorOptions,
}) {
const { options: parsedOptions, webPreferences: parsedWebPreferences } = parseFeatures(features);
return {
show: true,
width: 800,
height: 600,
...parsedOptions,
...overrideOptions,
// Note that for normal code path an existing WebContents created by
// Chromium will be used, with web preferences parsed in the
// |-will-add-new-contents| event.
// The |webPreferences| here is only used by the |new-window| event.
webPreferences: makeWebPreferences({
embedder,
insecureParsedWebPreferences: parsedWebPreferences,
secureOverrideWebPreferences: overrideOptions && overrideOptions.webPreferences
})
} as Electron.BrowserViewConstructorOptions;
}
export function makeWebPreferences ({ embedder, secureOverrideWebPreferences = {}, insecureParsedWebPreferences: parsedWebPreferences = {} }: {
embedder: WebContents,
insecureParsedWebPreferences?: ReturnType<typeof parseFeatures>['webPreferences'],

View File

@@ -1,23 +0,0 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
"electron",
"electron/main",
"electron/renderer"
],
"patterns": [
"./*",
"../*",
"@electron/internal/browser/*",
"@electron/internal/isolated_renderer/*",
"@electron/internal/renderer/*",
"@electron/internal/sandboxed_worker/*",
"@electron/internal/worker/*"
]
}
]
}
}

View File

@@ -1,6 +1,5 @@
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
// eslint-disable-next-line no-restricted-imports
import type * as ipcRendererUtilsModule from '@electron/internal/renderer/ipc-renderer-internal-utils';
const clipboard = process._linkedBinding('electron_common_clipboard');

135
lib/common/api/deprecate.ts Normal file
View File

@@ -0,0 +1,135 @@
let deprecationHandler: ElectronInternal.DeprecationHandler | null = null;
function warnOnce (oldName: string, newName?: string) {
let warned = false;
const msg = newName
? `'${oldName}' is deprecated and will be removed. Please use '${newName}' instead.`
: `'${oldName}' is deprecated and will be removed.`;
return () => {
if (!warned && !process.noDeprecation) {
warned = true;
deprecate.log(msg);
}
};
}
const deprecate: ElectronInternal.DeprecationUtil = {
warnOnce,
setHandler: (handler) => { deprecationHandler = handler; },
getHandler: () => deprecationHandler,
warn: (oldName, newName) => {
if (!process.noDeprecation) {
deprecate.log(`'${oldName}' is deprecated. Use '${newName}' instead.`);
}
},
log: (message) => {
if (typeof deprecationHandler === 'function') {
deprecationHandler(message);
} else if (process.throwDeprecation) {
throw new Error(message);
} else if (process.traceDeprecation) {
return console.trace(message);
} else {
return console.warn(`(electron) ${message}`);
}
},
// remove a function with no replacement
removeFunction: (fn, removedName) => {
if (!fn) { throw Error(`'${removedName} function' is invalid or does not exist.`); }
// wrap the deprecated function to warn user
const warn = warnOnce(`${fn.name} function`);
return function (this: any) {
warn();
fn.apply(this, arguments);
} as unknown as typeof fn;
},
// change the name of a function
renameFunction: (fn, newName) => {
const warn = warnOnce(`${fn.name} function`, `${newName} function`);
return function (this: any) {
warn();
return fn.apply(this, arguments);
} as unknown as typeof fn;
},
moveAPI<T extends Function> (fn: T, oldUsage: string, newUsage: string): T {
const warn = warnOnce(oldUsage, newUsage);
return function (this: any) {
warn();
return fn.apply(this, arguments);
} as unknown as typeof fn;
},
// change the name of an event
event: (emitter, oldName, newName) => {
const warn = newName.startsWith('-') /* internal event */
? warnOnce(`${oldName} event`)
: warnOnce(`${oldName} event`, `${newName} event`);
return emitter.on(newName, function (this: NodeJS.EventEmitter, ...args) {
if (this.listenerCount(oldName) !== 0) {
warn();
this.emit(oldName, ...args);
}
});
},
// remove a property with no replacement
removeProperty: (o, removedName, onlyForValues) => {
// if the property's already been removed, warn about it
const info = Object.getOwnPropertyDescriptor((o as any).__proto__, removedName) // eslint-disable-line
if (!info) {
deprecate.log(`Unable to remove property '${removedName}' from an object that lacks it.`);
return o;
}
if (!info.get || !info.set) {
deprecate.log(`Unable to remove property '${removedName}' from an object does not have a getter / setter`);
return o;
}
// wrap the deprecated property in an accessor to warn
const warn = warnOnce(removedName);
return Object.defineProperty(o, removedName, {
configurable: true,
get: () => {
warn();
return info.get!.call(o);
},
set: newVal => {
if (!onlyForValues || onlyForValues.includes(newVal)) {
warn();
}
return info.set!.call(o, newVal);
}
});
},
// change the name of a property
renameProperty: (o, oldName, newName) => {
const warn = warnOnce(oldName, newName);
// if the new property isn't there yet,
// inject it and warn about it
if ((oldName in o) && !(newName in o)) {
warn();
o[newName] = (o as any)[oldName];
}
// wrap the deprecated property in an accessor to warn
// and redirect to the new property
return Object.defineProperty(o, oldName, {
get: () => {
warn();
return o[newName];
},
set: value => {
warn();
o[newName] = value;
}
});
}
};
export default deprecate;

View File

@@ -2,5 +2,7 @@
export const commonModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'clipboard', loader: () => require('./clipboard') },
{ name: 'nativeImage', loader: () => require('./native-image') },
{ name: 'shell', loader: () => require('./shell') }
{ name: 'shell', loader: () => require('./shell') },
// The internal modules, invisible unless you know their names.
{ name: 'deprecate', loader: () => require('./deprecate'), private: true }
];

View File

@@ -9,7 +9,7 @@ export function defineProperties (targetExports: Object, moduleList: ElectronInt
const descriptors: PropertyDescriptorMap = {};
for (const module of moduleList) {
descriptors[module.name] = {
enumerable: true,
enumerable: !module.private,
get: handleESModule(module.loader)
};
}

View File

@@ -1,142 +0,0 @@
type DeprecationHandler = (message: string) => void;
let deprecationHandler: DeprecationHandler | null = null;
export function warnOnce (oldName: string, newName?: string) {
return warnOnceMessage(newName
? `'${oldName}' is deprecated and will be removed. Please use '${newName}' instead.`
: `'${oldName}' is deprecated and will be removed.`);
}
export function warnOnceMessage (msg: string) {
let warned = false;
return () => {
if (!warned && !process.noDeprecation) {
warned = true;
log(msg);
}
};
}
export function setHandler (handler: DeprecationHandler | null): void {
deprecationHandler = handler;
}
export function getHandler (): DeprecationHandler | null {
return deprecationHandler;
}
export function warn (oldName: string, newName: string): void {
if (!process.noDeprecation) {
log(`'${oldName}' is deprecated. Use '${newName}' instead.`);
}
}
export function log (message: string): void {
if (typeof deprecationHandler === 'function') {
deprecationHandler(message);
} else if (process.throwDeprecation) {
throw new Error(message);
} else if (process.traceDeprecation) {
return console.trace(message);
} else {
return console.warn(`(electron) ${message}`);
}
}
// remove a function with no replacement
export function removeFunction<T extends Function> (fn: T, removedName: string): T {
if (!fn) { throw Error(`'${removedName} function' is invalid or does not exist.`); }
// wrap the deprecated function to warn user
const warn = warnOnce(`${fn.name} function`);
return function (this: any) {
warn();
fn.apply(this, arguments);
} as unknown as typeof fn;
}
// change the name of a function
export function renameFunction<T extends Function> (fn: T, newName: string): T {
const warn = warnOnce(`${fn.name} function`, `${newName} function`);
return function (this: any) {
warn();
return fn.apply(this, arguments);
} as unknown as typeof fn;
}
// change the name of an event
export function event (emitter: NodeJS.EventEmitter, oldName: string, newName: string) {
const warn = newName.startsWith('-') /* internal event */
? warnOnce(`${oldName} event`)
: warnOnce(`${oldName} event`, `${newName} event`);
return emitter.on(newName, function (this: NodeJS.EventEmitter, ...args) {
if (this.listenerCount(oldName) !== 0) {
warn();
this.emit(oldName, ...args);
}
});
}
// remove a property with no replacement
export function removeProperty<T, K extends (keyof T & string)>(object: T, removedName: K, onlyForValues?: any[]): T {
// if the property's already been removed, warn about it
const info = Object.getOwnPropertyDescriptor((object as any).__proto__, removedName) // eslint-disable-line
if (!info) {
log(`Unable to remove property '${removedName}' from an object that lacks it.`);
return object;
}
if (!info.get || !info.set) {
log(`Unable to remove property '${removedName}' from an object does not have a getter / setter`);
return object;
}
// wrap the deprecated property in an accessor to warn
const warn = warnOnce(removedName);
return Object.defineProperty(object, removedName, {
configurable: true,
get: () => {
warn();
return info.get!.call(object);
},
set: newVal => {
if (!onlyForValues || onlyForValues.includes(newVal)) {
warn();
}
return info.set!.call(object, newVal);
}
});
}
// change the name of a property
export function renameProperty<T, K extends (keyof T & string)>(object: T, oldName: string, newName: K): T {
const warn = warnOnce(oldName, newName);
// if the new property isn't there yet,
// inject it and warn about it
if ((oldName in object) && !(newName in object)) {
warn();
object[newName] = (object as any)[oldName];
}
// wrap the deprecated property in an accessor to warn
// and redirect to the new property
return Object.defineProperty(object, oldName, {
get: () => {
warn();
return object[newName];
},
set: value => {
warn();
object[newName] = value;
}
});
}
export function moveAPI<T extends Function> (fn: T, oldUsage: string, newUsage: string): T {
const warn = warnOnce(oldUsage, newUsage);
return function (this: any) {
warn();
return fn.apply(this, arguments);
} as unknown as typeof fn;
}

View File

@@ -1,18 +0,0 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
"electron",
"electron/main"
],
"patterns": [
"./*",
"../*",
"@electron/internal/browser/*"
]
}
]
}
}

View File

@@ -1,18 +0,0 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
"electron",
"electron/main"
],
"patterns": [
"./*",
"../*",
"@electron/internal/browser/*"
]
}
]
}
}

View File

@@ -7,11 +7,7 @@ const checkContextIsolationEnabled = () => {
const contextBridge: Electron.ContextBridge = {
exposeInMainWorld: (key: string, api: any) => {
checkContextIsolationEnabled();
return binding.exposeAPIInWorld(0, key, api);
},
exposeInIsolatedWorld: (worldId: number, key: string, api: any) => {
checkContextIsolationEnabled();
return binding.exposeAPIInWorld(worldId, key, api);
return binding.exposeAPIInMainWorld(key, api);
}
};

View File

@@ -1,4 +1,4 @@
import { ipcRenderer } from 'electron/renderer';
import { ipcRenderer } from 'electron';
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
import type * as webViewInitModule from '@electron/internal/renderer/web-view/web-view-init';

View File

@@ -2,7 +2,7 @@ import { internalContextBridge } from '@electron/internal/renderer/api/context-b
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal';
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
import { webFrame } from 'electron/renderer';
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
import { IPC_MESSAGES } from '../common/ipc-messages';
const { contextIsolationEnabled } = internalContextBridge;

View File

@@ -1,4 +1,4 @@
import { webFrame, WebFrame } from 'electron/renderer';
import { webFrame, WebFrame } from 'electron';
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';

View File

@@ -1,18 +0,0 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
"electron",
"electron/main"
],
"patterns": [
"./*",
"../*",
"@electron/internal/browser/*"
]
}
]
}
}

View File

@@ -18,5 +18,11 @@ export const moduleList: ElectronInternal.ModuleEntry[] = [
{
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
}
];

View File

@@ -1,18 +0,0 @@
{
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
"electron",
"electron/main"
],
"patterns": [
"./*",
"../*",
"@electron/internal/browser/*"
]
}
]
}
}

View File

@@ -70,30 +70,8 @@ function isInstalled () {
// unzips and makes path.txt point at the correct executable
function extractFile (zipPath) {
return new Promise((resolve, reject) => {
const distPath = process.env.ELECTRON_OVERRIDE_DIST_PATH || path.join(__dirname, 'dist');
extract(zipPath, { dir: path.join(__dirname, 'dist') })
.then(() => {
// If the zip contains an "electron.d.ts" file,
// move that up
const srcTypeDefPath = path.join(distPath, 'electron.d.ts');
const targetTypeDefPath = path.join(__dirname, 'electron.d.ts');
const hasTypeDefinitions = fs.existsSync(srcTypeDefPath);
if (hasTypeDefinitions) {
try {
fs.renameSync(srcTypeDefPath, targetTypeDefPath);
} catch (err) {
reject(err);
}
}
// Write a "path.txt" file.
return fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath);
})
.catch((err) => reject(err));
});
return extract(zipPath, { dir: path.join(__dirname, 'dist') })
.then(() => fs.promises.writeFile(path.join(__dirname, 'path.txt'), platformPath));
}
function getPlatformPath () {

View File

@@ -8,11 +8,11 @@
"postinstall": "node install.js"
},
"dependencies": {
"@electron/get": "^2.0.0",
"@electron/get": "^1.14.1",
"@types/node": "^16.11.26",
"extract-zip": "^2.0.1"
},
"engines": {
"node": ">= 12.20.55"
"node": ">= 10.17.0"
}
}

View File

@@ -1,12 +1,12 @@
{
"name": "electron",
"version": "22.0.0-alpha.6",
"version": "21.0.0-beta.3",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@azure/storage-blob": "^12.9.0",
"@electron/docs-parser": "^0.12.4",
"@electron/typescript-definitions": "^8.9.6",
"@electron/typescript-definitions": "^8.9.5",
"@octokit/auth-app": "^2.10.0",
"@octokit/rest": "^18.0.3",
"@primer/octicons": "^10.0.0",
@@ -27,13 +27,12 @@
"@types/stream-json": "^1.5.1",
"@types/temp": "^0.8.34",
"@types/uuid": "^3.4.6",
"@types/webpack": "^5.28.0",
"@types/webpack-env": "^1.17.0",
"@types/webpack": "^4.41.21",
"@types/webpack-env": "^1.16.3",
"@typescript-eslint/eslint-plugin": "^4.4.1",
"@typescript-eslint/parser": "^4.4.1",
"asar": "^3.1.0",
"aws-sdk": "^2.814.0",
"buffer": "^6.0.3",
"check-for-leaks": "^1.2.1",
"colors": "1.4.0",
"dotenv-safe": "^4.0.4",
@@ -45,7 +44,6 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-typescript": "^0.14.0",
"events": "^3.2.0",
"express": "^4.16.4",
"folder-hash": "^2.1.1",
"fs-extra": "^9.0.1",
@@ -59,7 +57,6 @@
"minimist": "^1.2.6",
"null-loader": "^4.0.0",
"pre-flight": "^1.1.0",
"process": "^0.11.10",
"remark-cli": "^10.0.0",
"remark-preset-lint-markdown-style-guide": "^4.0.0",
"semver": "^5.6.0",
@@ -72,9 +69,9 @@
"ts-loader": "^8.0.2",
"ts-node": "6.2.0",
"typescript": "^4.5.5",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"wrapper-webpack-plugin": "^2.2.0"
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12",
"wrapper-webpack-plugin": "^2.1.0"
},
"private": true,
"scripts": {

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