Compare commits

...

81 Commits

Author SHA1 Message Date
trop[bot]
4120b8f72a fix: wide string concatenation (#40909)
* fix: wide string concatenation

Co-authored-by: clavin <clavin@electronjs.org>

* Use wstring_views to keep length in context

Co-authored-by: clavin <clavin@electronjs.org>

* forgot a space, oopsies

Co-authored-by: clavin <clavin@electronjs.org>

* chore: update patches

* use AsWStringPiece
This code is being merged to a branch before the change from crrev.com/c/5010979

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: clavin <clavin@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-01-08 14:34:15 -08:00
trop[bot]
73111dae51 fix: macOS maximize button shouldn't be disabled just because the window is non-fullscreenable (#40896)
* fix: macOS maximize button shouldn't be disabled just because the window is non-fullscreenable

Co-authored-by: Tamás Zahola <tzahola@gmail.com>

* add test

Co-authored-by: Tamás Zahola <tzahola@gmail.com>

* fix test by enabling maximize button if `resizable && (maximizable || fullscreenable)` instead of `(resizable && maximizable) && fullscreenable`

Co-authored-by: Tamás Zahola <tzahola@gmail.com>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Tamás Zahola <tzahola@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-01-08 21:55:34 +01:00
trop[bot]
73197a85e2 docs: add missing vibrancy breaking change (#40906)
* docs: add missing vibranch change

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2024-01-07 22:03:58 -08:00
electron-roller[bot]
741774177f chore: bump chromium to 120.0.6099.199 (28-x-y) (#40762)
* chore: bump chromium in DEPS to 120.0.6099.110

* chore: bump chromium in DEPS to 120.0.6099.130

* chore: bump chromium in DEPS to 120.0.6099.199

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2024-01-05 15:09:15 +01:00
trop[bot]
9b2ddea855 fix: add partition alloc check for MacOS 13/14+ (#40765)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
2024-01-04 20:43:31 -08:00
trop[bot]
aa8d667bef chore: add disclaimer to release timeline (#40884)
* chore: add disclaimer to release timeline

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>

* Update docs/tutorial/electron-timelines.md

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-01-04 12:45:26 -08:00
trop[bot]
7989f02a43 fix: ignore all NODE_ envs from foreign parent in node process (#40880) 2024-01-04 13:34:10 +01:00
Calvin
0b8f962010 fix: titlebar incorrectly displayed on frameless windows (#40867)
Manual backport of #40749

Co-authored-by: Bruno Henrique da Silva <bruno.d@miro.com>
2024-01-03 11:10:26 +01:00
Pedro Pontes
957d8748b2 chore: cherry-pick 1 changes from Release-2-M120 (#40806)
* chore: [28-x-y] cherry-pick 1 changes from Release-2-M120

* 8d607d3921b8 from chromium

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-12-21 07:40:26 -08:00
trop[bot]
14c6651e35 feat: enable code cache for custom protocols (#40709)
* feat: enable code cache for custom protocols

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>

* chore: update feat_allow_code_cache_in_custom_schemes.patch

* chore: e patches all

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-12-13 12:48:48 -06:00
electron-roller[bot]
c9f886c03d chore: bump chromium to 120.0.6099.109 (28-x-y) (#40756)
* chore: bump chromium in DEPS to 120.0.6099.109

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-12-13 10:20:32 -06:00
trop[bot]
0aa33cc3df fix: wrong default port in docs (#40743)
fix: wrong default port

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Felipe C <felipe@carassonet.org>
2023-12-11 18:18:13 -06:00
electron-roller[bot]
5d5ebc9da2 chore: bump chromium to 120.0.6099.71 (28-x-y) (#40722)
chore: bump chromium in DEPS to 120.0.6099.71

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2023-12-11 14:50:11 +01:00
trop[bot]
66e4c3089b fix: prevent node mode to be used as script runner by other apps (#40710)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2023-12-11 12:35:06 +09:00
trop[bot]
4a617aa666 docs: fix year typos in electron-timelines.md (#40729)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Yureka <yuka@yuka.dev>
2023-12-08 15:23:37 +01:00
electron-roller[bot]
271f2b576a chore: bump chromium to 120.0.6099.62 (28-x-y) (#40700)
* chore: bump chromium in DEPS to 120.0.6099.62

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-12-05 11:53:33 -08:00
trop[bot]
515803e601 docs: add E28 support for ESM in tutorial.md (#40691)
docs: add E28 support for ESM in tutorial

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2023-12-05 00:57:35 -08:00
trop[bot]
34d115a430 fix: cherry pick 9009d76968b1ec2ed825bc95e47d086ceea07520 from chromium (#40688)
* chore: cherry pick 9009d76968b1ec2ed825bc95e47d086ceea07520 from chromium

Co-authored-by: Ryan Manuel <ryanm@cypress.io>

* update patch message

Co-authored-by: Ryan Manuel <ryanm@cypress.io>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Ryan Manuel <ryanm@cypress.io>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-12-04 10:19:02 -08:00
electron-roller[bot]
e809537ac0 chore: bump chromium to 120.0.6099.56 (28-x-y) (#40653)
* chore: bump chromium in DEPS to 120.0.6099.56

* chore: update patches

* 5041802: Reland "Incorporate policy override for OOPPD feature" | https://chromium-review.googlesource.com/c/chromium/src/+/5041802

(cherry picked from commit 771174eb8c)

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2023-12-04 12:51:16 +01:00
trop[bot]
589c827cb9 build: fix release notes script bug that omitted edited release-clerk comments (#40656)
* build: fix release notes script bug that omitted edited release-clerk comments

add a warning when neither notes nor no-notes are found

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* fixup! build: fix release notes script bug that omitted edited release-clerk comments

use console.warn() instead of console.log()

Co-authored-by: Charles Kerr <charles@charleskerr.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-12-03 19:23:59 +01:00
trop[bot]
fe49f1c79a fix: clean up devtools frontend_host on webcontents destroy (#40679)
* fix: clean up devtools frontend_host on destroy

Co-authored-by: Albert Xing <albertxing@slack-corp.com>

* chore: use IsInPrimaryMainFrame instead of IsInMainFrame

Co-authored-by: Albert Xing <albertxing@slack-corp.com>

* test: add a test for re-opening devtools

Co-authored-by: Albert Xing <albertxing@slack-corp.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Albert Xing <albertxing@slack-corp.com>
2023-12-03 18:25:34 +01:00
trop[bot]
5bc8e761d6 fix: add missing set_wants_to_be_visible(true) to NativeWindowMac::ShowInactive() (#40659)
* fix: add missing set_wants_to_be_visible(true) to NativeWindowMac::ShowInactive()

Co-authored-by: zaza <tamas@miro.com>

* add test

Co-authored-by: Tamás Zahola <tzahola@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: zaza <tamas@miro.com>
Co-authored-by: Tamás Zahola <tzahola@gmail.com>
2023-12-03 17:36:57 +01:00
trop[bot]
0756fe6f30 docs: add dates for e29 (#40669) 2023-11-30 23:00:55 -08:00
Keeley Hammond
a0c85cf57e chore: cherry-pick 2 changes from Release-3-M119 (#40647)
chore: [28-x-y] cherry-pick 2 changes from Release-3-M119

* 971d6055e7b7 from openscreen
* 6169a1fabae1 from skia
2023-11-30 12:40:09 +01:00
David Sanders
e45e20acd5 chore: extend linting of code blocks in the docs (#40636) 2023-11-30 12:13:07 +01:00
trop[bot]
1af25902a6 fix: add patch for simdutf base64 crash (#40542)
* fix: add patch for simdutf base64 crash

Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>

* chore: update .patches after trop

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-11-29 12:47:13 +09:00
Milan Burda
9ad4024e82 chore: allow passing more roots to lint.js (#40627)
chore: allow passing more roots to lint.js (#40571)

Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2023-11-29 10:08:18 +09:00
Charles Kerr
9e323e3104 fix: 28-x-y patches (#40629)
* chore: update revert_same_party_cookie_attribute_removal.patch

No manual changes; patch succeeded with p1 fuzz

* chore: update patches

* chore: cleanup patch

---------

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-11-28 17:07:02 -05:00
trop[bot]
9e1c116ff6 build: specify explicit typeroots for ts builds (#40595)
Upstreaming of bf63336f60

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-11-28 15:37:19 +01:00
trop[bot]
581fafb2e9 fix: Use activateIgnoringOtherApps for non-panels (#40621)
Use activateIgnoringOtherApps for non-panels

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Felix Rieseberg <fr@makenotion.com>
2023-11-28 12:48:09 +01:00
electron-roller[bot]
630d75981c chore: bump chromium to 120.0.6099.35 (28-x-y) (#40547)
* chore: bump chromium in DEPS to 120.0.6099.28

* chore: bump chromium in DEPS to 120.0.6099.35

* 5007463: Fix domain joining function on macOS 14 | https://chromium-review.googlesource.com/c/chromium/src/+/5007463

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2023-11-27 14:35:45 -08:00
trop[bot]
f939be0638 feat: add/update missing Display properties (#40554)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-11-27 13:47:31 -05:00
trop[bot]
d01469e486 fix: do not call after() async_hook for asyncId 0 (#40594)
fix: do not call after() async_hook for asyncId 0

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-11-23 11:15:21 +01:00
trop[bot]
0594081f26 fix: restore performance of macOS window resizing (#40586)
* fix: restore performance of macOS window resizing

Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-11-22 09:42:37 -08:00
trop[bot]
131c5e7986 fix: maximized window bounds when toggle setResizable (#40582)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Tomasz Malinowski <tomasz@openfin.co>
2023-11-22 10:58:47 +01:00
trop[bot]
a3986f84db fix: ShowItemUsingFileManager should escape path in Linux (#40562)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: hsfzxjy <hsfzxjy@gmail.com>
2023-11-21 10:23:03 +09:00
Keeley Hammond
33b39fb63d fix: revert SameParty cookie attribute removal (#40526) 2023-11-16 13:41:12 -08:00
trop[bot]
9a4b32d517 fix: emit will-navigate for links in chrome: pages (#40525)
* fix: emit will-navigate for links in chrome: pages

Co-authored-by: Samuel Maddock <smaddock@slack-corp.com>

* test: will-navigate emitted from chrome: pages

Co-authored-by: Samuel Maddock <smaddock@slack-corp.com>

* Update shell/browser/electron_navigation_throttle.cc

Co-authored-by: Charles Kerr <charles@charleskerr.com>

Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Maddock <smaddock@slack-corp.com>
Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>
2023-11-15 10:50:12 +01:00
trop[bot]
8eb6b35fc0 fix: chrome.action API registration (#40514)
* fix: chrome.action API registration

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fix: browser_action implemented_in

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-11-13 11:26:55 +01:00
trop[bot]
b92b4c8fcf fix: Do not activate app when calling focus on inactive panel window (#40465)
* fix: Do not activate app when calling focus on inactive panel window

Co-authored-by: Felix Rieseberg <fr@makenotion.com>

* Use activate

Co-authored-by: Felix Rieseberg <fr@makenotion.com>

* Use "activate" for all windows

Co-authored-by: Felix Rieseberg <fr@makenotion.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Felix Rieseberg <fr@makenotion.com>
2023-11-10 15:40:47 -05:00
electron-roller[bot]
bc07c3be54 chore: bump chromium to 120.0.6099.18 (28-x-y) (#40488)
* chore: bump chromium in DEPS to 120.0.6099.18

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-11-09 13:58:17 -08:00
trop[bot]
1f0fa3471a docs: update references to Electron Packager (#40496)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-11-09 13:57:03 -08:00
trop[bot]
460b8dc453 feat: keyboard.lock() should use permissions helper (#40460)
feat: keyboard.lock should use permissions helper

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-11-09 10:41:31 -08:00
Brad Parham
db995982cd chore: bump node to v18.18.2 (#40472)
* chore: bump node to v18.18.1 (main) (#40174)

* chore: bump node in DEPS to v18.18.1

* Revert "deps: upgrade to libuv 1.46.0"

https://github.com/nodejs/node/pull/50036

* chore: fixup patch indices

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: bump node to v18.18.2 (main) (#40205)

* chore: bump node in DEPS to v18.18.2

* chore: update patches

* deps: update nghttp2 to 1.55.0

https://github.com/nodejs/node/pull/48746

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-11-09 10:39:21 -08:00
trop[bot]
30fe3b5667 docs: fix hid-device-{added|removed|revoked} event types (#40478)
docs: fix hid-device-{added|removed|revoked} types

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-11-07 18:09:41 -08:00
Robo
0b847b0d9f fix: broken shader cache due to compilation error (#40450)
Refs https://chromium-review.googlesource.com/c/chromium/src/+/4988290
2023-11-07 11:00:27 +09:00
trop[bot]
a77f2e0cee fix: crash when unloading some WebViews (#40445)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-11-03 13:50:26 -04:00
trop[bot]
f739cb110a docs: document our Node.js versioning policy (#40416)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-11-02 17:14:49 -04:00
electron-roller[bot]
b2235fefc3 chore: bump chromium to 120.0.6099.5 (28-x-y) (#40420)
* chore: bump chromium in DEPS to 120.0.6099.5

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-11-02 16:19:30 -04:00
trop[bot]
5c70bd768a docs: add bypassCustomProtocolHandlers to ses.fetch (#40424)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Brandon Fowler <brandfowl@gmail.com>
2023-11-02 07:11:02 -04:00
John Kleinschmidt
3934f72496 chore: bump chromium to 120.0.6099.0 (28-x-y) (#40413)
* chore: bump chromium to 120.0.6078.0 (main) (#40114)

* chore: bump chromium in DEPS to 120.0.6049.0

* chore: update patches

* chore: bump chromium in DEPS to 120.0.6050.0

* chore: update patches

* 4910494: Reland "[autopip] Show autopip UI for video pip"

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

* 4812338: Move partition_alloc into a "partition_alloc" dir.

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

* [Extensions Cleanup] Remove mojom ViewType::kExtensionDialog

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

* 4894923: Force enable raw_ptrs pointer arithmetic check.

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

* gin: Prevent wrappables from being constructed from author code.

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

* chore: update patches

* chore: bump chromium in DEPS to 120.0.6052.0

* chore: bump chromium in DEPS to 120.0.6054.0

* chore: bump chromium in DEPS to 120.0.6056.0

* chore: fix patches

* 4918545: Reland "[autopip] Add permissions embargo"
https://chromium-review.googlesource.com/c/chromium/src/+/4918545

* 4881761: UI bindings for visual logging with structured metrics.

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

* chore: bump chromium in DEPS to 120.0.6058.0

* chore: update patches

* chore: bump chromium in DEPS to 120.0.6060.0

* chore: bump chromium in DEPS to 120.0.6061.0

* chore: bump chromium in DEPS to 120.0.6062.0

* chore: gen libc++ filenames

* chore: update patches

* 4911894: Move //c/b/ui/views/eye_dropper to //components
https://chromium-review.googlesource.com/c/chromium/src/+/4911894

* chore: bump chromium in DEPS to 120.0.6064.0

* chore: bump chromium in DEPS to 120.0.6066.0

* chore: bump chromium in DEPS to 120.0.6068.0

* chore: bump chromium in DEPS to 120.0.6070.0

* chore: remove temp_prevent_unused_function_error.patch

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

* chore: add TransferDragSecurityInfo()

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

* mark TransferDragSecurityInfo() as NOTREACHED

A follow-up to previous commit. I think this is commit is correct (i.e.
that this function shouldn't get called) but am not positive, so I'm
including it in a standalone commit in case we need to revert.

* chore: update signature of OnPrivateNetworkAccessPermissionRequired()

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

Our impl is a no-op, so updating the signature is the only change.

* chore: rebuild patches

* chore: bump chromium in DEPS to 120.0.6072.0

* chore: update patches

* chore: sync ParseMatchPattern() param order with upstream change

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

* chore: update fix_crash_loading_non-standard_schemes_in_iframes.patch

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

* chore: rebuild patches

* chore: bump chromium in DEPS to 120.0.6073.0

* chore: update patches

* chore: bump chromium in DEPS to 120.0.6074.0

* chore: update disable_color_correct_rendering.patch

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

no manual changes; patch applied with fuzz 1

* chore: update fix_handle_no_top_level_aura_window_in_webcontentsimpl.patch

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

minor manual sync to upstream code shear

* chore: rebuild patches

* chore: update ClearHttpAuthCache arguments

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

adding ClearDataFilterPtr arg. Upstream added this arg, which is already
present in other NetworkContext methods. Our code uses `nullptr` there.

* chore: bump chromium in DEPS to 120.0.6076.0

* chore: update mas_disable_remote_accessibility.patch

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

minor manual sync to upstream code shear

* chore: update disable_color_correct_rendering.patch

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

minor manual sync to upstream code shear

* fix: move x11_util.h include to top of source file

This is a short-term fix to unblock the roll. I will follow up a better fix in a standalone PR.

* chore: rebuild patches

* chore: bump chromium in DEPS to 120.0.6077.0

* chore: update patches

* chore: bump chromium in DEPS to 120.0.6078.0

* chore: update patches

* refactor: add BrowserProcessImpl::os_crypt_async()

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

This is one to keep an eye on. This commit copies the upstream impl,
which appears to be an interim step with more upstream code changes
still forthcoming.

Xref: https://bugs.chromium.org/p/chromium/issues/detail?id=1373092

* fixup! refactor: add BrowserProcessImpl::os_crypt_async()

chore: make 'gn check' happy

* chore: remove ensure_messageports_get_gced_when_not_referenced.patch

Xref: ensure_messageports_get_gced_when_not_referenced.patch

no longer needed because upstreamed

* chore: remove webrtc/pipewire_capturer_make_restore_tokens_re-usable_more_than_one_time.patch

Xref: https://webrtc-review.googlesource.com/c/src/+/322621

no longer needed because upstreamed

* chore: add //components/compose:buildflags dep

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

needed by browser/ui/browser_dialogs.h

* chore: update filenames.libcxx.gni

node ./script/gen-libc++-filenames.js

* test: fix UI.InspectorView -> UI.InspectorView.instance()

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: clavin <clavin@electronjs.org>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
(cherry picked from commit be44a2c5b7)

* chore: bump chromium to 120.0.6099.0 (main) (#40316)

* chore: bump chromium in DEPS to 120.0.6086.0

* chore: update patches

* chore: rename FrameSubscriber::OnNewCropVersion()

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

just a simple renaming

* chore: rename ToJsTime() to .InMillisecondsFSinceUnixEpoch()

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

function renamed upstream

* chore: rename ToDoubleT() to .InSecondsFSinceUnixEpoch()

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

function renamed upstream

* chore: rename FromDoubleT() to .FromSecondsSinceUnixEpoch()

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

function renamed upstream

* chore: bump chromium in DEPS to 120.0.6088.2

* chore: update patches

* chore: regen filenames.libcxx.gni

* chore: migrate from (removed upstream) inputFormType to formControlType

* chore: bump chromium in DEPS to 120.0.6089.0

* chore: update allow_disabling_blink_scheduler_throttling_per_renderview.patch

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

manually sync to upstream changes + reduce diff size

* chore: update patches

* chore: bump chromium in DEPS to 120.0.6090.0

* chore: update fix_disabling_background_throttling_in_compositor.patch

no manual changes; patch applied with fuzz 2 (4 lines)

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

* chore: update fix_handle_no_top_level_aura_window_in_webcontentsimpl.patch

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

do not patch WebContentsImpl::SetWindowShowState() any longer because it has been removed

* chore: update patches

* chore: bump chromium in DEPS to 120.0.6091.0

* chore: update patches

* chore: bump chromium in DEPS to 120.0.6093.0

* chore: bump chromium in DEPS to 120.0.6095.0

* chore: bump chromium in DEPS to 120.0.6096.0

* chore: bump chromium in DEPS to 120.0.6097.0

* chore: update patches

* chore: update patch after rebase

* 4961495: [document pip] Focus the window when opened manually

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

* [Extensions UserScripts] Store extensions with user scripts in tracker

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

* chore: bump chromium in DEPS to 120.0.6099.0

* chore: update patches

* chore: update filenames.libcxx.gni

* chore: remove trailing space

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
(cherry picked from commit bc1ba1fe9d)

* build: update appveyor image to latest version (#40325)

* build: update appveyor image to latest version

* chore: update version to e-120.0.6099.0

* chore: rename base image for bakes

---------

Co-authored-by: jkleinsc <jkleinsc@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
(cherry picked from commit 878c6e3062)

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-11-01 19:46:39 -04:00
trop[bot]
8d5a15316f docs: avoid leaking the IpcRendererEvent in contextBridge examples (#40412)
* docs: avoid leaking the `IpcRendererEvent` in `contextBridge` examples

Co-authored-by: Milan Burda <milan.burda@gmail.com>

* Update docs/fiddles/ipc/pattern-3/preload.js

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

Co-authored-by: Milan Burda <milan.burda@gmail.com>

* Update docs/tutorial/ipc.md

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

Co-authored-by: Milan Burda <milan.burda@gmail.com>

* Update docs/tutorial/ipc.md

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

Co-authored-by: Milan Burda <milan.burda@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-11-01 18:55:47 -04:00
Shelley Vohr
6916e19ce1 refactor: remove DevTools legacy UI patching (#40409)
* refactor: remove DevTools legacy UI patching

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-11-01 16:24:06 -04:00
electron-roller[bot]
5997b47d21 chore: bump chromium to 119.0.6045.105 (28-x-y) (#40405)
* chore: bump chromium in DEPS to 119.0.6045.105

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-11-01 11:41:52 -04:00
trop[bot]
3f0af4d435 build: actually show github upload output if verbose is true. (#40398)
* build: actually show github upload output if verbose is true.

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

* chore: fixup lint

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-10-31 21:24:07 -04:00
trop[bot]
45fbdcca6a fix: navigator.keyboard.lock() fullscreen exit handling (#40389)
fix: navigator.keyboard.lock() fullscreen exit handling

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-31 21:23:50 -04:00
trop[bot]
09c151a701 build: update deps to fix yarn audit (#40392)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-10-31 17:30:14 -04:00
electron-roller[bot]
5dad69ce8f chore: bump chromium to 119.0.6045.59 (28-x-y) (#40356)
* chore: bump chromium in DEPS to 119.0.6045.59

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-10-31 09:34:43 -04:00
trop[bot]
d0d2a64739 refactor: options parsing in WebContents.prototype.printToPDF() (#40279)
* refactor: options parsing in WebContents.prototype.printToPDF()

Co-authored-by: Milan Burda <milan.burda@gmail.com>

* tweak parsePageSize

Co-authored-by: Milan Burda <milan.burda@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-10-30 11:55:29 -07:00
trop[bot]
2c200c9b8d docs: add reference to app.getAppMetrics() in serviceName for utilityProcess (#40367)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-10-30 11:43:57 -07:00
trop[bot]
bb0dd34e63 fix: prevent PopUpButtonHandler premature dealloc (#40346)
fix: prevent PopUpButtonHandler dealloc

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-26 14:12:43 -04:00
trop[bot]
8148ba5398 build: upload slow, more time good (#40336)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-10-26 00:20:43 -07:00
trop[bot]
f6d7aba69c test: add spec for app.getAppMetrics() for utility process (#40312)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-10-25 09:30:28 -04:00
trop[bot]
22687c18c4 test: add spec for child-process-gone event for utility process (#40304)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-10-23 11:44:22 -07:00
trop[bot]
d1bf107bee chore: Show FIDO devices in the chooser if allowed (#40275)
chore: Show FIDO devices in the chooser if allowed (#40216)

* chore: Show FIDO devices in the chooser if allowed

* chore: tweak HidChooserContext::IsFidoAllowedForOrigin

* chore: feedback from review

---------

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-10-20 10:28:57 +02:00
electron-roller[bot]
eff2ea682d chore: bump chromium to 119.0.6045.33 (28-x-y) (#40278)
* chore: bump chromium in DEPS to 119.0.6045.33

* chore: update patches

* test: fix Node.js color edge snapshot stack traces

(cherry picked from commit af4943fd1b)

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-19 19:20:48 -04:00
trop[bot]
0310156be6 docs: fix represented file fiddle (#40252)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-10-19 10:03:23 +02:00
trop[bot]
714e6ea49c chore: implement no-op chrome.action extension APIs (#40261)
chore: implement no-op chrome.action extension APIs

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-18 21:39:10 +02:00
trop[bot]
3cf8652027 fix: correctly track receiver for methods called via ctx bridge (#40263)
* fix: correctly track receiver for methods called via ctx bridge

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* spec: test for correct contextBridge passage

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-18 21:24:16 +02:00
trop[bot]
f622bd9927 build: re-enable partition alloc on mac (#40230)
* build: re-enable partition alloc on mac

Co-authored-by: VerteDinde <vertedinde@electronjs.org>

* Trigger Build

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: VerteDinde <vertedinde@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-10-18 12:50:12 -04:00
trop[bot]
9ddd08ba89 fix: support the throwIfNoEntry option to statSync and lstatSync in asar files (#40224)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2023-10-18 11:33:48 +02:00
trop[bot]
a98d66dd23 refactor: partition HidDelegate observers by browser context (#40238)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-18 10:06:16 +02:00
trop[bot]
1e51ee974d fix: Windows Toast notification dismissal from Action Center (#40243)
* fix: Windows Toast notification dismissal from Action Center

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* docs: note Toast behavior in event

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: address feedback from review

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-18 10:03:57 +02:00
trop[bot]
6732f63ac0 docs: Update docs on testing Electron apps with WebdriverIO (#40227)
* docs: Updated docs on testing Electron using WebdriverIO

Co-authored-by: Christian Bromann <github@christian-bromann.com>

* Update docs/tutorial/automated-testing.md

Co-authored-by: Felix Rieseberg <fr@makenotion.com>

Co-authored-by: Christian Bromann <github@christian-bromann.com>

* Update docs/tutorial/automated-testing.md

Co-authored-by: Felix Rieseberg <fr@makenotion.com>

Co-authored-by: Christian Bromann <github@christian-bromann.com>

* more updates

Co-authored-by: Christian Bromann <git@bromann.dev>

* address PR comments

Co-authored-by: Christian Bromann <git@bromann.dev>

* Update docs/tutorial/automated-testing.md

Co-authored-by: Erick Zhao <erick@hotmail.ca>

Co-authored-by: Christian Bromann <github@christian-bromann.com>

* Update docs/tutorial/automated-testing.md

Co-authored-by: Erick Zhao <erick@hotmail.ca>

Co-authored-by: Christian Bromann <github@christian-bromann.com>

* Update docs/tutorial/automated-testing.md

Co-authored-by: Erick Zhao <erick@hotmail.ca>

Co-authored-by: Christian Bromann <github@christian-bromann.com>

* Update docs/tutorial/automated-testing.md

Co-authored-by: Erick Zhao <erick@hotmail.ca>

Co-authored-by: Christian Bromann <github@christian-bromann.com>

* Update docs/tutorial/automated-testing.md

Co-authored-by: Erick Zhao <erick@hotmail.ca>

Co-authored-by: Christian Bromann <github@christian-bromann.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Christian Bromann <github@christian-bromann.com>
Co-authored-by: Christian Bromann <git@bromann.dev>
2023-10-17 16:54:41 +02:00
trop[bot]
641249f384 fix: incorrect wco bounds in macOS fullscreen (#40219)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-16 15:06:39 +02:00
electron-roller[bot]
f6b135e1ac chore: bump chromium to 119.0.6045.21 (28-x-y) (#40178)
* chore: bump chromium in DEPS to 119.0.6045.9

* chore: update patches

* chore: bump chromium in DEPS to 119.0.6045.21

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-10-16 14:53:20 +02:00
trop[bot]
a5f01f0328 docs: fix some string union typings (#40199)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-10-16 14:10:13 +09:00
trop[bot]
d65b8761f8 chore: formally deprecate gpu-process-crashed event (#40195)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-10-16 09:19:27 +09:00
trop[bot]
f8d4c45f8e fix: ensure MessagePorts get GCed when not referenced (#40201)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-16 09:18:36 +09:00
trop[bot]
6625666e40 fix: store portal restore token under the right source ID (#40192)
XDG Desktop Portal provides restore tokens to restore a previously
selected PipeWire stream instead of prompting the user again. This
restore token is single use only and it has to be replaced when the
stream is completed/stopped.

BaseCapturerPipewire maintains two source IDs: one is initialized by
the constructor for new sources (source_id_) and another is for
capturing previously selected sources (selected_source_id_). The
restore token was always being stored under `source_id_`, even if the
capture was ongoing for `selected_source_id_`. This prevents a stream
from being restored more than once. Fix that by storing the restore
token under the selected source ID if it exists.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Athul Iddya <athul@iddya.com>
2023-10-13 22:09:09 +02:00
trop[bot]
e3e7bf3786 fix: webContents.capturePage() for hidden windows on Windows/Linux (#40185)
fix: capturePage for hidden windows on Windows/Linux

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-12 13:54:43 +02:00
333 changed files with 12272 additions and 2344 deletions

View File

@@ -660,6 +660,7 @@ step-nodejs-headers-build: &step-nodejs-headers-build
step-electron-publish: &step-electron-publish step-electron-publish: &step-electron-publish
run: run:
name: Publish Electron Dist name: Publish Electron Dist
no_output_timeout: 30m
command: | command: |
if [ "`uname`" == "Darwin" ]; then if [ "`uname`" == "Darwin" ]; then
rm -rf src/out/Default/obj rm -rf src/out/Default/obj

View File

@@ -434,6 +434,7 @@ source_set("electron_lib") {
"//chrome/app/resources:platform_locale_settings", "//chrome/app/resources:platform_locale_settings",
"//components/autofill/core/common:features", "//components/autofill/core/common:features",
"//components/certificate_transparency", "//components/certificate_transparency",
"//components/compose:buildflags",
"//components/embedder_support:browser_util", "//components/embedder_support:browser_util",
"//components/language/core/browser", "//components/language/core/browser",
"//components/net_log", "//components/net_log",
@@ -442,6 +443,8 @@ source_set("electron_lib") {
"//components/network_hints/renderer", "//components/network_hints/renderer",
"//components/network_session_configurator/common", "//components/network_session_configurator/common",
"//components/omnibox/browser:buildflags", "//components/omnibox/browser:buildflags",
"//components/os_crypt/async/browser",
"//components/os_crypt/async/browser:key_provider_interface",
"//components/os_crypt/sync", "//components/os_crypt/sync",
"//components/pref_registry", "//components/pref_registry",
"//components/prefs", "//components/prefs",

4
DEPS
View File

@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
vars = { vars = {
'chromium_version': 'chromium_version':
'119.0.6045.0', '120.0.6099.199',
'node_version': 'node_version':
'v18.18.0', 'v18.18.2',
'nan_version': 'nan_version':
'e14bdcd1f72d62bca1d541b66da43130384ec213', 'e14bdcd1f72d62bca1d541b66da43130384ec213',
'squirrel.mac_version': 'squirrel.mac_version':

View File

@@ -6,7 +6,7 @@
version: 1.0.{build} version: 1.0.{build}
build_cloud: electronhq-16-core build_cloud: electronhq-16-core
image: e-112.0.5607.0-vs2022 image: base-bake-image
environment: environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default ELECTRON_OUT_DIR: Default

View File

@@ -29,7 +29,7 @@
version: 1.0.{build} version: 1.0.{build}
build_cloud: electronhq-16-core build_cloud: electronhq-16-core
image: e-119.0.6045.0 image: e-120.0.6099.0
environment: environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default ELECTRON_OUT_DIR: Default

View File

@@ -29,7 +29,7 @@
version: 1.0.{build} version: 1.0.{build}
build_cloud: electronhq-16-core build_cloud: electronhq-16-core
image: e-119.0.6045.0 image: e-120.0.6099.0
environment: environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default ELECTRON_OUT_DIR: Default

View File

@@ -100,8 +100,6 @@ static_library("chrome") {
"//chrome/browser/ui/ui_features.h", "//chrome/browser/ui/ui_features.h",
"//chrome/browser/ui/views/eye_dropper/eye_dropper.cc", "//chrome/browser/ui/views/eye_dropper/eye_dropper.cc",
"//chrome/browser/ui/views/eye_dropper/eye_dropper.h", "//chrome/browser/ui/views/eye_dropper/eye_dropper.h",
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc",
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view.h",
"//chrome/browser/ui/views/overlay/back_to_tab_label_button.cc", "//chrome/browser/ui/views/overlay/back_to_tab_label_button.cc",
"//chrome/browser/ui/views/overlay/close_image_button.cc", "//chrome/browser/ui/views/overlay/close_image_button.cc",
"//chrome/browser/ui/views/overlay/close_image_button.h", "//chrome/browser/ui/views/overlay/close_image_button.h",
@@ -156,15 +154,6 @@ static_library("chrome") {
sources += [ "//chrome/browser/media/webrtc/window_icon_util_ozone.cc" ] sources += [ "//chrome/browser/media/webrtc/window_icon_util_ozone.cc" ]
} }
if (use_aura) {
sources += [
"//chrome/browser/platform_util_aura.cc",
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura.cc",
"//ui/views/native_window_tracker_aura.cc",
"//ui/views/native_window_tracker_aura.h",
]
}
public_deps = [ public_deps = [
"//chrome/browser:dev_ui_browser_resources", "//chrome/browser:dev_ui_browser_resources",
"//chrome/browser/resources/accessibility:resources", "//chrome/browser/resources/accessibility:resources",
@@ -189,6 +178,16 @@ static_library("chrome") {
"//ui/views/controls/webview", "//ui/views/controls/webview",
] ]
if (use_aura) {
sources += [
"//chrome/browser/platform_util_aura.cc",
"//chrome/browser/ui/views/eye_dropper/eye_dropper_aura.cc",
"//ui/views/native_window_tracker_aura.cc",
"//ui/views/native_window_tracker_aura.h",
]
deps += [ "//components/eye_dropper" ]
}
if (is_linux) { if (is_linux) {
sources += [ "//chrome/browser/icon_loader_auralinux.cc" ] sources += [ "//chrome/browser/icon_loader_auralinux.cc" ]
if (use_ozone) { if (use_ozone) {
@@ -257,6 +256,8 @@ static_library("chrome") {
sources += [ sources += [
"//chrome/browser/bad_message.cc", "//chrome/browser/bad_message.cc",
"//chrome/browser/bad_message.h", "//chrome/browser/bad_message.h",
"//chrome/browser/printing/prefs_util.cc",
"//chrome/browser/printing/prefs_util.h",
"//chrome/browser/printing/print_job.cc", "//chrome/browser/printing/print_job.cc",
"//chrome/browser/printing/print_job.h", "//chrome/browser/printing/print_job.h",
"//chrome/browser/printing/print_job_manager.cc", "//chrome/browser/printing/print_job_manager.cc",

View File

@@ -15,7 +15,7 @@ Shortcuts are registered with the [`globalShortcut`](global-shortcut.md) module
using the [`register`](global-shortcut.md#globalshortcutregisteraccelerator-callback) using the [`register`](global-shortcut.md#globalshortcutregisteraccelerator-callback)
method, i.e. method, i.e.
```javascript ```js
const { app, globalShortcut } = require('electron') const { app, globalShortcut } = require('electron')
app.whenReady().then(() => { app.whenReady().then(() => {

View File

@@ -1134,11 +1134,11 @@ indicates success while any other value indicates failure according to Chromium
resolver will attempt to use the system's DNS settings to do DNS lookups resolver will attempt to use the system's DNS settings to do DNS lookups
itself. Enabled by default on macOS, disabled by default on Windows and itself. Enabled by default on macOS, disabled by default on Windows and
Linux. Linux.
* `secureDnsMode` string (optional) - Can be "off", "automatic" or "secure". * `secureDnsMode` string (optional) - Can be 'off', 'automatic' or 'secure'.
Configures the DNS-over-HTTP mode. When "off", no DoH lookups will be Configures the DNS-over-HTTP mode. When 'off', no DoH lookups will be
performed. When "automatic", DoH lookups will be performed first if DoH is performed. When 'automatic', DoH lookups will be performed first if DoH is
available, and insecure DNS lookups will be performed as a fallback. When available, and insecure DNS lookups will be performed as a fallback. When
"secure", only DoH lookups will be performed. Defaults to "automatic". 'secure', only DoH lookups will be performed. Defaults to 'automatic'.
* `secureDnsServers` string[]&#32;(optional) - A list of DNS-over-HTTP * `secureDnsServers` string[]&#32;(optional) - A list of DNS-over-HTTP
server templates. See [RFC8484 § 3][] for details on the template format. server templates. See [RFC8484 § 3][] for details on the template format.
Most servers support the POST method; the template for such servers is Most servers support the POST method; the template for such servers is
@@ -1542,7 +1542,7 @@ A `boolean` property that returns `true` if the app is packaged, `false` otherw
[tasks]:https://learn.microsoft.com/en-us/windows/win32/shell/taskbar-extensions#tasks [tasks]:https://learn.microsoft.com/en-us/windows/win32/shell/taskbar-extensions#tasks
[app-user-model-id]: https://learn.microsoft.com/en-us/windows/win32/shell/appids [app-user-model-id]: https://learn.microsoft.com/en-us/windows/win32/shell/appids
[electron-forge]: https://www.electronforge.io/ [electron-forge]: https://www.electronforge.io/
[electron-packager]: https://github.com/electron/electron-packager [electron-packager]: https://github.com/electron/packager
[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115 [CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115
[LSCopyDefaultHandlerForURLScheme]: https://developer.apple.com/documentation/coreservices/1441725-lscopydefaulthandlerforurlscheme?language=objc [LSCopyDefaultHandlerForURLScheme]: https://developer.apple.com/documentation/coreservices/1441725-lscopydefaulthandlerforurlscheme?language=objc
[handoff]: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html [handoff]: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html

View File

@@ -16,7 +16,7 @@ module is emitted.
### Example ### Example
```javascript ```js
// In the main process. // In the main process.
const { app, BrowserView, BrowserWindow } = require('electron') const { app, BrowserView, BrowserWindow } = require('electron')

View File

@@ -7,7 +7,7 @@ Process: [Main](../glossary.md#main-process)
This module cannot be used until the `ready` event of the `app` This module cannot be used until the `ready` event of the `app`
module is emitted. module is emitted.
```javascript ```js
// In the main process. // In the main process.
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
@@ -38,7 +38,7 @@ While loading the page, the `ready-to-show` event will be emitted when the rende
process has rendered the page for the first time if the window has not been shown yet. Showing process has rendered the page for the first time if the window has not been shown yet. Showing
the window after this event will have no visual flash: the window after this event will have no visual flash:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ show: false }) const win = new BrowserWindow({ show: false })
win.once('ready-to-show', () => { win.once('ready-to-show', () => {
@@ -59,7 +59,7 @@ For a complex app, the `ready-to-show` event could be emitted too late, making
the app feel slow. In this case, it is recommended to show the window the app feel slow. In this case, it is recommended to show the window
immediately, and use a `backgroundColor` close to your app's background: immediately, and use a `backgroundColor` close to your app's background:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ backgroundColor: '#2e2c29' }) const win = new BrowserWindow({ backgroundColor: '#2e2c29' })
@@ -85,7 +85,7 @@ For more information about these color types see valid options in [win.setBackgr
By using `parent` option, you can create child windows: By using `parent` option, you can create child windows:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const top = new BrowserWindow() const top = new BrowserWindow()
@@ -101,7 +101,7 @@ The `child` window will always show on top of the `top` window.
A modal window is a child window that disables parent window, to create a modal A modal window is a child window that disables parent window, to create a modal
window, you have to set both `parent` and `modal` options: window, you have to set both `parent` and `modal` options:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const top = new BrowserWindow() const top = new BrowserWindow()
@@ -188,7 +188,7 @@ window should be closed, which will also be called when the window is
reloaded. In Electron, returning any value other than `undefined` would cancel the reloaded. In Electron, returning any value other than `undefined` would cancel the
close. For example: close. For example:
```javascript ```js
window.onbeforeunload = (e) => { window.onbeforeunload = (e) => {
console.log('I do not want to be closed') console.log('I do not want to be closed')
@@ -351,7 +351,7 @@ Commands are lowercased, underscores are replaced with hyphens, and the
`APPCOMMAND_` prefix is stripped off. `APPCOMMAND_` prefix is stripped off.
e.g. `APPCOMMAND_BROWSER_BACKWARD` is emitted as `browser-backward`. e.g. `APPCOMMAND_BROWSER_BACKWARD` is emitted as `browser-backward`.
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
win.on('app-command', (e, cmd) => { win.on('app-command', (e, cmd) => {
@@ -456,7 +456,7 @@ Returns `BrowserWindow | null` - The window with the given `id`.
Objects created with `new BrowserWindow` have the following properties: Objects created with `new BrowserWindow` have the following properties:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
// In this example `win` is our instance // In this example `win` is our instance
const win = new BrowserWindow({ width: 800, height: 600 }) const win = new BrowserWindow({ width: 800, height: 600 })
@@ -780,7 +780,7 @@ Closes the currently open [Quick Look][quick-look] panel.
Resizes and moves the window to the supplied bounds. Any properties that are not supplied will default to their current values. Resizes and moves the window to the supplied bounds. Any properties that are not supplied will default to their current values.
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
@@ -1035,7 +1035,7 @@ Changes the attachment point for sheets on macOS. By default, sheets are
attached just below the window frame, but you may want to display them beneath attached just below the window frame, but you may want to display them beneath
a HTML-rendered toolbar. For example: a HTML-rendered toolbar. For example:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
@@ -1178,7 +1178,7 @@ To ensure that file URLs are properly formatted, it is recommended to use
Node's [`url.format`](https://nodejs.org/api/url.html#url_url_format_urlobject) Node's [`url.format`](https://nodejs.org/api/url.html#url_url_format_urlobject)
method: method:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
@@ -1194,7 +1194,7 @@ win.loadURL(url)
You can load a URL using a `POST` request with URL-encoded data by doing You can load a URL using a `POST` request with URL-encoded data by doing
the following: the following:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()

View File

@@ -65,7 +65,7 @@ strictly follow the Node.js model as described in the
For instance, we could have created the same request to 'github.com' as follows: For instance, we could have created the same request to 'github.com' as follows:
```javascript ```js
const request = net.request({ const request = net.request({
method: 'GET', method: 'GET',
protocol: 'https:', protocol: 'https:',
@@ -104,7 +104,7 @@ The `callback` function is expected to be called back with user credentials:
* `username` string * `username` string
* `password` string * `password` string
```javascript @ts-type={request:Electron.ClientRequest} ```js @ts-type={request:Electron.ClientRequest}
request.on('login', (authInfo, callback) => { request.on('login', (authInfo, callback) => {
callback('username', 'password') callback('username', 'password')
}) })
@@ -113,7 +113,7 @@ request.on('login', (authInfo, callback) => {
Providing empty credentials will cancel the request and report an authentication Providing empty credentials will cancel the request and report an authentication
error on the response object: error on the response object:
```javascript @ts-type={request:Electron.ClientRequest} ```js @ts-type={request:Electron.ClientRequest}
request.on('response', (response) => { request.on('response', (response) => {
console.log(`STATUS: ${response.statusCode}`) console.log(`STATUS: ${response.statusCode}`)
response.on('error', (error) => { response.on('error', (error) => {

View File

@@ -7,7 +7,7 @@ Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer
On Linux, there is also a `selection` clipboard. To manipulate it On Linux, there is also a `selection` clipboard. To manipulate it
you need to pass `selection` to each method: you need to pass `selection` to each method:
```javascript ```js
const { clipboard } = require('electron') const { clipboard } = require('electron')
clipboard.writeText('Example string', 'selection') clipboard.writeText('Example string', 'selection')

View File

@@ -6,7 +6,7 @@ You can use [app.commandLine.appendSwitch][append-switch] to append them in
your app's main script before the [ready][ready] event of the [app][app] module your app's main script before the [ready][ready] event of the [app][app] module
is emitted: is emitted:
```javascript ```js
const { app } = require('electron') const { app } = require('electron')
app.commandLine.appendSwitch('remote-debugging-port', '8315') app.commandLine.appendSwitch('remote-debugging-port', '8315')
app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1') app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1')
@@ -185,7 +185,7 @@ list of hosts. This flag has an effect only if used in tandem with
For example: For example:
```javascript ```js
const { app } = require('electron') const { app } = require('electron')
app.commandLine.appendSwitch('proxy-bypass-list', '<local>;*.google.com;*foo.com;1.2.3.4:5678') app.commandLine.appendSwitch('proxy-bypass-list', '<local>;*.google.com;*foo.com;1.2.3.4:5678')
``` ```

View File

@@ -7,7 +7,7 @@ _This class is not exported from the `'electron'` module. It is only available a
The following example shows how to check if the `--disable-gpu` flag is set. The following example shows how to check if the `--disable-gpu` flag is set.
```javascript ```js
const { app } = require('electron') const { app } = require('electron')
app.commandLine.hasSwitch('disable-gpu') app.commandLine.hasSwitch('disable-gpu')
``` ```

View File

@@ -10,7 +10,7 @@ This module does not include a web interface. To view recorded traces, use
**Note:** You should not use this module until the `ready` event of the app **Note:** You should not use this module until the `ready` event of the app
module is emitted. module is emitted.
```javascript ```js
const { app, contentTracing } = require('electron') const { app, contentTracing } = require('electron')
app.whenReady().then(() => { app.whenReady().then(() => {

View File

@@ -6,7 +6,7 @@ Process: [Renderer](../glossary.md#renderer-process)
An example of exposing an API to a renderer from an isolated preload script is given below: An example of exposing an API to a renderer from an isolated preload script is given below:
```javascript ```js
// Preload (Isolated World) // Preload (Isolated World)
const { contextBridge, ipcRenderer } = require('electron') const { contextBridge, ipcRenderer } = require('electron')
@@ -18,7 +18,7 @@ contextBridge.exposeInMainWorld(
) )
``` ```
```javascript @ts-nocheck ```js @ts-nocheck
// Renderer (Main World) // Renderer (Main World)
window.electron.doThing() window.electron.doThing()
@@ -64,7 +64,7 @@ the API become immutable and updates on either side of the bridge do not result
An example of a complex API is shown below: An example of a complex API is shown below:
```javascript ```js
const { contextBridge, ipcRenderer } = require('electron') const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld( contextBridge.exposeInMainWorld(
@@ -92,7 +92,7 @@ contextBridge.exposeInMainWorld(
An example of `exposeInIsolatedWorld` is shown below: An example of `exposeInIsolatedWorld` is shown below:
```javascript ```js
const { contextBridge, ipcRenderer } = require('electron') const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInIsolatedWorld( contextBridge.exposeInIsolatedWorld(
@@ -104,7 +104,7 @@ contextBridge.exposeInIsolatedWorld(
) )
``` ```
```javascript @ts-nocheck ```js @ts-nocheck
// Renderer (In isolated world id1004) // Renderer (In isolated world id1004)
window.electron.doThing() window.electron.doThing()
@@ -145,7 +145,7 @@ The table of supported types described above also applies to Node APIs that you
Please note that many Node APIs grant access to local system resources. Please note that many Node APIs grant access to local system resources.
Be very cautious about which globals and APIs you expose to untrusted remote content. Be very cautious about which globals and APIs you expose to untrusted remote content.
```javascript ```js
const { contextBridge } = require('electron') const { contextBridge } = require('electron')
const crypto = require('node:crypto') const crypto = require('node:crypto')
contextBridge.exposeInMainWorld('nodeCrypto', { contextBridge.exposeInMainWorld('nodeCrypto', {

View File

@@ -10,7 +10,7 @@ a `Session`.
For example: For example:
```javascript ```js
const { session } = require('electron') const { session } = require('electron')
// Query all cookies. // Query all cookies.

View File

@@ -7,7 +7,7 @@ Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer
The following is an example of setting up Electron to automatically submit The following is an example of setting up Electron to automatically submit
crash reports to a remote server: crash reports to a remote server:
```javascript ```js
const { crashReporter } = require('electron') const { crashReporter } = require('electron')
crashReporter.start({ submitURL: 'https://your-domain.com/url-to-submit' }) crashReporter.start({ submitURL: 'https://your-domain.com/url-to-submit' })

View File

@@ -8,7 +8,7 @@ _This class is not exported from the `'electron'` module. It is only available a
Chrome Developer Tools has a [special binding][rdp] available at JavaScript Chrome Developer Tools has a [special binding][rdp] available at JavaScript
runtime that allows interacting with pages and instrumenting them. runtime that allows interacting with pages and instrumenting them.
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()

View File

@@ -8,7 +8,7 @@ Process: [Main](../glossary.md#main-process)
The following example shows how to capture video from a desktop window whose The following example shows how to capture video from a desktop window whose
title is `Electron`: title is `Electron`:
```javascript ```js
// In the main process. // In the main process.
const { BrowserWindow, desktopCapturer } = require('electron') const { BrowserWindow, desktopCapturer } = require('electron')
@@ -24,7 +24,7 @@ desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources =
}) })
``` ```
```javascript @ts-nocheck ```js @ts-nocheck
// In the preload script. // In the preload script.
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
@@ -68,7 +68,7 @@ To capture both audio and video from the entire desktop the constraints passed
to [`navigator.mediaDevices.getUserMedia`][] must include `chromeMediaSource: 'desktop'`, to [`navigator.mediaDevices.getUserMedia`][] must include `chromeMediaSource: 'desktop'`,
for both `audio` and `video`, but should not include a `chromeMediaSourceId` constraint. for both `audio` and `video`, but should not include a `chromeMediaSourceId` constraint.
```javascript ```js
const constraints = { const constraints = {
audio: { audio: {
mandatory: { mandatory: {

View File

@@ -6,7 +6,7 @@ Process: [Main](../glossary.md#main-process)
An example of showing a dialog to select multiple files: An example of showing a dialog to select multiple files:
```javascript ```js
const { dialog } = require('electron') const { dialog } = require('electron')
console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] })) console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
``` ```
@@ -52,7 +52,7 @@ The `browserWindow` argument allows the dialog to attach itself to a parent wind
The `filters` specifies an array of file types that can be displayed or The `filters` specifies an array of file types that can be displayed or
selected when you want to limit the user to a specific type. For example: selected when you want to limit the user to a specific type. For example:
```javascript ```js
{ {
filters: [ filters: [
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }, { name: 'Images', extensions: ['jpg', 'png', 'gif'] },
@@ -119,7 +119,7 @@ The `browserWindow` argument allows the dialog to attach itself to a parent wind
The `filters` specifies an array of file types that can be displayed or The `filters` specifies an array of file types that can be displayed or
selected when you want to limit the user to a specific type. For example: selected when you want to limit the user to a specific type. For example:
```javascript ```js
{ {
filters: [ filters: [
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }, { name: 'Images', extensions: ['jpg', 'png', 'gif'] },

View File

@@ -7,7 +7,7 @@ _This class is not exported from the `'electron'` module. It is only available a
The following example shows how to bounce your icon on the dock. The following example shows how to bounce your icon on the dock.
```javascript ```js
const { app } = require('electron') const { app } = require('electron')
app.dock.bounce() app.dock.bounce()
``` ```

View File

@@ -9,7 +9,7 @@ _This class is not exported from the `'electron'` module. It is only available a
It is used in `will-download` event of `Session` class, and allows users to It is used in `will-download` event of `Session` class, and allows users to
control the download item. control the download item.
```javascript ```js
// In the main process. // In the main process.
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()

View File

@@ -59,7 +59,7 @@ geolocation webservice. To enable this feature, acquire a
and place the following code in your main process file, before opening any and place the following code in your main process file, before opening any
browser windows that will make geolocation requests: browser windows that will make geolocation requests:
```javascript ```js
process.env.GOOGLE_API_KEY = 'YOUR_KEY_HERE' process.env.GOOGLE_API_KEY = 'YOUR_KEY_HERE'
``` ```

View File

@@ -12,7 +12,7 @@ shortcuts.
not have the keyboard focus. This module cannot be used before the `ready` not have the keyboard focus. This module cannot be used before the `ready`
event of the app module is emitted. event of the app module is emitted.
```javascript ```js
const { app, globalShortcut } = require('electron') const { app, globalShortcut } = require('electron')
app.whenReady().then(() => { app.whenReady().then(() => {

View File

@@ -89,7 +89,7 @@ tuples. So, the even-numbered offsets are key values, and the odd-numbered
offsets are the associated values. Header names are not lowercased, and offsets are the associated values. Header names are not lowercased, and
duplicates are not merged. duplicates are not merged.
```javascript @ts-type={response:Electron.IncomingMessage} ```js @ts-type={response:Electron.IncomingMessage}
// Prints something like: // Prints something like:
// //
// [ 'user-agent', // [ 'user-agent',

View File

@@ -120,7 +120,7 @@ The main process should listen for `channel` with
For example: For example:
```javascript @ts-type={someArgument:unknown} @ts-type={doSomeWork:(arg:unknown)=>Promise<unknown>} ```js @ts-type={someArgument:unknown} @ts-type={doSomeWork:(arg:unknown)=>Promise<unknown>}
// Renderer process // Renderer process
ipcRenderer.invoke('some-name', someArgument).then((result) => { ipcRenderer.invoke('some-name', someArgument).then((result) => {
// ... // ...

View File

@@ -151,7 +151,7 @@ can have a submenu.
An example of creating the application menu with the simple template API: An example of creating the application menu with the simple template API:
```javascript @ts-expect-error=[107] ```js @ts-expect-error=[107]
const { app, Menu } = require('electron') const { app, Menu } = require('electron')
const isMac = process.platform === 'darwin' const isMac = process.platform === 'darwin'
@@ -353,7 +353,7 @@ By default, items will be inserted in the order they exist in the template unles
Template: Template:
```javascript ```js
[ [
{ id: '1', label: 'one' }, { id: '1', label: 'one' },
{ id: '2', label: 'two' }, { id: '2', label: 'two' },
@@ -373,7 +373,7 @@ Menu:
Template: Template:
```javascript ```js
[ [
{ id: '1', label: 'one' }, { id: '1', label: 'one' },
{ type: 'separator' }, { type: 'separator' },
@@ -397,7 +397,7 @@ Menu:
Template: Template:
```javascript ```js
[ [
{ id: '1', label: 'one', after: ['3'] }, { id: '1', label: 'one', after: ['3'] },
{ id: '2', label: 'two', before: ['1'] }, { id: '2', label: 'two', before: ['1'] },

View File

@@ -10,7 +10,7 @@ In Electron, for the APIs that take images, you can pass either file paths or
For example, when creating a tray or setting a window's icon, you can pass an For example, when creating a tray or setting a window's icon, you can pass an
image file path as a `string`: image file path as a `string`:
```javascript ```js
const { BrowserWindow, Tray } = require('electron') const { BrowserWindow, Tray } = require('electron')
const appIcon = new Tray('/Users/somebody/images/icon.png') const appIcon = new Tray('/Users/somebody/images/icon.png')
@@ -20,7 +20,7 @@ console.log(appIcon, win)
Or read the image from the clipboard, which returns a `NativeImage`: Or read the image from the clipboard, which returns a `NativeImage`:
```javascript ```js
const { clipboard, Tray } = require('electron') const { clipboard, Tray } = require('electron')
const image = clipboard.readImage() const image = clipboard.readImage()
const appIcon = new Tray(image) const appIcon = new Tray(image)
@@ -71,7 +71,7 @@ images/
└── icon@3x.png └── icon@3x.png
``` ```
```javascript ```js
const { Tray } = require('electron') const { Tray } = require('electron')
const appIcon = new Tray('/Users/somebody/images/icon.png') const appIcon = new Tray('/Users/somebody/images/icon.png')
console.log(appIcon) console.log(appIcon)
@@ -138,7 +138,7 @@ Creates a new `NativeImage` instance from a file located at `path`. This method
returns an empty image if the `path` does not exist, cannot be read, or is not returns an empty image if the `path` does not exist, cannot be read, or is not
a valid image. a valid image.
```javascript ```js
const nativeImage = require('electron').nativeImage const nativeImage = require('electron').nativeImage
const image = nativeImage.createFromPath('/Users/somebody/images/icon.png') const image = nativeImage.createFromPath('/Users/somebody/images/icon.png')

View File

@@ -4,7 +4,7 @@
Process: [Main](../glossary.md#main-process) Process: [Main](../glossary.md#main-process)
```javascript ```js
const { app, netLog } = require('electron') const { app, netLog } = require('electron')
app.whenReady().then(async () => { app.whenReady().then(async () => {

View File

@@ -26,7 +26,7 @@ Node.js.
Example usage: Example usage:
```javascript ```js
const { app } = require('electron') const { app } = require('electron')
app.whenReady().then(() => { app.whenReady().then(() => {
const { net } = require('electron') const { net } = require('electron')

View File

@@ -85,6 +85,8 @@ Emitted when the notification is closed by manual intervention from the user.
This event is not guaranteed to be emitted in all cases where the notification This event is not guaranteed to be emitted in all cases where the notification
is closed. is closed.
On Windows, the `close` event can be emitted in one of three ways: programmatic dismissal with `notification.close()`, by the user closing the notification, or via system timeout. If a notification is in the Action Center after the initial `close` event is emitted, a call to `notification.close()` will remove the notification from the action center but the `close` event will not be emitted again.
#### Event: 'reply' _macOS_ #### Event: 'reply' _macOS_
Returns: Returns:
@@ -127,6 +129,8 @@ shown notification and create a new one with identical properties.
Dismisses the notification. Dismisses the notification.
On Windows, calling `notification.close()` while the notification is visible on screen will dismiss the notification and remove it from the Action Center. If `notification.close()` is called after the notification is no longer visible on screen, calling `notification.close()` will try remove it from the Action Center.
### Instance Properties ### Instance Properties
#### `notification.title` #### `notification.title`

View File

@@ -6,7 +6,7 @@ Process: [Main](../glossary.md#main-process)
For example: For example:
```javascript ```js
const { powerSaveBlocker } = require('electron') const { powerSaveBlocker } = require('electron')
const id = powerSaveBlocker.start('prevent-display-sleep') const id = powerSaveBlocker.start('prevent-display-sleep')

View File

@@ -7,7 +7,7 @@ Process: [Main](../glossary.md#main-process)
An example of implementing a protocol that has the same effect as the An example of implementing a protocol that has the same effect as the
`file://` protocol: `file://` protocol:
```javascript ```js
const { app, protocol, net } = require('electron') const { app, protocol, net } = require('electron')
app.whenReady().then(() => { app.whenReady().then(() => {
@@ -31,7 +31,7 @@ a different session and your custom protocol will not work if you just use
To have your custom protocol work in combination with a custom session, you need To have your custom protocol work in combination with a custom session, you need
to register it to that session explicitly. to register it to that session explicitly.
```javascript ```js
const { app, BrowserWindow, net, protocol, session } = require('electron') const { app, BrowserWindow, net, protocol, session } = require('electron')
const path = require('node:path') const path = require('node:path')
const url = require('url') const url = require('url')
@@ -61,13 +61,14 @@ The `protocol` module has the following methods:
module gets emitted and can be called only once. module gets emitted and can be called only once.
Registers the `scheme` as standard, secure, bypasses content security policy for Registers the `scheme` as standard, secure, bypasses content security policy for
resources, allows registering ServiceWorker, supports fetch API, and streaming resources, allows registering ServiceWorker, supports fetch API, streaming
video/audio. Specify a privilege with the value of `true` to enable the capability. video/audio, and V8 code cache. Specify a privilege with the value of `true` to
enable the capability.
An example of registering a privileged scheme, that bypasses Content Security An example of registering a privileged scheme, that bypasses Content Security
Policy: Policy:
```javascript ```js
const { protocol } = require('electron') const { protocol } = require('electron')
protocol.registerSchemesAsPrivileged([ protocol.registerSchemesAsPrivileged([
{ scheme: 'foo', privileges: { bypassCSP: true } } { scheme: 'foo', privileges: { bypassCSP: true } }
@@ -212,7 +213,7 @@ property.
Example: Example:
```javascript ```js
protocol.registerBufferProtocol('atom', (request, callback) => { protocol.registerBufferProtocol('atom', (request, callback) => {
callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') }) callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') })
}) })
@@ -267,7 +268,7 @@ has the `data` property.
Example: Example:
```javascript ```js
const { protocol } = require('electron') const { protocol } = require('electron')
const { PassThrough } = require('stream') const { PassThrough } = require('stream')
@@ -292,7 +293,7 @@ protocol.registerStreamProtocol('atom', (request, callback) => {
It is possible to pass any object that implements the readable stream API (emits It is possible to pass any object that implements the readable stream API (emits
`data`/`end`/`error` events). For example, here's how a file could be returned: `data`/`end`/`error` events). For example, here's how a file could be returned:
```javascript ```js
protocol.registerStreamProtocol('atom', (request, callback) => { protocol.registerStreamProtocol('atom', (request, callback) => {
callback(fs.createReadStream('index.html')) callback(fs.createReadStream('index.html'))
}) })

View File

@@ -6,7 +6,7 @@ Process: [Main](../glossary.md#main-process)
For example, when registering for push notifications via Apple push notification services (APNS): For example, when registering for push notifications via Apple push notification services (APNS):
```javascript ```js
const { pushNotifications, Notification } = require('electron') const { pushNotifications, Notification } = require('electron')
pushNotifications.registerForAPNSNotifications().then((token) => { pushNotifications.registerForAPNSNotifications().then((token) => {

View File

@@ -14,20 +14,29 @@ property, so writing `let { screen } = require('electron')` will not work.
An example of creating a window that fills the whole screen: An example of creating a window that fills the whole screen:
```javascript fiddle='docs/fiddles/screen/fit-screen' ```fiddle docs/fiddles/screen/fit-screen
const { app, BrowserWindow, screen } = require('electron') // Retrieve information about screen size, displays, cursor position, etc.
//
// For more info, see:
// https://www.electronjs.org/docs/latest/api/screen
const { app, BrowserWindow, screen } = require('electron/main')
let mainWindow = null
let win
app.whenReady().then(() => { app.whenReady().then(() => {
const { width, height } = screen.getPrimaryDisplay().workAreaSize // Create a window that fills the screen's available work area.
win = new BrowserWindow({ width, height }) const primaryDisplay = screen.getPrimaryDisplay()
win.loadURL('https://github.com') const { width, height } = primaryDisplay.workAreaSize
mainWindow = new BrowserWindow({ width, height })
mainWindow.loadURL('https://electronjs.org')
}) })
``` ```
Another example of creating a window in the external display: Another example of creating a window in the external display:
```javascript ```js
const { app, BrowserWindow, screen } = require('electron') const { app, BrowserWindow, screen } = require('electron')
let win let win

View File

@@ -10,7 +10,7 @@ a `Session`.
For example: For example:
```javascript ```js
const { session } = require('electron') const { session } = require('electron')
// Get all service workers. // Get all service workers.

View File

@@ -9,7 +9,7 @@ The `session` module can be used to create new `Session` objects.
You can also access the `session` of existing pages by using the `session` You can also access the `session` of existing pages by using the `session`
property of [`WebContents`](web-contents.md), or from the `session` module. property of [`WebContents`](web-contents.md), or from the `session` module.
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 600 }) const win = new BrowserWindow({ width: 800, height: 600 })
@@ -75,7 +75,7 @@ _This class is not exported from the `'electron'` module. It is only available a
You can create a `Session` object in the `session` module: You can create a `Session` object in the `session` module:
```javascript ```js
const { session } = require('electron') const { session } = require('electron')
const ses = session.fromPartition('persist:name') const ses = session.fromPartition('persist:name')
console.log(ses.getUserAgent()) console.log(ses.getUserAgent())
@@ -98,7 +98,7 @@ Emitted when Electron is about to download `item` in `webContents`.
Calling `event.preventDefault()` will cancel the download and `item` will not be Calling `event.preventDefault()` will cancel the download and `item` will not be
available from next tick of the process. available from next tick of the process.
```javascript @ts-expect-error=[4] ```js @ts-expect-error=[4]
const { session } = require('electron') const { session } = require('electron')
session.defaultSession.on('will-download', (event, item, webContents) => { session.defaultSession.on('will-download', (event, item, webContents) => {
event.preventDefault() event.preventDefault()
@@ -214,7 +214,7 @@ cancel the request. Additionally, permissioning on `navigator.hid` can
be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler) be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler)
and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler). and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler).
```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)} ```js @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let win = null let win = null
@@ -266,7 +266,7 @@ Returns:
* `event` Event * `event` Event
* `details` Object * `details` Object
* `device` [HIDDevice[]](structures/hid-device.md) * `device` [HIDDevice](structures/hid-device.md)
* `frame` [WebFrameMain](web-frame-main.md) * `frame` [WebFrameMain](web-frame-main.md)
Emitted after `navigator.hid.requestDevice` has been called and Emitted after `navigator.hid.requestDevice` has been called and
@@ -281,7 +281,7 @@ Returns:
* `event` Event * `event` Event
* `details` Object * `details` Object
* `device` [HIDDevice[]](structures/hid-device.md) * `device` [HIDDevice](structures/hid-device.md)
* `frame` [WebFrameMain](web-frame-main.md) * `frame` [WebFrameMain](web-frame-main.md)
Emitted after `navigator.hid.requestDevice` has been called and Emitted after `navigator.hid.requestDevice` has been called and
@@ -296,7 +296,7 @@ Returns:
* `event` Event * `event` Event
* `details` Object * `details` Object
* `device` [HIDDevice[]](structures/hid-device.md) * `device` [HIDDevice](structures/hid-device.md)
* `origin` string (optional) - The origin that the device has been revoked from. * `origin` string (optional) - The origin that the device has been revoked from.
Emitted after `HIDDevice.forget()` has been called. This event can be used Emitted after `HIDDevice.forget()` has been called. This event can be used
@@ -320,7 +320,7 @@ cancel the request. Additionally, permissioning on `navigator.serial` can
be managed by using [ses.setPermissionCheckHandler(handler)](#sessetpermissioncheckhandlerhandler) be managed by using [ses.setPermissionCheckHandler(handler)](#sessetpermissioncheckhandlerhandler)
with the `serial` permission. with the `serial` permission.
```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)} ```js @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let win = null let win = null
@@ -463,7 +463,7 @@ cancel the request. Additionally, permissioning on `navigator.usb` can
be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler) be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler)
and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler). and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler).
```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)} @ts-type={updateGrantedDevices:(devices:Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)=>void} ```js @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)} @ts-type={updateGrantedDevices:(devices:Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)=>void}
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let win = null let win = null
@@ -754,7 +754,7 @@ Sets download saving directory. By default, the download directory will be the
Emulates network with the given configuration for the `session`. Emulates network with the given configuration for the `session`.
```javascript ```js
const win = new BrowserWindow() const win = new BrowserWindow()
// To emulate a GPRS connection with 50kbps throughput and 500 ms latency. // To emulate a GPRS connection with 50kbps throughput and 500 ms latency.
@@ -785,7 +785,7 @@ Returns `Promise<void>` - Resolves when all connections are closed.
#### `ses.fetch(input[, init])` #### `ses.fetch(input[, init])`
* `input` string | [GlobalRequest](https://nodejs.org/api/globals.html#request) * `input` string | [GlobalRequest](https://nodejs.org/api/globals.html#request)
* `init` [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/fetch#options) (optional) * `init` [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/fetch#options) & { bypassCustomProtocolHandlers?: boolean } (optional)
Returns `Promise<GlobalResponse>` - see [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response). Returns `Promise<GlobalResponse>` - see [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).
@@ -868,7 +868,7 @@ calling `callback(-2)` rejects it.
Calling `setCertificateVerifyProc(null)` will revert back to default certificate Calling `setCertificateVerifyProc(null)` will revert back to default certificate
verify proc. verify proc.
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
@@ -901,6 +901,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
* `midiSysex` - Request the use of system exclusive messages in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API). * `midiSysex` - Request the use of system exclusive messages in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
* `notifications` - Request notification creation and the ability to display them in the user's system tray using the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/notification) * `notifications` - Request notification creation and the ability to display them in the user's system tray using the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/notification)
* `pointerLock` - Request to directly interpret mouse movements as an input method via the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API). These requests always appear to originate from the main frame. * `pointerLock` - Request to directly interpret mouse movements as an input method via the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API). These requests always appear to originate from the main frame.
* `keyboardLock` - Request capture of keypresses for any or all of the keys on the physical keyboard via the [Keyboard Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Keyboard/lock). These requests always appear to originate from the main frame.
* `openExternal` - Request to open links in external applications. * `openExternal` - Request to open links in external applications.
* `window-management` - Request access to enumerate screens using the [`getScreenDetails`](https://developer.chrome.com/en/articles/multi-screen-window-placement/) API. * `window-management` - Request access to enumerate screens using the [`getScreenDetails`](https://developer.chrome.com/en/articles/multi-screen-window-placement/) API.
* `unknown` - An unrecognized permission request. * `unknown` - An unrecognized permission request.
@@ -920,7 +921,7 @@ To clear the handler, call `setPermissionRequestHandler(null)`. Please note tha
you must also implement `setPermissionCheckHandler` to get complete permission handling. you must also implement `setPermissionCheckHandler` to get complete permission handling.
Most web APIs do a permission check and then make a permission request if the check is denied. Most web APIs do a permission check and then make a permission request if the check is denied.
```javascript ```js
const { session } = require('electron') const { session } = require('electron')
session.fromPartition('some-partition').setPermissionRequestHandler((webContents, permission, callback) => { session.fromPartition('some-partition').setPermissionRequestHandler((webContents, permission, callback) => {
if (webContents.getURL() === 'some-host' && permission === 'notifications') { if (webContents.getURL() === 'some-host' && permission === 'notifications') {
@@ -966,7 +967,7 @@ you must also implement `setPermissionRequestHandler` to get complete permission
Most web APIs do a permission check and then make a permission request if the check is denied. Most web APIs do a permission check and then make a permission request if the check is denied.
To clear the handler, call `setPermissionCheckHandler(null)`. To clear the handler, call `setPermissionCheckHandler(null)`.
```javascript ```js
const { session } = require('electron') const { session } = require('electron')
const url = require('url') const url = require('url')
session.fromPartition('some-partition').setPermissionCheckHandler((webContents, permission, requestingOrigin) => { session.fromPartition('some-partition').setPermissionCheckHandler((webContents, permission, requestingOrigin) => {
@@ -1011,7 +1012,7 @@ via the `navigator.mediaDevices.getDisplayMedia` API. Use the
[desktopCapturer](desktop-capturer.md) API to choose which stream(s) to grant [desktopCapturer](desktop-capturer.md) API to choose which stream(s) to grant
access to. access to.
```javascript ```js
const { session, desktopCapturer } = require('electron') const { session, desktopCapturer } = require('electron')
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => { session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
@@ -1025,7 +1026,7 @@ session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
Passing a [WebFrameMain](web-frame-main.md) object as a video or audio stream Passing a [WebFrameMain](web-frame-main.md) object as a video or audio stream
will capture the video or audio stream from that frame. will capture the video or audio stream from that frame.
```javascript ```js
const { session } = require('electron') const { session } = require('electron')
session.defaultSession.setDisplayMediaRequestHandler((request, callback) => { session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
@@ -1054,7 +1055,7 @@ Additionally, the default behavior of Electron is to store granted device permis
If longer term storage is needed, a developer can store granted device If longer term storage is needed, a developer can store granted device
permissions (eg when handling the `select-hid-device` event) and then read from that storage with `setDevicePermissionHandler`. permissions (eg when handling the `select-hid-device` event) and then read from that storage with `setDevicePermissionHandler`.
```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)} ```js @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let win = null let win = null
@@ -1136,7 +1137,7 @@ The return value for the handler is a string array of USB classes which should b
Returning an empty string array from the handler will allow all USB classes; returning the passed in array will maintain the default list of protected USB classes (this is also the default behavior if a handler is not defined). Returning an empty string array from the handler will allow all USB classes; returning the passed in array will maintain the default list of protected USB classes (this is also the default behavior if a handler is not defined).
To clear the handler, call `setUSBProtectedClassesHandler(null)`. To clear the handler, call `setUSBProtectedClassesHandler(null)`.
```javascript ```js
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let win = null let win = null
@@ -1191,7 +1192,7 @@ that requires additional validation will be automatically cancelled.
macOS does not require a handler because macOS handles the pairing macOS does not require a handler because macOS handles the pairing
automatically. To clear the handler, call `setBluetoothPairingHandler(null)`. automatically. To clear the handler, call `setBluetoothPairingHandler(null)`.
```javascript ```js
const { app, BrowserWindow, session } = require('electron') const { app, BrowserWindow, session } = require('electron')
const path = require('node:path') const path = require('node:path')
@@ -1237,7 +1238,7 @@ Clears the host resolver cache.
Dynamically sets whether to always send credentials for HTTP NTLM or Negotiate Dynamically sets whether to always send credentials for HTTP NTLM or Negotiate
authentication. authentication.
```javascript ```js
const { session } = require('electron') const { session } = require('electron')
// consider any url ending with `example.com`, `foobar.com`, `baz` // consider any url ending with `example.com`, `foobar.com`, `baz`
// for integrated authentication. // for integrated authentication.
@@ -1355,6 +1356,10 @@ registered.
Sets the directory to store the generated JS [code cache](https://v8.dev/blog/code-caching-for-devs) for this session. The directory is not required to be created by the user before this call, the runtime will create if it does not exist otherwise will use the existing directory. If directory cannot be created, then code cache will not be used and all operations related to code cache will fail silently inside the runtime. By default, the directory will be `Code Cache` under the Sets the directory to store the generated JS [code cache](https://v8.dev/blog/code-caching-for-devs) for this session. The directory is not required to be created by the user before this call, the runtime will create if it does not exist otherwise will use the existing directory. If directory cannot be created, then code cache will not be used and all operations related to code cache will fail silently inside the runtime. By default, the directory will be `Code Cache` under the
respective user data folder. respective user data folder.
Note that by default code cache is only enabled for http(s) URLs, to enable code
cache for custom protocols, `codeCache: true` and `standard: true` must be
specified when registering the protocol.
#### `ses.clearCodeCaches(options)` #### `ses.clearCodeCaches(options)`
* `options` Object * `options` Object
@@ -1542,7 +1547,7 @@ A [`WebRequest`](web-request.md) object for this session.
A [`Protocol`](protocol.md) object for this session. A [`Protocol`](protocol.md) object for this session.
```javascript ```js
const { app, session } = require('electron') const { app, session } = require('electron')
const path = require('node:path') const path = require('node:path')
@@ -1561,7 +1566,7 @@ app.whenReady().then(() => {
A [`NetLog`](net-log.md) object for this session. A [`NetLog`](net-log.md) object for this session.
```javascript ```js
const { app, session } = require('electron') const { app, session } = require('electron')
app.whenReady().then(async () => { app.whenReady().then(async () => {

View File

@@ -8,7 +8,7 @@ The `shell` module provides functions related to desktop integration.
An example of opening a URL in the user's default browser: An example of opening a URL in the user's default browser:
```javascript ```js
const { shell } = require('electron') const { shell } = require('electron')
shell.openExternal('https://github.com') shell.openExternal('https://github.com')

View File

@@ -9,3 +9,5 @@
* `supportFetchAPI` boolean (optional) - Default false. * `supportFetchAPI` boolean (optional) - Default false.
* `corsEnabled` boolean (optional) - Default false. * `corsEnabled` boolean (optional) - Default false.
* `stream` boolean (optional) - Default false. * `stream` boolean (optional) - Default false.
* `codeCache` boolean (optional) - Enable V8 code cache for the scheme, only
works when `standard` is also set to true. Default false.

View File

@@ -1,22 +1,25 @@
# Display Object # Display Object
* `id` number - Unique identifier associated with the display. * `accelerometerSupport` string - Can be `available`, `unavailable`, `unknown`.
* `bounds` [Rectangle](rectangle.md) - the bounds of the display in DIP points.
* `colorDepth` number - The number of bits per pixel.
* `colorSpace` string - represent a color space (three-dimensional object which contains all realizable color combinations) for the purpose of color conversions.
* `depthPerComponent` number - The number of bits per color component.
* `detected` boolean - `true`` if the display is detected by the system.
* `displayFrequency` number - The display refresh rate.
* `id` number - Unique identifier associated with the display. A value of of -1 means the display is invalid or the correct `id` is not yet known, and a value of -10 means the display is a virtual display assigned to a unified desktop.
* `internal` boolean - `true` for an internal display and `false` for an external display.
* `label` string - User-friendly label, determined by the platform. * `label` string - User-friendly label, determined by the platform.
* `maximumCursorSize` [Size](size.md) - Maximum cursor size in native pixels.
* `nativeOrigin` [Point](point.md) - Returns the display's origin in pixel coordinates. Only available on windowing systems like X11 that position displays in pixel coordinates.
* `rotation` number - Can be 0, 90, 180, 270, represents screen rotation in * `rotation` number - Can be 0, 90, 180, 270, represents screen rotation in
clock-wise degrees. clock-wise degrees.
* `scaleFactor` number - Output device's pixel scale factor. * `scaleFactor` number - Output device's pixel scale factor.
* `touchSupport` string - Can be `available`, `unavailable`, `unknown`. * `touchSupport` string - Can be `available`, `unavailable`, `unknown`.
* `monochrome` boolean - Whether or not the display is a monochrome display. * `monochrome` boolean - Whether or not the display is a monochrome display.
* `accelerometerSupport` string - Can be `available`, `unavailable`, `unknown`.
* `colorSpace` string - represent a color space (three-dimensional object which contains all realizable color combinations) for the purpose of color conversions
* `colorDepth` number - The number of bits per pixel.
* `depthPerComponent` number - The number of bits per color component.
* `displayFrequency` number - The display refresh rate.
* `bounds` [Rectangle](rectangle.md) - the bounds of the display in DIP points.
* `size` [Size](size.md) * `size` [Size](size.md)
* `workArea` [Rectangle](rectangle.md) - the work area of the display in DIP points. * `workArea` [Rectangle](rectangle.md) - the work area of the display in DIP points.
* `workAreaSize` [Size](size.md) * `workAreaSize` [Size](size.md) - The size of the work area.
* `internal` boolean - `true` for an internal display and `false` for an external display
The `Display` object represents a physical display connected to the system. A The `Display` object represents a physical display connected to the system. A
fake `Display` may exist on a headless system, or a `Display` may correspond to fake `Display` may exist on a headless system, or a `Display` may correspond to

View File

@@ -14,7 +14,7 @@ The number represented by `status` means different things on different platforms
Below is an example of some of the additional options that may be set which Below is an example of some of the additional options that may be set which
may be different on each platform. may be different on each platform.
```javascript ```js
{ {
name: 'Austin_4th_Floor_Printer___C02XK13BJHD4', name: 'Austin_4th_Floor_Printer___C02XK13BJHD4',
displayName: 'Austin 4th Floor Printer @ C02XK13BJHD4', displayName: 'Austin 4th Floor Printer @ C02XK13BJHD4',

View File

@@ -4,7 +4,7 @@
Process: [Main](../glossary.md#main-process) Process: [Main](../glossary.md#main-process)
```javascript ```js
const { systemPreferences } = require('electron') const { systemPreferences } = require('electron')
console.log(systemPreferences.isAeroGlassEnabled()) console.log(systemPreferences.isAeroGlassEnabled())
``` ```
@@ -189,7 +189,7 @@ enabled, and `false` otherwise.
An example of using it to determine if you should create a transparent window or An example of using it to determine if you should create a transparent window or
not (transparent windows won't work correctly when DWM composition is disabled): not (transparent windows won't work correctly when DWM composition is disabled):
```javascript ```js
const { BrowserWindow, systemPreferences } = require('electron') const { BrowserWindow, systemPreferences } = require('electron')
const browserOptions = { width: 1000, height: 800 } const browserOptions = { width: 1000, height: 800 }
@@ -348,7 +348,7 @@ Returns `boolean` - whether or not this device has the ability to use Touch ID.
Returns `Promise<void>` - resolves if the user has successfully authenticated with Touch ID. Returns `Promise<void>` - resolves if the user has successfully authenticated with Touch ID.
```javascript ```js
const { systemPreferences } = require('electron') const { systemPreferences } = require('electron')
systemPreferences.promptTouchID('To get consent for a Security-Gated Thing').then(success => { systemPreferences.promptTouchID('To get consent for a Security-Gated Thing').then(success => {

View File

@@ -79,7 +79,7 @@ immediately updates the escape item in the touch bar.
Below is an example of a simple slot machine touch bar game with a button Below is an example of a simple slot machine touch bar game with a button
and some labels. and some labels.
```javascript ```js
const { app, BrowserWindow, TouchBar } = require('electron') const { app, BrowserWindow, TouchBar } = require('electron')
const { TouchBarLabel, TouchBarButton, TouchBarSpacer } = TouchBar const { TouchBarLabel, TouchBarButton, TouchBarSpacer } = TouchBar

View File

@@ -8,7 +8,7 @@ Process: [Main](../glossary.md#main-process)
`Tray` is an [EventEmitter][event-emitter]. `Tray` is an [EventEmitter][event-emitter].
```javascript ```js
const { app, Menu, Tray } = require('electron') const { app, Menu, Tray } = require('electron')
let tray = null let tray = null
@@ -39,7 +39,7 @@ app.whenReady().then(() => {
* In order for changes made to individual `MenuItem`s to take effect, * In order for changes made to individual `MenuItem`s to take effect,
you have to call `setContextMenu` again. For example: you have to call `setContextMenu` again. For example:
```javascript ```js
const { app, Menu, Tray } = require('electron') const { app, Menu, Tray } = require('electron')
let appIcon = null let appIcon = null

View File

@@ -28,8 +28,9 @@ Process: [Main](../glossary.md#main-process)<br />
* `ignore`: equivalent to \['ignore', 'ignore', 'ignore'] * `ignore`: equivalent to \['ignore', 'ignore', 'ignore']
* `inherit`: equivalent to \['ignore', 'inherit', 'inherit'] * `inherit`: equivalent to \['ignore', 'inherit', 'inherit']
* `serviceName` string (optional) - Name of the process that will appear in `name` property of * `serviceName` string (optional) - Name of the process that will appear in `name` property of
[`child-process-gone` event of `app`](app.md#event-child-process-gone). [`ProcessMetric`](structures/process-metric.md) returned by [`app.getAppMetrics`](app.md#appgetappmetrics)
Default is `node.mojom.NodeService`. and [`child-process-gone` event of `app`](app.md#event-child-process-gone).
Default is `Node Utility Process`.
* `allowLoadingUnsignedLibraries` boolean (optional) _macOS_ - With this flag, the utility process will be * `allowLoadingUnsignedLibraries` boolean (optional) _macOS_ - With this flag, the utility process will be
launched via the `Electron Helper (Plugin).app` helper executable on macOS, which can be launched via the `Electron Helper (Plugin).app` helper executable on macOS, which can be
codesigned with `com.apple.security.cs.disable-library-validation` and codesigned with `com.apple.security.cs.disable-library-validation` and

View File

@@ -9,7 +9,7 @@ It is responsible for rendering and controlling a web page and is a property of
the [`BrowserWindow`](browser-window.md) object. An example of accessing the the [`BrowserWindow`](browser-window.md) object. An example of accessing the
`webContents` object: `webContents` object:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 1500 }) const win = new BrowserWindow({ width: 800, height: 1500 })
@@ -53,7 +53,7 @@ If you want to also observe navigations in `<iframe>`s, use [`will-frame-navigat
These methods can be accessed from the `webContents` module: These methods can be accessed from the `webContents` module:
```javascript ```js
const { webContents } = require('electron') const { webContents } = require('electron')
console.log(webContents) console.log(webContents)
``` ```
@@ -439,7 +439,7 @@ Emitted when a `beforeunload` event handler is attempting to cancel a page unloa
Calling `event.preventDefault()` will ignore the `beforeunload` event handler Calling `event.preventDefault()` will ignore the `beforeunload` event handler
and allow the page to be unloaded. and allow the page to be unloaded.
```javascript ```js
const { BrowserWindow, dialog } = require('electron') const { BrowserWindow, dialog } = require('electron')
const win = new BrowserWindow({ width: 800, height: 600 }) const win = new BrowserWindow({ width: 800, height: 600 })
win.webContents.on('will-prevent-unload', (event) => { win.webContents.on('will-prevent-unload', (event) => {
@@ -541,7 +541,7 @@ and the menu shortcuts.
To only prevent the menu shortcuts, use To only prevent the menu shortcuts, use
[`setIgnoreMenuShortcuts`](#contentssetignoremenushortcutsignore): [`setIgnoreMenuShortcuts`](#contentssetignoremenushortcutsignore):
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 600 }) const win = new BrowserWindow({ width: 800, height: 600 })
@@ -783,9 +783,18 @@ Returns:
word and spellchecker is enabled. word and spellchecker is enabled.
* `frameCharset` string - The character encoding of the frame on which the * `frameCharset` string - The character encoding of the frame on which the
menu was invoked. menu was invoked.
* `inputFieldType` string - If the context menu was invoked on an input * `formControlType` string - The source that the context menu was invoked on.
field, the type of that field. Possible values include `none`, `plainText`, Possible values include `none`, `button-button`, `field-set`,
`password`, `other`. `input-button`, `input-checkbox`, `input-color`, `input-date`,
`input-datetime-local`, `input-email`, `input-file`, `input-hidden`,
`input-image`, `input-month`, `input-number`, `input-password`, `input-radio`,
`input-range`, `input-reset`, `input-search`, `input-submit`, `input-telephone`,
`input-text`, `input-time`, `input-url`, `input-week`, `output`, `reset-button`,
`select-list`, `select-list`, `select-multiple`, `select-one`, `submit-button`,
and `text-area`,
* `inputFieldType` string _Deprecated_ - If the context menu was invoked on an
input field, the type of that field. Possible values include `none`,
`plainText`, `password`, `other`.
* `spellcheckEnabled` boolean - If the context is editable, whether or not spellchecking is enabled. * `spellcheckEnabled` boolean - If the context is editable, whether or not spellchecking is enabled.
* `menuSourceType` string - Input source that invoked the context menu. * `menuSourceType` string - Input source that invoked the context menu.
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`. Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
@@ -842,7 +851,7 @@ Due to the nature of bluetooth, scanning for devices when
`select-bluetooth-device` to fire multiple times until `callback` is called `select-bluetooth-device` to fire multiple times until `callback` is called
with either a device id or an empty string to cancel the request. with either a device id or an empty string to cancel the request.
```javascript title='main.js' ```js title='main.js'
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let win = null let win = null
@@ -877,7 +886,7 @@ Returns:
Emitted when a new frame is generated. Only the dirty area is passed in the Emitted when a new frame is generated. Only the dirty area is passed in the
buffer. buffer.
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ webPreferences: { offscreen: true } }) const win = new BrowserWindow({ webPreferences: { offscreen: true } })
@@ -1009,7 +1018,7 @@ Loads the `url` in the window. The `url` must contain the protocol prefix,
e.g. the `http://` or `file://`. If the load should bypass http cache then e.g. the `http://` or `file://`. If the load should bypass http cache then
use the `pragma` header to achieve it. use the `pragma` header to achieve it.
```javascript ```js
const win = new BrowserWindow() const win = new BrowserWindow()
const options = { extraHeaders: 'pragma: no-cache\n' } const options = { extraHeaders: 'pragma: no-cache\n' }
win.webContents.loadURL('https://github.com', options) win.webContents.loadURL('https://github.com', options)
@@ -1059,7 +1068,7 @@ Initiates a download of the resource at `url` without navigating. The
Returns `string` - The URL of the current web page. Returns `string` - The URL of the current web page.
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 600 }) const win = new BrowserWindow({ width: 800, height: 600 })
win.loadURL('https://github.com').then(() => { win.loadURL('https://github.com').then(() => {
@@ -1211,7 +1220,7 @@ Returns `string` - The user agent for this web page.
* `css` string * `css` string
* `options` Object (optional) * `options` Object (optional)
* `cssOrigin` string (optional) - Can be either 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'. * `cssOrigin` string (optional) - Can be 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'.
Returns `Promise<string>` - A promise that resolves with a key for the inserted CSS that can later be used to remove the CSS via `contents.removeInsertedCSS(key)`. Returns `Promise<string>` - A promise that resolves with a key for the inserted CSS that can later be used to remove the CSS via `contents.removeInsertedCSS(key)`.
@@ -1508,7 +1517,7 @@ can be obtained by subscribing to [`found-in-page`](web-contents.md#event-found-
Stops any `findInPage` request for the `webContents` with the provided `action`. Stops any `findInPage` request for the `webContents` with the provided `action`.
```javascript ```js
const win = new BrowserWindow() const win = new BrowserWindow()
win.webContents.on('found-in-page', (event, result) => { win.webContents.on('found-in-page', (event, result) => {
if (result.finalUpdate) win.webContents.stopFindInPage('clearSelection') if (result.finalUpdate) win.webContents.stopFindInPage('clearSelection')
@@ -1628,7 +1637,7 @@ The `landscape` will be ignored if `@page` CSS at-rule is used in the web page.
An example of `webContents.printToPDF`: An example of `webContents.printToPDF`:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const fs = require('node:fs') const fs = require('node:fs')
const path = require('node:path') const path = require('node:path')
@@ -1660,7 +1669,7 @@ See [Page.printToPdf](https://chromedevtools.github.io/devtools-protocol/tot/Pag
Adds the specified path to DevTools workspace. Must be used after DevTools Adds the specified path to DevTools workspace. Must be used after DevTools
creation: creation:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
win.webContents.on('devtools-opened', () => { win.webContents.on('devtools-opened', () => {
@@ -1983,7 +1992,7 @@ the cursor when dragging.
Returns `Promise<void>` - resolves if the page is saved. Returns `Promise<void>` - resolves if the page is saved.
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()

View File

@@ -8,7 +8,7 @@ The `webFrameMain` module can be used to lookup frames across existing
[`WebContents`](web-contents.md) instances. Navigation events are the common [`WebContents`](web-contents.md) instances. Navigation events are the common
use case. use case.
```javascript ```js
const { BrowserWindow, webFrameMain } = require('electron') const { BrowserWindow, webFrameMain } = require('electron')
const win = new BrowserWindow({ width: 800, height: 1500 }) const win = new BrowserWindow({ width: 800, height: 1500 })
@@ -29,7 +29,7 @@ win.webContents.on(
You can also access frames of existing pages by using the `mainFrame` property You can also access frames of existing pages by using the `mainFrame` property
of [`WebContents`](web-contents.md). of [`WebContents`](web-contents.md).
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
async function main () { async function main () {

View File

@@ -10,7 +10,7 @@ certain properties and methods (e.g. `webFrame.firstChild`).
An example of zooming current page to 200%. An example of zooming current page to 200%.
```javascript ```js
const { webFrame } = require('electron') const { webFrame } = require('electron')
webFrame.setZoomFactor(2) webFrame.setZoomFactor(2)
@@ -96,7 +96,7 @@ with an array of misspelt words when complete.
An example of using [node-spellchecker][spellchecker] as provider: An example of using [node-spellchecker][spellchecker] as provider:
```javascript @ts-expect-error=[2,6] ```js @ts-expect-error=[2,6]
const { webFrame } = require('electron') const { webFrame } = require('electron')
const spellChecker = require('spellchecker') const spellChecker = require('spellchecker')
webFrame.setSpellCheckProvider('en-US', { webFrame.setSpellCheckProvider('en-US', {
@@ -113,7 +113,7 @@ webFrame.setSpellCheckProvider('en-US', {
* `css` string * `css` string
* `options` Object (optional) * `options` Object (optional)
* `cssOrigin` string (optional) - Can be either 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'. * `cssOrigin` string (optional) - Can be 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'.
Returns `string` - A key for the inserted CSS that can later be used to remove Returns `string` - A key for the inserted CSS that can later be used to remove
the CSS via `webFrame.removeInsertedCSS(key)`. the CSS via `webFrame.removeInsertedCSS(key)`.
@@ -205,14 +205,14 @@ Returns `Object`:
Returns an object describing usage information of Blink's internal memory Returns an object describing usage information of Blink's internal memory
caches. caches.
```javascript ```js
const { webFrame } = require('electron') const { webFrame } = require('electron')
console.log(webFrame.getResourceUsage()) console.log(webFrame.getResourceUsage())
``` ```
This will generate: This will generate:
```javascript ```js
{ {
images: { images: {
count: 22, count: 22,

View File

@@ -23,7 +23,7 @@ called with a `response` object when `listener` has done its work.
An example of adding `User-Agent` header for requests: An example of adding `User-Agent` header for requests:
```javascript ```js
const { session } = require('electron') const { session } = require('electron')
// Modify the user agent for all requests to the following urls. // Modify the user agent for all requests to the following urls.

View File

@@ -255,7 +255,7 @@ The `webview` tag has the following methods:
**Example** **Example**
```javascript @ts-expect-error=[3] ```js @ts-expect-error=[3]
const webview = document.querySelector('webview') const webview = document.querySelector('webview')
webview.addEventListener('dom-ready', () => { webview.addEventListener('dom-ready', () => {
webview.openDevTools() webview.openDevTools()
@@ -802,7 +802,7 @@ Fired when the guest window logs a console message.
The following example code forwards all log messages to the embedder's console The following example code forwards all log messages to the embedder's console
without regard for log level or other properties. without regard for log level or other properties.
```javascript @ts-expect-error=[3] ```js @ts-expect-error=[3]
const webview = document.querySelector('webview') const webview = document.querySelector('webview')
webview.addEventListener('console-message', (e) => { webview.addEventListener('console-message', (e) => {
console.log('Guest page logged a message:', e.message) console.log('Guest page logged a message:', e.message)
@@ -823,7 +823,7 @@ Returns:
Fired when a result is available for Fired when a result is available for
[`webview.findInPage`](#webviewfindinpagetext-options) request. [`webview.findInPage`](#webviewfindinpagetext-options) request.
```javascript @ts-expect-error=[3,6] ```js @ts-expect-error=[3,6]
const webview = document.querySelector('webview') const webview = document.querySelector('webview')
webview.addEventListener('found-in-page', (e) => { webview.addEventListener('found-in-page', (e) => {
webview.stopFindInPage('keepSelection') webview.stopFindInPage('keepSelection')
@@ -948,7 +948,7 @@ Fired when the guest page attempts to close itself.
The following example code navigates the `webview` to `about:blank` when the The following example code navigates the `webview` to `about:blank` when the
guest attempts to close itself. guest attempts to close itself.
```javascript @ts-expect-error=[3] ```js @ts-expect-error=[3]
const webview = document.querySelector('webview') const webview = document.querySelector('webview')
webview.addEventListener('close', () => { webview.addEventListener('close', () => {
webview.src = 'about:blank' webview.src = 'about:blank'
@@ -968,7 +968,7 @@ Fired when the guest page has sent an asynchronous message to embedder page.
With `sendToHost` method and `ipc-message` event you can communicate With `sendToHost` method and `ipc-message` event you can communicate
between guest page and embedder page: between guest page and embedder page:
```javascript @ts-expect-error=[4,7] ```js @ts-expect-error=[4,7]
// In embedder page. // In embedder page.
const webview = document.querySelector('webview') const webview = document.querySelector('webview')
webview.addEventListener('ipc-message', (event) => { webview.addEventListener('ipc-message', (event) => {
@@ -978,7 +978,7 @@ webview.addEventListener('ipc-message', (event) => {
webview.send('ping') webview.send('ping')
``` ```
```javascript ```js
// In guest page. // In guest page.
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
ipcRenderer.on('ping', () => { ipcRenderer.on('ping', () => {
@@ -1106,9 +1106,18 @@ Returns:
word and spellchecker is enabled. word and spellchecker is enabled.
* `frameCharset` string - The character encoding of the frame on which the * `frameCharset` string - The character encoding of the frame on which the
menu was invoked. menu was invoked.
* `inputFieldType` string - If the context menu was invoked on an input * `formControlType` string - The source that the context menu was invoked on.
field, the type of that field. Possible values include `none`, `plainText`, Possible values include `none`, `button-button`, `field-set`,
`password`, `other`. `input-button`, `input-checkbox`, `input-color`, `input-date`,
`input-datetime-local`, `input-email`, `input-file`, `input-hidden`,
`input-image`, `input-month`, `input-number`, `input-password`, `input-radio`,
`input-range`, `input-reset`, `input-search`, `input-submit`, `input-telephone`,
`input-text`, `input-time`, `input-url`, `input-week`, `output`, `reset-button`,
`select-list`, `select-list`, `select-multiple`, `select-one`, `submit-button`,
and `text-area`,
* `inputFieldType` string _Deprecated_ - If the context menu was invoked on an
input field, the type of that field. Possible values include `none`,
`plainText`, `password`, `other`.
* `spellcheckEnabled` boolean - If the context is editable, whether or not spellchecking is enabled. * `spellcheckEnabled` boolean - If the context is editable, whether or not spellchecking is enabled.
* `menuSourceType` string - Input source that invoked the context menu. * `menuSourceType` string - Input source that invoked the context menu.
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`. Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.

View File

@@ -80,7 +80,7 @@ window will not close when the opener window closes. The default value is `false
### Native `Window` example ### Native `Window` example
```javascript ```js
// main.js // main.js
const mainWindow = new BrowserWindow() const mainWindow = new BrowserWindow()
@@ -104,7 +104,7 @@ mainWindow.webContents.setWindowOpenHandler(({ url }) => {
}) })
``` ```
```javascript ```js
// renderer process (mainWindow) // renderer process (mainWindow)
const childWindow = window.open('', 'modal') const childWindow = window.open('', 'modal')
childWindow.document.write('<h1>Hello</h1>') childWindow.document.write('<h1>Hello</h1>')

View File

@@ -88,6 +88,12 @@ app.on('renderer-process-crashed', (event, webContents, killed) => { /* ... */ }
app.on('render-process-gone', (event, webContents, details) => { /* ... */ }) app.on('render-process-gone', (event, webContents, details) => { /* ... */ })
``` ```
### Deprecated: `params.inputFormType` property on `context-menu` on `WebContents`
The `inputFormType` property of the params object in the `context-menu`
event from `WebContents` has been deprecated. Use the new `formControlType`
property instead.
### Deprecated: `crashed` event on `WebContents` and `<webview>` ### Deprecated: `crashed` event on `WebContents` and `<webview>`
The `crashed` events on `WebContents` and `<webview>` have been deprecated. The `crashed` events on `WebContents` and `<webview>` have been deprecated.
@@ -103,6 +109,19 @@ win.webContents.on('render-process-gone', (event, details) => { /* ... */ })
webview.addEventListener('render-process-gone', (event) => { /* ... */ }) webview.addEventListener('render-process-gone', (event) => { /* ... */ })
``` ```
### Deprecated: `gpu-process-crashed` event on `app`
The `gpu-process-crashed` event on `app` has been deprecated.
Use the new `child-process-gone` event instead.
```js
// Deprecated
app.on('gpu-process-crashed', (event, killed) => { /* ... */ })
// Replace with
app.on('child-process-gone', (event, details) => { /* ... */ })
```
## Planned Breaking API Changes (27.0) ## Planned Breaking API Changes (27.0)
### Removed: macOS 10.13 / 10.14 support ### Removed: macOS 10.13 / 10.14 support
@@ -136,6 +155,18 @@ systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
nativeTheme.on('updated', () => { /* ... */ }) nativeTheme.on('updated', () => { /* ... */ })
``` ```
### Removed: Some `window.setVibrancy` options on macOS
The following vibrancy options have been removed:
* 'light'
* 'medium-light'
* 'dark'
* 'ultra-dark'
* 'appearance-based'
These were previously deprecated and have been removed by Apple in 10.15.
### Removed: `webContents.getPrinters` ### Removed: `webContents.getPrinters`
The `webContents.getPrinters` method has been removed. Use The `webContents.getPrinters` method has been removed. Use
@@ -515,7 +546,7 @@ The `new-window` event of `<webview>` has been removed. There is no direct repla
webview.addEventListener('new-window', (event) => {}) webview.addEventListener('new-window', (event) => {})
``` ```
```javascript fiddle='docs/fiddles/ipc/webview-new-window' ```js
// Replace with // Replace with
// main.js // main.js
@@ -1180,7 +1211,7 @@ module](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-
The APIs are now synchronous and the optional callback is no longer needed. The APIs are now synchronous and the optional callback is no longer needed.
```javascript ```js
// Deprecated // Deprecated
protocol.unregisterProtocol(scheme, () => { /* ... */ }) protocol.unregisterProtocol(scheme, () => { /* ... */ })
// Replace with // Replace with
@@ -1209,7 +1240,7 @@ protocol.unregisterProtocol(scheme)
The APIs are now synchronous and the optional callback is no longer needed. The APIs are now synchronous and the optional callback is no longer needed.
```javascript ```js
// Deprecated // Deprecated
protocol.registerFileProtocol(scheme, handler, () => { /* ... */ }) protocol.registerFileProtocol(scheme, handler, () => { /* ... */ })
// Replace with // Replace with
@@ -1224,7 +1255,7 @@ until navigation happens.
This API is deprecated and users should use `protocol.isProtocolRegistered` This API is deprecated and users should use `protocol.isProtocolRegistered`
and `protocol.isProtocolIntercepted` instead. and `protocol.isProtocolIntercepted` instead.
```javascript ```js
// Deprecated // Deprecated
protocol.isProtocolHandled(scheme).then(() => { /* ... */ }) protocol.isProtocolHandled(scheme).then(() => { /* ... */ })
// Replace with // Replace with

View File

@@ -164,7 +164,7 @@ An example of the contents of this file can be found [here](https://github.com/e
Add your module to the module list found at `"lib/browser/api/module-list.ts"` like so: Add your module to the module list found at `"lib/browser/api/module-list.ts"` like so:
```typescript title='lib/browser/api/module-list.ts' @ts-nocheck ```ts title='lib/browser/api/module-list.ts' @ts-nocheck
export const browserModuleList: ElectronInternal.ModuleEntry[] = [ export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'apiName', loader: () => require('./api-name') }, { name: 'apiName', loader: () => require('./api-name') },
]; ];

View File

@@ -65,7 +65,7 @@ If you encounter this problem, the following articles may prove helpful:
If you want a quick fix, you can make the variables global by changing your If you want a quick fix, you can make the variables global by changing your
code from this: code from this:
```javascript ```js
const { app, Tray } = require('electron') const { app, Tray } = require('electron')
app.whenReady().then(() => { app.whenReady().then(() => {
const tray = new Tray('/path/to/icon.png') const tray = new Tray('/path/to/icon.png')
@@ -75,7 +75,7 @@ app.whenReady().then(() => {
to this: to this:
```javascript ```js
const { app, Tray } = require('electron') const { app, Tray } = require('electron')
let tray = null let tray = null
app.whenReady().then(() => { app.whenReady().then(() => {
@@ -92,7 +92,7 @@ for some libraries since they want to insert the symbols with the same names.
To solve this, you can turn off node integration in Electron: To solve this, you can turn off node integration in Electron:
```javascript ```js
// In the main process. // In the main process.
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ const win = new BrowserWindow({
@@ -141,7 +141,7 @@ Sub-pixel anti-aliasing needs a non-transparent background of the layer containi
To achieve this goal, set the background in the constructor for [BrowserWindow][browser-window]: To achieve this goal, set the background in the constructor for [BrowserWindow][browser-window]:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ const win = new BrowserWindow({
backgroundColor: '#fff' backgroundColor: '#fff'

View File

@@ -7,14 +7,20 @@ function createWindow () {
height: 600 height: 600
}) })
win.setRepresentedFilename(os.homedir())
win.setDocumentEdited(true)
win.loadFile('index.html') win.loadFile('index.html')
} }
app.whenReady().then(() => { app.whenReady().then(() => {
const win = new BrowserWindow() createWindow()
win.setRepresentedFilename(os.homedir()) app.on('activate', () => {
win.setDocumentEdited(true) if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
}) })
app.on('window-all-closed', () => { app.on('window-all-closed', () => {
@@ -22,9 +28,3 @@ app.on('window-all-closed', () => {
app.quit() app.quit()
} }
}) })
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -1,5 +1,6 @@
const { contextBridge, ipcRenderer } = require('electron/renderer') const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electronAPI', { contextBridge.exposeInMainWorld('electronAPI', {
handleCounter: (callback) => ipcRenderer.on('update-counter', () => callback()) onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value)),
counterValue: (value) => ipcRenderer.send('counter-value', value)
}) })

View File

@@ -1,8 +1,8 @@
const counter = document.getElementById('counter') const counter = document.getElementById('counter')
window.electronAPI.handleCounter((event, value) => { window.electronAPI.onUpdateCounter((value) => {
const oldValue = Number(counter.innerText) const oldValue = Number(counter.innerText)
const newValue = oldValue + value const newValue = oldValue + value
counter.innerText = newValue counter.innerText = newValue.toString()
event.sender.send('counter-value', newValue) window.electronAPI.counterValue(newValue)
}) })

View File

@@ -44,7 +44,7 @@
<h3>Packaging</h3> <h3>Packaging</h3>
<p>This feature will only work on macOS when your app is packaged. It will not work when you're launching it in <p>This feature will only work on macOS when your app is packaged. It will not work when you're launching it in
development from the command-line. When you package your app you'll need to make sure the macOS <code>plist</code> development from the command-line. When you package your app you'll need to make sure the macOS <code>plist</code>
for the app is updated to include the new protocol handler. If you're using <code>electron-packager</code> then you for the app is updated to include the new protocol handler. If you're using <code>@electron/packager</code> then you
can add the flag <code>--extend-info</code> with a path to the <code>plist</code> you've created. The one for this can add the flag <code>--extend-info</code> with a path to the <code>plist</code> you've created. The one for this
app is below:</p> app is below:</p>

View File

@@ -12,7 +12,7 @@ including instances of `BrowserWindow`, `BrowserView`, and `WebView`. You
can open them programmatically by calling the `openDevTools()` API on the can open them programmatically by calling the `openDevTools()` API on the
`webContents` of the instance: `webContents` of the instance:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()

View File

@@ -41,27 +41,27 @@ $ asar list /path/to/example.asar
Read a file in the ASAR archive: Read a file in the ASAR archive:
```javascript ```js
const fs = require('node:fs') const fs = require('node:fs')
fs.readFileSync('/path/to/example.asar/file.txt') fs.readFileSync('/path/to/example.asar/file.txt')
``` ```
List all files under the root of the archive: List all files under the root of the archive:
```javascript ```js
const fs = require('node:fs') const fs = require('node:fs')
fs.readdirSync('/path/to/example.asar') fs.readdirSync('/path/to/example.asar')
``` ```
Use a module from the archive: Use a module from the archive:
```javascript @ts-nocheck ```js @ts-nocheck
require('./path/to/example.asar/dir/module.js') require('./path/to/example.asar/dir/module.js')
``` ```
You can also display a web page in an ASAR archive with `BrowserWindow`: You can also display a web page in an ASAR archive with `BrowserWindow`:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
@@ -90,7 +90,7 @@ 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 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: `original-fs` module which provides original `fs` APIs without `asar` support:
```javascript ```js
const originalFs = require('original-fs') const originalFs = require('original-fs')
originalFs.readFileSync('/path/to/example.asar') originalFs.readFileSync('/path/to/example.asar')
``` ```
@@ -98,7 +98,7 @@ originalFs.readFileSync('/path/to/example.asar')
You can also set `process.noAsar` to `true` to disable the support for `asar` in You can also set `process.noAsar` to `true` to disable the support for `asar` in
the `fs` module: the `fs` module:
```javascript ```js
const fs = require('node:fs') const fs = require('node:fs')
process.noAsar = true process.noAsar = true
fs.readFileSync('/path/to/example.asar') fs.readFileSync('/path/to/example.asar')

View File

@@ -13,7 +13,7 @@ Currently ASAR integrity checking is only supported on macOS.
### Electron Forge / Electron Packager ### 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). If you are using `>= @electron/packager`, `>= 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 ### Other build systems

View File

@@ -22,34 +22,101 @@ 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 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. (e.g. reporter and services) that can help you put together your test setup.
If you already have an existing WebdriverIO setup, it is recommended to update your dependencies and validate your existing configuration with how it is [outlined in the docs](https://webdriver.io/docs/desktop-testing/electron#configuration).
#### Install the test runner #### Install the test runner
First you need to run the WebdriverIO starter toolkit in your project root directory: If you don't use WebdriverIO in your project yet, you can add it by running the starter toolkit in your project root directory:
```sh npm2yarn ```sh npm2yarn
npx wdio . --yes npm init wdio@latest ./
``` ```
This installs all necessary packages for you and generates a `wdio.conf.js` configuration file. This starts a configuration wizard that helps you put together the right setup, installs all necessary packages, and generates a `wdio.conf.js` configuration file. Make sure to select _"Desktop Testing - of Electron Applications"_ on one of the first questions asking _"What type of testing would you like to do?"_.
#### Connect WDIO to your Electron app #### Connect WDIO to your Electron app
Update the capabilities in your configuration file to point to your Electron app binary: After running the configuration wizard, your `wdio.conf.js` should include roughly the following content:
```javascript title='wdio.conf.js' ```js title='wdio.conf.js' @ts-nocheck
exports.config = { export const config = {
// ... // ...
services: ['electron'],
capabilities: [{ capabilities: [{
browserName: 'chrome', browserName: 'electron',
'goog:chromeOptions': { 'wdio:electronServiceOptions': {
binary: '/path/to/your/electron/binary', // Path to your Electron binary. // WebdriverIO can automatically find your bundled application
args: [/* cli arguments */] // Optional, perhaps 'app=' + /path/to/your/app/ // if you use Electron Forge or electron-builder, otherwise you
// can define it here, e.g.:
// appBinaryPath: './path/to/bundled/application.exe',
appArgs: ['foo', 'bar=baz']
} }
}] }]
// ... // ...
} }
``` ```
#### Write your tests
Use the [WebdriverIO API](https://webdriver.io/docs/api) to interact with elements on the screen. The framework provides custom "matchers" that make asserting the state of your application easy, e.g.:
```js @ts-nocheck
import { browser, $, expect } from '@wdio/globals'
describe('keyboard input', () => {
it('should detect keyboard input', async () => {
await browser.keys(['y', 'o'])
await expect($('keypress-count')).toHaveText('YO')
})
})
```
Furthermore, WebdriverIO allows you to access Electron APIs to get static information about your application:
```js @ts-nocheck
import { browser, $, expect } from '@wdio/globals'
describe('when the make smaller button is clicked', () => {
it('should decrease the window height and width by 10 pixels', async () => {
const boundsBefore = await browser.electron.browserWindow('getBounds')
expect(boundsBefore.width).toEqual(210)
expect(boundsBefore.height).toEqual(310)
await $('.make-smaller').click()
const boundsAfter = await browser.electron.browserWindow('getBounds')
expect(boundsAfter.width).toEqual(200)
expect(boundsAfter.height).toEqual(300)
})
})
```
or to retrieve other Electron process information:
```js @ts-nocheck
import fs from 'node:fs'
import path from 'node:path'
import { browser, expect } from '@wdio/globals'
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), { encoding: 'utf-8' }))
const { name, version } = packageJson
describe('electron APIs', () => {
it('should retrieve app metadata through the electron API', async () => {
const appName = await browser.electron.app('getName')
expect(appName).toEqual(name)
const appVersion = await browser.electron.app('getVersion')
expect(appVersion).toEqual(version)
})
it('should pass args through to the launched application', async () => {
// custom args are set in the wdio.conf.js file as they need to be set before WDIO starts
const argv = await browser.electron.mainProcess('argv')
expect(argv).toContain('--foo')
expect(argv).toContain('--bar=baz')
})
})
```
#### Run your tests #### Run your tests
To run your tests: To run your tests:
@@ -58,6 +125,12 @@ To run your tests:
$ npx wdio run wdio.conf.js $ npx wdio run wdio.conf.js
``` ```
WebdriverIO helps launch and shut down the application for you.
#### More documentation
Find more documentation on Mocking Electron APIs and other useful resources in the [official WebdriverIO documentation](https://webdriver.io/docs/desktop-testing/electron).
### With Selenium ### With Selenium
[Selenium](https://www.selenium.dev/) is a web automation framework that [Selenium](https://www.selenium.dev/) is a web automation framework that

View File

@@ -30,7 +30,7 @@ Electron Forge is a tool for packaging and publishing Electron applications. It
into a single extensible interface so that anyone can jump right into making Electron apps. into a single extensible interface so that anyone can jump right into making Electron apps.
Forge comes with [a ready-to-use template](https://electronforge.io/templates) using Webpack as a bundler. It includes an example typescript configuration and provides two configuration files to enable easy customization. It uses the same core modules used by the Forge comes with [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)) greater Electron community (like [`@electron/packager`](https://github.com/electron/packager))
changes made by Electron maintainers (like Slack) benefit Forge's users, too. changes made by Electron maintainers (like Slack) benefit Forge's users, too.
You can find more information and documentation on [electronforge.io](https://electronforge.io/). You can find more information and documentation on [electronforge.io](https://electronforge.io/).

View File

@@ -51,7 +51,7 @@ ways to get your application signed and notarized.
If you're using Electron's favorite build tool, getting your application signed If you're using Electron's favorite build tool, getting your application signed
and notarized requires a few additions to your configuration. [Forge](https://electronforge.io) is a and notarized requires a few additions to your configuration. [Forge](https://electronforge.io) is a
collection of the official Electron tools, using [`electron-packager`][], collection of the official Electron tools, using [`@electron/packager`][],
[`@electron/osx-sign`][], and [`@electron/notarize`][] under the hood. [`@electron/osx-sign`][], and [`@electron/notarize`][] under the hood.
Detailed instructions on how to configure your application can be found in the Detailed instructions on how to configure your application can be found in the
@@ -61,14 +61,14 @@ the Electron Forge docs.
### Using Electron Packager ### 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, you
are likely using [`electron-packager`][], which includes [`@electron/osx-sign`][] and are likely using [`@electron/packager`][], which includes [`@electron/osx-sign`][] and
[`@electron/notarize`][]. [`@electron/notarize`][].
If you're using Packager's API, you can pass [in configuration that both signs If you're using Packager's API, you can pass [in configuration that both signs
and notarizes your application](https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html). and notarizes your application](https://electron.github.io/packager/main/interfaces/electronpackager.options.html).
```js @ts-nocheck ```js @ts-nocheck
const packager = require('electron-packager') const packager = require('@electron/packager')
packager({ packager({
dir: '/path/to/my/app', dir: '/path/to/my/app',
@@ -190,7 +190,7 @@ See the [Windows Store Guide][].
[apple developer program]: https://developer.apple.com/programs/ [apple developer program]: https://developer.apple.com/programs/
[`@electron/osx-sign`]: https://github.com/electron/osx-sign [`@electron/osx-sign`]: https://github.com/electron/osx-sign
[`electron-packager`]: https://github.com/electron/electron-packager [`@electron/packager`]: https://github.com/electron/packager
[`@electron/notarize`]: https://github.com/electron/notarize [`@electron/notarize`]: https://github.com/electron/notarize
[`electron-winstaller`]: https://github.com/electron/windows-installer [`electron-winstaller`]: https://github.com/electron/windows-installer
[`electron-wix-msi`]: https://github.com/electron-userland/electron-wix-msi [`electron-wix-msi`]: https://github.com/electron-userland/electron-wix-msi

View File

@@ -16,7 +16,7 @@ Context isolation has been enabled by default since Electron 12, and it is a rec
Exposing APIs from your preload script to a loaded website in the renderer process is a common use-case. With context isolation disabled, your preload script would share a common global `window` object with the renderer. You could then attach arbitrary properties to a preload script: Exposing APIs from your preload script to a loaded website in the renderer process is a common use-case. With context isolation disabled, your preload script would share a common global `window` object with the renderer. You could then attach arbitrary properties to a preload script:
```javascript title='preload.js' @ts-nocheck ```js title='preload.js' @ts-nocheck
// preload with contextIsolation disabled // preload with contextIsolation disabled
window.myAPI = { window.myAPI = {
doAThing: () => {} doAThing: () => {}
@@ -25,7 +25,7 @@ window.myAPI = {
The `doAThing()` function could then be used directly in the renderer process: The `doAThing()` function could then be used directly in the renderer process:
```javascript title='renderer.js' @ts-nocheck ```js title='renderer.js' @ts-nocheck
// use the exposed API in the renderer // use the exposed API in the renderer
window.myAPI.doAThing() window.myAPI.doAThing()
``` ```
@@ -34,7 +34,7 @@ window.myAPI.doAThing()
There is a dedicated module in Electron to help you do this in a painless way. The [`contextBridge`](../api/context-bridge.md) module can be used to **safely** expose APIs from your preload script's isolated context to the context the website is running in. The API will also be accessible from the website on `window.myAPI` just like it was before. There is a dedicated module in Electron to help you do this in a painless way. The [`contextBridge`](../api/context-bridge.md) module can be used to **safely** expose APIs from your preload script's isolated context to the context the website is running in. The API will also be accessible from the website on `window.myAPI` just like it was before.
```javascript title='preload.js' ```js title='preload.js'
// preload with contextIsolation enabled // preload with contextIsolation enabled
const { contextBridge } = require('electron') const { contextBridge } = require('electron')
@@ -43,7 +43,7 @@ contextBridge.exposeInMainWorld('myAPI', {
}) })
``` ```
```javascript title='renderer.js' @ts-nocheck ```js title='renderer.js' @ts-nocheck
// use the exposed API in the renderer // use the exposed API in the renderer
window.myAPI.doAThing() window.myAPI.doAThing()
``` ```
@@ -54,7 +54,7 @@ Please read the `contextBridge` documentation linked above to fully understand i
Just enabling `contextIsolation` and using `contextBridge` does not automatically mean that everything you do is safe. For instance, this code is **unsafe**. Just enabling `contextIsolation` and using `contextBridge` does not automatically mean that everything you do is safe. For instance, this code is **unsafe**.
```javascript title='preload.js' ```js title='preload.js'
// ❌ Bad code // ❌ Bad code
contextBridge.exposeInMainWorld('myAPI', { contextBridge.exposeInMainWorld('myAPI', {
send: ipcRenderer.send send: ipcRenderer.send
@@ -63,7 +63,7 @@ contextBridge.exposeInMainWorld('myAPI', {
It directly exposes a powerful API without any kind of argument filtering. This would allow any website to send arbitrary IPC messages, which you do not want to be possible. The correct way to expose IPC-based APIs would instead be to provide one method per IPC message. It directly exposes a powerful API without any kind of argument filtering. This would allow any website to send arbitrary IPC messages, which you do not want to be possible. The correct way to expose IPC-based APIs would instead be to provide one method per IPC message.
```javascript title='preload.js' ```js title='preload.js'
// ✅ Good code // ✅ Good code
contextBridge.exposeInMainWorld('myAPI', { contextBridge.exposeInMainWorld('myAPI', {
loadPreferences: () => ipcRenderer.invoke('load-prefs') loadPreferences: () => ipcRenderer.invoke('load-prefs')
@@ -76,7 +76,7 @@ If you're building your Electron app with TypeScript, you'll want to add types t
For example, given this `preload.ts` script: For example, given this `preload.ts` script:
```typescript title='preload.ts' ```ts title='preload.ts'
contextBridge.exposeInMainWorld('electronAPI', { contextBridge.exposeInMainWorld('electronAPI', {
loadPreferences: () => ipcRenderer.invoke('load-prefs') loadPreferences: () => ipcRenderer.invoke('load-prefs')
}) })
@@ -84,7 +84,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
You can create a `renderer.d.ts` declaration file and globally augment the `Window` interface: You can create a `renderer.d.ts` declaration file and globally augment the `Window` interface:
```typescript title='renderer.d.ts' @ts-noisolate ```ts title='renderer.d.ts' @ts-noisolate
export interface IElectronAPI { export interface IElectronAPI {
loadPreferences: () => Promise<void>, loadPreferences: () => Promise<void>,
} }
@@ -98,7 +98,7 @@ declare global {
Doing so will ensure that the TypeScript compiler will know about the `electronAPI` property on your global `window` object when writing scripts in your renderer process: Doing so will ensure that the TypeScript compiler will know about the `electronAPI` property on your global `window` object when writing scripts in your renderer process:
```typescript title='renderer.ts' ```ts title='renderer.ts'
window.electronAPI.loadPreferences() window.electronAPI.loadPreferences()
``` ```

View File

@@ -50,7 +50,7 @@ of this theming, due to the use of the macOS 10.14 SDK.
This example demonstrates an Electron application that derives its theme colors from the This example demonstrates an Electron application that derives its theme colors from the
`nativeTheme`. Additionally, it provides theme toggle and reset controls using IPC channels. `nativeTheme`. Additionally, it provides theme toggle and reset controls using IPC channels.
```javascript fiddle='docs/fiddles/features/dark-mode' ```fiddle docs/fiddles/features/dark-mode
``` ```
@@ -199,7 +199,7 @@ Run the example using Electron Fiddle and then click the "Toggle Dark Mode" butt
[system-wide-dark-mode]: https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/dark-mode/ [system-wide-dark-mode]: https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/dark-mode/
[electron-forge]: https://www.electronforge.io/ [electron-forge]: https://www.electronforge.io/
[electron-packager]: https://github.com/electron/electron-packager [electron-packager]: https://github.com/electron/packager
[packager-darwindarkmode-api]: https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html#darwindarkmodesupport [packager-darwindarkmode-api]: https://electron.github.io/packager/main/interfaces/electronpackager.options.html#darwindarkmodesupport
[prefers-color-scheme]: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme [prefers-color-scheme]: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme
[event-listeners]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener [event-listeners]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

View File

@@ -14,10 +14,10 @@ process:
Electron will listen for V8 inspector protocol messages on the specified `port`, Electron will listen for V8 inspector protocol messages on the specified `port`,
an external debugger will need to connect on this port. The default `port` is an external debugger will need to connect on this port. The default `port` is
`5858`. `9229`.
```shell ```shell
electron --inspect=5858 your/app electron --inspect=9229 your/app
``` ```
### `--inspect-brk=[port]` ### `--inspect-brk=[port]`

View File

@@ -26,7 +26,7 @@ This example demonstrates an Electron application that automatically selects
the first available bluetooth device when the `Test Bluetooth` button is the first available bluetooth device when the `Test Bluetooth` button is
clicked. clicked.
```javascript fiddle='docs/fiddles/features/web-bluetooth' ```fiddle docs/fiddles/features/web-bluetooth
``` ```
@@ -61,7 +61,7 @@ By default Electron employs the same [blocklist](https://github.com/WICG/webhid/
used by Chromium. If you wish to override this behavior, you can do so by used by Chromium. If you wish to override this behavior, you can do so by
setting the `disable-hid-blocklist` flag: setting the `disable-hid-blocklist` flag:
```javascript ```js
app.commandLine.appendSwitch('disable-hid-blocklist') app.commandLine.appendSwitch('disable-hid-blocklist')
``` ```
@@ -72,7 +72,7 @@ HID devices through [`ses.setDevicePermissionHandler(handler)`](../api/session.m
and through [`select-hid-device` event on the Session](../api/session.md#event-select-hid-device) and through [`select-hid-device` event on the Session](../api/session.md#event-select-hid-device)
when the `Test WebHID` button is clicked. when the `Test WebHID` button is clicked.
```javascript fiddle='docs/fiddles/features/web-hid' ```fiddle docs/fiddles/features/web-hid
``` ```
@@ -112,7 +112,7 @@ as well as demonstrating selecting the first available Arduino Uno serial device
[`select-serial-port` event on the Session](../api/session.md#event-select-serial-port) [`select-serial-port` event on the Session](../api/session.md#event-select-serial-port)
when the `Test Web Serial` button is clicked. when the `Test Web Serial` button is clicked.
```javascript fiddle='docs/fiddles/features/web-serial' ```fiddle docs/fiddles/features/web-serial
``` ```
@@ -152,6 +152,6 @@ USB devices (if they are attached) through [`ses.setDevicePermissionHandler(hand
and through [`select-usb-device` event on the Session](../api/session.md#event-select-usb-device) and through [`select-usb-device` event on the Session](../api/session.md#event-select-usb-device)
when the `Test WebUSB` button is clicked. when the `Test WebUSB` button is clicked.
```javascript fiddle='docs/fiddles/features/web-usb' ```fiddle docs/fiddles/features/web-usb
``` ```

View File

@@ -33,7 +33,7 @@ Using the [React Developer Tools][react-devtools] as an example:
1. Pass the location of the extension to the [`ses.loadExtension`][load-extension] 1. Pass the location of the extension to the [`ses.loadExtension`][load-extension]
API. For React Developer Tools `v4.9.0`, it looks something like: API. For React Developer Tools `v4.9.0`, it looks something like:
```javascript ```js
const { app, session } = require('electron') const { app, session } = require('electron')
const path = require('node:path') const path = require('node:path')
const os = require('node:os') const os = require('node:os')

View File

@@ -9,10 +9,11 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported | | Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- | | ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
| 28.0.0 | 2023-Oct-11 | 2023-Nov-6 | 2023-Dec-5 | TBD | M120 | TBD | ✅ | | 29.0.0 | 2023-Dec-07 | 2024-Jan-24 | 2024-Feb-20 | 2024-Aug-20 | M122 | v18.19 | ✅ |
| 28.0.0 | 2023-Oct-11 | 2023-Nov-06 | 2023-Dec-05 | 2024-Jun-11 | M120 | v18.18 | ✅ |
| 27.0.0 | 2023-Aug-17 | 2023-Sep-13 | 2023-Oct-10 | 2024-Apr-16 | M118 | v18.17 | ✅ | | 27.0.0 | 2023-Aug-17 | 2023-Sep-13 | 2023-Oct-10 | 2024-Apr-16 | M118 | v18.17 | ✅ |
| 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-15 | 2024-Feb-27 | M116 | v18.16 | ✅ | | 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-15 | 2024-Feb-20 | M116 | v18.16 | ✅ |
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2024-Jan-02 | M114 | v18.15 | | | 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2023-Dec-05 | M114 | v18.15 | 🚫 |
| 24.0.0 | 2023-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-10 | M112 | v18.14 | 🚫 | | 24.0.0 | 2023-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-10 | M112 | v18.14 | 🚫 |
| 23.0.0 | 2022-Dec-01 | 2023-Jan-10 | 2023-Feb-07 | 2023-Aug-15 | M110 | v18.12 | 🚫 | | 23.0.0 | 2022-Dec-01 | 2023-Jan-10 | 2023-Feb-07 | 2023-Aug-15 | M110 | v18.12 | 🚫 |
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | 2023-Oct-10 | M108 | v16.17 | 🚫 | | 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | 2023-Oct-10 | M108 | v16.17 | 🚫 |
@@ -37,6 +38,19 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | 2019-Jul-30 | M66 | v10.2 | 🚫 | | 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | 2019-Jul-30 | M66 | v10.2 | 🚫 |
| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | 2019-Apr-23 | M61 | v8.9 | 🚫 | | 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | 2019-Apr-23 | M61 | v8.9 | 🚫 |
:::info Official support dates may change
Electron's official support policy is the latest 3 stable releases. Our stable
release and end-of-life dates are determined by Chromium, and may be subject to
change. While we try to keep our planned release and end-of-life dates frequently
updated here, future dates may change if affected by upstream scheduling changes,
and may not always be accurately reflected.
See [Chromium's public release schedule](https://chromiumdash.appspot.com/schedule) for
definitive information about Chromium's scheduled release dates.
:::
**Notes:** **Notes:**
* The `-alpha.1`, `-beta.1`, and `stable` dates are our solid release dates. * The `-alpha.1`, `-beta.1`, and `stable` dates are our solid release dates.
@@ -48,26 +62,10 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
* Since Electron 5, Electron has been publicizing its release dates ([see blog post](https://www.electronjs.org/blog/electron-5-0-timeline)). * Since Electron 5, Electron has been publicizing its release dates ([see blog post](https://www.electronjs.org/blog/electron-5-0-timeline)).
* Since Electron 6, Electron major versions have been targeting every other Chromium major version. Each Electron stable should happen on the same day as Chrome stable ([see blog post](https://www.electronjs.org/blog/12-week-cadence)). * Since Electron 6, Electron major versions have been targeting every other Chromium major version. Each Electron stable should happen on the same day as Chrome stable ([see blog post](https://www.electronjs.org/blog/12-week-cadence)).
* Since Electron 16, Electron has been releasing major versions on an 8-week cadence in accordance to Chrome's change to a 4-week release cadence ([see blog post](https://www.electronjs.org/blog/8-week-cadence)). * Since Electron 16, Electron has been releasing major versions on an 8-week cadence in accordance to Chrome's change to a 4-week release cadence ([see blog post](https://www.electronjs.org/blog/8-week-cadence)).
* Electron temporarily extended support for Electron 22 until October 10, 2023, to support an extended end-of-life for Windows 7/8/8.1
:::info Chrome release dates
Chromium has the own public release schedule [here](https://chromiumdash.appspot.com/schedule).
:::
## Version support policy ## Version support policy
:::info
The Electron team will temporarily support Electron 22 until October 10, 2023.
This extended support is intended to help Electron developers who still need
support for Windows 7/8/8.1, which ended support in Electron 23. The October
support date follows the extended support dates from both Chromium and Microsoft.
On October 11, the Electron team will drop support back to the latest three
stable major versions.
:::
The latest three _stable_ major versions are supported by the Electron team. The latest three _stable_ major versions are supported by the Electron team.
For example, if the latest release is 6.1.x, then the 5.0.x as well For example, if the latest release is 6.1.x, then the 5.0.x as well
as the 4.2.x series are supported. We only support the latest minor release as the 4.2.x series are supported. We only support the latest minor release
@@ -79,6 +77,38 @@ and the version prior to that receives the vast majority of those fixes
as time and bandwidth warrants. The oldest supported release line will receive as time and bandwidth warrants. The oldest supported release line will receive
only security fixes directly. only security fixes directly.
### Chromium version support
:::info Chromium release schedule
Chromium's public release schedule is [here](https://chromiumdash.appspot.com/schedule).
:::
Electron targets Chromium even-number versions, releasing every 8 weeks in concert
with Chromium's 4-week release schedule. For example, Electron 26 uses Chromium 116, while Electron 27 uses Chromium 118.
### Node.js version support
Electron upgrades its `main` branch to even-number versions of Node.js when they enter Active LTS. The schedule
is as follows:
<img src="https://raw.githubusercontent.com/nodejs/Release/main/schedule.svg?sanitize=true" alt="Releases">
As a rule, stable branches of Electron do not receive Node.js upgrades after they have been cut.
If Electron has recently updated its `main` branch to a new major version of Node.js, the next stable
branch to be cut will be released with the new version.
Patch upgrades of Node that contain significant security or bug fixes, and are submitted
more than 2 weeks prior to a stable release date, will be accepted into an Electron alpha
or beta release branch.
Minor upgrades of Node that contain significant security or bug fixes, and are submitted
more than 2 weeks prior to a stable release date may be accepted into an Electron alpha or
beta release branch on a case-by-case basis. These requests will be reviewed and voted on
by the [Releases Working Group](https://github.com/electron/governance/tree/main/wg-releases),
to ensure minimal disruption for developers who may be consuming alpha or beta releases.
### Breaking API changes ### Breaking API changes
When an API is changed or removed in a way that breaks existing functionality, the When an API is changed or removed in a way that breaks existing functionality, the

View File

@@ -16,16 +16,7 @@ Once Fiddle is installed, you can press on the "Open in Fiddle" button that you
will find below code samples like the following one: will find below code samples like the following one:
```fiddle docs/fiddles/quick-start ```fiddle docs/fiddles/quick-start
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const type of ['chrome', 'node', 'electron']) {
replaceText(`${type}-version`, process.versions[type])
}
})
``` ```
If there is still something that you do not know how to do, please take a look at the [API][app] If there is still something that you do not know how to do, please take a look at the [API][app]

View File

@@ -34,7 +34,7 @@ To test In-App Purchase in development with Electron you'll have to change the `
Here is an example that shows how to use In-App Purchases in Electron. You'll have to replace the product ids by the identifiers of the products created with iTunes Connect (the identifier of `com.example.app.product1` is `product1`). Note that you have to listen to the `transactions-updated` event as soon as possible in your app. Here is an example that shows how to use In-App Purchases in Electron. You'll have to replace the product ids by the identifiers of the products created with iTunes Connect (the identifier of `com.example.app.product1` is `product1`). Note that you have to listen to the `transactions-updated` event as soon as possible in your app.
```javascript ```js
// Main process // Main process
const { inAppPurchase } = require('electron') const { inAppPurchase } = require('electron')
const PRODUCT_IDS = ['id1', 'id2'] const PRODUCT_IDS = ['id1', 'id2']

View File

@@ -66,7 +66,7 @@ You can use environment variables to override the base URL, the path at which to
look for Electron binaries, and the binary filename. The URL used by `@electron/get` look for Electron binaries, and the binary filename. The URL used by `@electron/get`
is composed as follows: is composed as follows:
```javascript @ts-nocheck ```js @ts-nocheck
url = ELECTRON_MIRROR + ELECTRON_CUSTOM_DIR + '/' + ELECTRON_CUSTOM_FILENAME url = ELECTRON_MIRROR + ELECTRON_CUSTOM_DIR + '/' + ELECTRON_CUSTOM_FILENAME
``` ```

View File

@@ -50,7 +50,7 @@ sections.
In the main process, set an IPC listener on the `set-title` channel with the `ipcMain.on` API: In the main process, set an IPC listener on the `set-title` channel with the `ipcMain.on` API:
```javascript {6-10,22} title='main.js (Main Process)' ```js {6-10,22} title='main.js (Main Process)'
const { app, BrowserWindow, ipcMain } = require('electron') const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path') const path = require('node:path')
@@ -96,7 +96,7 @@ you need to choose which APIs to expose from your preload script using the `cont
In your preload script, add the following code, which will expose a global `window.electronAPI` In your preload script, add the following code, which will expose a global `window.electronAPI`
variable to your renderer process. variable to your renderer process.
```javascript title='preload.js (Preload Script)' ```js title='preload.js (Preload Script)'
const { contextBridge, ipcRenderer } = require('electron') const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', { contextBridge.exposeInMainWorld('electronAPI', {
@@ -138,7 +138,7 @@ To make these elements interactive, we'll be adding a few lines of code in the i
`renderer.js` file that leverages the `window.electronAPI` functionality exposed from the preload `renderer.js` file that leverages the `window.electronAPI` functionality exposed from the preload
script: script:
```javascript title='renderer.js (Renderer Process)' @ts-expect-error=[4,5] ```js title='renderer.js (Renderer Process)' @ts-expect-error=[4,5]
const setButton = document.getElementById('btn') const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title') const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => { setButton.addEventListener('click', () => {
@@ -181,7 +181,7 @@ provided to the renderer process. Please refer to
[#24427](https://github.com/electron/electron/issues/24427) for details. [#24427](https://github.com/electron/electron/issues/24427) for details.
::: :::
```javascript {6-13,25} title='main.js (Main Process)' ```js {6-13,25} title='main.js (Main Process)'
const { app, BrowserWindow, dialog, ipcMain } = require('electron') const { app, BrowserWindow, dialog, ipcMain } = require('electron')
const path = require('node:path') const path = require('node:path')
@@ -225,7 +225,7 @@ In the preload script, we expose a one-line `openFile` function that calls and r
`ipcRenderer.invoke('dialog:openFile')`. We'll be using this API in the next step to call the `ipcRenderer.invoke('dialog:openFile')`. We'll be using this API in the next step to call the
native dialog from our renderer's user interface. native dialog from our renderer's user interface.
```javascript title='preload.js (Preload Script)' ```js title='preload.js (Preload Script)'
const { contextBridge, ipcRenderer } = require('electron') const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', { contextBridge.exposeInMainWorld('electronAPI', {
@@ -263,7 +263,7 @@ The UI consists of a single `#btn` button element that will be used to trigger o
a `#filePath` element that will be used to display the path of the selected file. Making these a `#filePath` element that will be used to display the path of the selected file. Making these
pieces work will take a few lines of code in the renderer process script: pieces work will take a few lines of code in the renderer process script:
```javascript title='renderer.js (Renderer Process)' @ts-expect-error=[5] ```js title='renderer.js (Renderer Process)' @ts-expect-error=[5]
const btn = document.getElementById('btn') const btn = document.getElementById('btn')
const filePathElement = document.getElementById('filePath') const filePathElement = document.getElementById('filePath')
@@ -299,7 +299,7 @@ The `ipcRenderer.send` API that we used for single-way communication can also be
perform two-way communication. This was the recommended way for asynchronous two-way communication perform two-way communication. This was the recommended way for asynchronous two-way communication
via IPC prior to Electron 7. via IPC prior to Electron 7.
```javascript title='preload.js (Preload Script)' ```js title='preload.js (Preload Script)'
// You can also put expose this code to the renderer // You can also put expose this code to the renderer
// process with the `contextBridge` API // process with the `contextBridge` API
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
@@ -310,7 +310,7 @@ ipcRenderer.on('asynchronous-reply', (_event, arg) => {
ipcRenderer.send('asynchronous-message', 'ping') ipcRenderer.send('asynchronous-message', 'ping')
``` ```
```javascript title='main.js (Main Process)' ```js title='main.js (Main Process)'
ipcMain.on('asynchronous-message', (event, arg) => { ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg) // prints "ping" in the Node console console.log(arg) // prints "ping" in the Node console
// works like `send`, but returning a message back // works like `send`, but returning a message back
@@ -332,7 +332,7 @@ channels, you would need to add additional app code to track each call and respo
The `ipcRenderer.sendSync` API sends a message to the main process and waits _synchronously_ for a The `ipcRenderer.sendSync` API sends a message to the main process and waits _synchronously_ for a
response. response.
```javascript title='main.js (Main Process)' ```js title='main.js (Main Process)'
const { ipcMain } = require('electron') const { ipcMain } = require('electron')
ipcMain.on('synchronous-message', (event, arg) => { ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg) // prints "ping" in the Node console console.log(arg) // prints "ping" in the Node console
@@ -340,7 +340,7 @@ ipcMain.on('synchronous-message', (event, arg) => {
}) })
``` ```
```javascript title='preload.js (Preload Script)' ```js title='preload.js (Preload Script)'
// You can also put expose this code to the renderer // You can also put expose this code to the renderer
// process with the `contextBridge` API // process with the `contextBridge` API
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
@@ -376,7 +376,7 @@ For this demo, we'll need to first build a custom menu in the main process using
module that uses the `webContents.send` API to send an IPC message from the main process to the module that uses the `webContents.send` API to send an IPC message from the main process to the
target renderer. target renderer.
```javascript {11-26} title='main.js (Main Process)' ```js {11-26} title='main.js (Main Process)'
const { app, BrowserWindow, Menu, ipcMain } = require('electron') const { app, BrowserWindow, Menu, ipcMain } = require('electron')
const path = require('node:path') const path = require('node:path')
@@ -412,7 +412,7 @@ function createWindow () {
For the purposes of the tutorial, it's important to note that the `click` handler For the purposes of the tutorial, it's important to note that the `click` handler
sends a message (either `1` or `-1`) to the renderer process through the `update-counter` channel. sends a message (either `1` or `-1`) to the renderer process through the `update-counter` channel.
```javascript @ts-type={mainWindow:Electron.BrowserWindow} ```js @ts-type={mainWindow:Electron.BrowserWindow}
click: () => mainWindow.webContents.send('update-counter', -1) click: () => mainWindow.webContents.send('update-counter', -1)
``` ```
@@ -425,11 +425,11 @@ Make sure you're loading the `index.html` and `preload.js` entry points for the
Like in the previous renderer-to-main example, we use the `contextBridge` and `ipcRenderer` Like in the previous renderer-to-main example, we use the `contextBridge` and `ipcRenderer`
modules in the preload script to expose IPC functionality to the renderer process: modules in the preload script to expose IPC functionality to the renderer process:
```javascript title='preload.js (Preload Script)' ```js title='preload.js (Preload Script)'
const { contextBridge, ipcRenderer } = require('electron') const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', { contextBridge.exposeInMainWorld('electronAPI', {
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', callback) onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value))
}) })
``` ```
@@ -439,13 +439,15 @@ After loading the preload script, your renderer process should have access to th
:::caution Security warning :::caution Security warning
We don't directly expose the whole `ipcRenderer.on` API for [security reasons][]. Make sure to We don't directly expose the whole `ipcRenderer.on` API for [security reasons][]. Make sure to
limit the renderer's access to Electron APIs as much as possible. limit the renderer's access to Electron APIs as much as possible.
Also don't just pass the callback to `ipcRenderer.on` as this will leak `ipcRenderer` via `event.sender`.
Use a custom handler that invoke the `callback` only with the desired arguments.
::: :::
:::info :::info
In the case of this minimal example, you can call `ipcRenderer.on` directly in the preload script In the case of this minimal example, you can call `ipcRenderer.on` directly in the preload script
rather than exposing it over the context bridge. rather than exposing it over the context bridge.
```javascript title='preload.js (Preload Script)' ```js title='preload.js (Preload Script)'
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
window.addEventListener('DOMContentLoaded', () => { window.addEventListener('DOMContentLoaded', () => {
@@ -486,10 +488,10 @@ To tie it all together, we'll create an interface in the loaded HTML file that c
Finally, to make the values update in the HTML document, we'll add a few lines of DOM manipulation Finally, to make the values update in the HTML document, we'll add a few lines of DOM manipulation
so that the value of the `#counter` element is updated whenever we fire an `update-counter` event. so that the value of the `#counter` element is updated whenever we fire an `update-counter` event.
```javascript title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(event:Electron.IpcRendererEvent,value:number)=>void)=>void}} ```js title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(value:number)=>void)=>void}}
const counter = document.getElementById('counter') const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((_event, value) => { window.electronAPI.onUpdateCounter((value) => {
const oldValue = Number(counter.innerText) const oldValue = Number(counter.innerText)
const newValue = oldValue + value const newValue = oldValue + value
counter.innerText = newValue.toString() counter.innerText = newValue.toString()
@@ -506,23 +508,32 @@ There's no equivalent for `ipcRenderer.invoke` for main-to-renderer IPC. Instead
send a reply back to the main process from within the `ipcRenderer.on` callback. send a reply back to the main process from within the `ipcRenderer.on` callback.
We can demonstrate this with slight modifications to the code from the previous example. In the We can demonstrate this with slight modifications to the code from the previous example. In the
renderer process, use the `event` parameter to send a reply back to the main process through the renderer process, expose another API to send a reply back to the main process through the
`counter-value` channel. `counter-value` channel.
```javascript title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(event:Electron.IpcRendererEvent,value:number)=>void)=>void}} ```js title='preload.js (Preload Script)'
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value)),
counterValue: (value) => ipcRenderer.send('counter-value', value)
})
```
```js title='renderer.js (Renderer Process)' @ts-window-type={electronAPI:{onUpdateCounter:(callback:(value:number)=>void)=>void,counterValue:(value:number)=>void}}
const counter = document.getElementById('counter') const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((event, value) => { window.electronAPI.onUpdateCounter((value) => {
const oldValue = Number(counter.innerText) const oldValue = Number(counter.innerText)
const newValue = oldValue + value const newValue = oldValue + value
counter.innerText = newValue.toString() counter.innerText = newValue.toString()
event.sender.send('counter-value', newValue) window.electronAPI.counterValue(newValue)
}) })
``` ```
In the main process, listen for `counter-value` events and handle them appropriately. In the main process, listen for `counter-value` events and handle them appropriately.
```javascript title='main.js (Main Process)' ```js title='main.js (Main Process)'
// ... // ...
ipcMain.on('counter-value', (_event, value) => { ipcMain.on('counter-value', (_event, value) => {
console.log(value) // will print value to Node console console.log(value) // will print value to Node console

View File

@@ -14,11 +14,19 @@ To configure a local keyboard shortcut, you need to specify an [`accelerator`][]
property when creating a [MenuItem][] within the [Menu][] module. property when creating a [MenuItem][] within the [Menu][] module.
Starting with a working application from the Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the [Quick Start Guide](quick-start.md), update the `main.js` to be:
following lines:
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/local' ```fiddle docs/fiddles/features/keyboard-shortcuts/local
const { Menu, MenuItem } = require('electron') const { app, BrowserWindow, Menu, MenuItem } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
const menu = new Menu() const menu = new Menu()
menu.append(new MenuItem({ menu.append(new MenuItem({
@@ -31,6 +39,20 @@ menu.append(new MenuItem({
})) }))
Menu.setApplicationMenu(menu) Menu.setApplicationMenu(menu)
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
``` ```
> NOTE: In the code above, you can see that the accelerator differs based on the > NOTE: In the code above, you can see that the accelerator differs based on the
@@ -53,17 +75,37 @@ module to detect keyboard events even when the application does not have
keyboard focus. keyboard focus.
Starting with a working application from the Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the [Quick Start Guide](quick-start.md), update the `main.js` to be:
following lines:
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/global' @ts-type={createWindow:()=>void} ```fiddle docs/fiddles/features/keyboard-shortcuts/global
const { app, globalShortcut } = require('electron') const { app, BrowserWindow, globalShortcut } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
app.whenReady().then(() => { app.whenReady().then(() => {
globalShortcut.register('Alt+CommandOrControl+I', () => { globalShortcut.register('Alt+CommandOrControl+I', () => {
console.log('Electron loves global shortcuts!') console.log('Electron loves global shortcuts!')
}) })
}).then(createWindow) }).then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
``` ```
> NOTE: In the code above, the `CommandOrControl` combination uses `Command` > NOTE: In the code above, the `CommandOrControl` combination uses `Command`
@@ -81,8 +123,8 @@ If you want to handle keyboard shortcuts within a [BrowserWindow][], you can
listen for the `keyup` and `keydown` [DOM events][dom-events] inside the listen for the `keyup` and `keydown` [DOM events][dom-events] inside the
renderer process using the [addEventListener() API][addEventListener-api]. renderer process using the [addEventListener() API][addEventListener-api].
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/web-apis|focus=renderer.js' ```fiddle docs/fiddles/features/keyboard-shortcuts/web-apis|focus=renderer.js
const handleKeyPress = (event) => { function handleKeyPress (event) {
// You can put code here to handle the keypress. // You can put code here to handle the keypress.
document.getElementById('last-keypress').innerText = event.key document.getElementById('last-keypress').innerText = event.key
console.log(`You pressed ${event.key}`) console.log(`You pressed ${event.key}`)
@@ -105,8 +147,8 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the [Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines: following lines:
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/interception-from-main' ```fiddle docs/fiddles/features/keyboard-shortcuts/interception-from-main
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron/main')
app.whenReady().then(() => { app.whenReady().then(() => {
const win = new BrowserWindow({ width: 800, height: 600 }) const win = new BrowserWindow({ width: 800, height: 600 })

View File

@@ -25,14 +25,14 @@ we will use will be "`electron-fiddle://`".
First, we will import the required modules from `electron`. These modules help First, we will import the required modules from `electron`. These modules help
control our application lifecycle and create a native browser window. control our application lifecycle and create a native browser window.
```javascript ```js
const { app, BrowserWindow, shell } = require('electron') const { app, BrowserWindow, shell } = require('electron')
const path = require('node:path') const path = require('node:path')
``` ```
Next, we will proceed to register our application to handle all "`electron-fiddle://`" protocols. Next, we will proceed to register our application to handle all "`electron-fiddle://`" protocols.
```javascript ```js
if (process.defaultApp) { if (process.defaultApp) {
if (process.argv.length >= 2) { if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('electron-fiddle', process.execPath, [path.resolve(process.argv[1])]) app.setAsDefaultProtocolClient('electron-fiddle', process.execPath, [path.resolve(process.argv[1])])
@@ -44,7 +44,7 @@ if (process.defaultApp) {
We will now define the function in charge of creating our browser window and load our application's `index.html` file. We will now define the function in charge of creating our browser window and load our application's `index.html` file.
```javascript ```js
let mainWindow let mainWindow
const createWindow = () => { const createWindow = () => {
@@ -67,7 +67,7 @@ This code will be different in Windows and Linux compared to MacOS. This is due
#### Windows and Linux code: #### Windows and Linux code:
```javascript @ts-type={mainWindow:Electron.BrowserWindow} @ts-type={createWindow:()=>void} ```js @ts-type={mainWindow:Electron.BrowserWindow} @ts-type={createWindow:()=>void}
const gotTheLock = app.requestSingleInstanceLock() const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) { if (!gotTheLock) {
@@ -92,7 +92,7 @@ if (!gotTheLock) {
#### MacOS code: #### MacOS code:
```javascript @ts-type={createWindow:()=>void} ```js @ts-type={createWindow:()=>void}
// This method will be called when Electron has finished // This method will be called when Electron has finished
// initialization and is ready to create browser windows. // initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs. // Some APIs can only be used after this event occurs.
@@ -108,7 +108,7 @@ app.on('open-url', (event, url) => {
Finally, we will add some additional code to handle when someone closes our application. Finally, we will add some additional code to handle when someone closes our application.
```javascript ```js
// Quit when all windows are closed, except on macOS. There, it's common // Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits // for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q. // explicitly with Cmd + Q.
@@ -159,7 +159,7 @@ shows the bare minimum needed to add the configuration changes)_:
} }
``` ```
#### [Electron Packager](https://github.com/electron/electron-packager) #### [Electron Packager](https://github.com/electron/packager)
For macOS support: For macOS support:
@@ -167,8 +167,8 @@ If you're using Electron Packager's API, adding support for protocol handlers is
Electron Forge is handled, except Electron Forge is handled, except
`protocols` is part of the Packager options passed to the `packager` function. `protocols` is part of the Packager options passed to the `packager` function.
```javascript @ts-nocheck ```js @ts-nocheck
const packager = require('electron-packager') const packager = require('@electron/packager')
packager({ packager({
// ...other options... // ...other options...

View File

@@ -23,10 +23,10 @@ To set your custom dock menu, you need to use the
[`app.dock.setMenu`](../api/dock.md#docksetmenumenu-macos) API, [`app.dock.setMenu`](../api/dock.md#docksetmenumenu-macos) API,
which is only available on macOS. which is only available on macOS.
```javascript fiddle='docs/fiddles/features/macos-dock-menu' ```fiddle docs/fiddles/features/macos-dock-menu
const { app, BrowserWindow, Menu } = require('electron') const { app, BrowserWindow, Menu } = require('electron/main')
const createWindow = () => { function createWindow () {
const win = new BrowserWindow({ const win = new BrowserWindow({
width: 800, width: 800,
height: 600 height: 600

View File

@@ -9,7 +9,7 @@ It is possible to use Node.js features in Electron's Web Workers, to do
so the `nodeIntegrationInWorker` option should be set to `true` in so the `nodeIntegrationInWorker` option should be set to `true` in
`webPreferences`. `webPreferences`.
```javascript ```js
const win = new BrowserWindow({ const win = new BrowserWindow({
webPreferences: { webPreferences: {
nodeIntegrationInWorker: true nodeIntegrationInWorker: true
@@ -42,7 +42,7 @@ safe.
The only way to load a native module safely for now, is to make sure the app The only way to load a native module safely for now, is to make sure the app
loads no native modules after the Web Workers get started. loads no native modules after the Web Workers get started.
```javascript @ts-expect-error=[1] ```js @ts-expect-error=[1]
process.dlopen = () => { process.dlopen = () => {
throw new Error('Load native module is not safe') throw new Error('Load native module is not safe')
} }

View File

@@ -44,7 +44,7 @@ Add a draggable element to `index.html`, and reference your renderer script:
In `renderer.js` set up the renderer process to handle drag events by calling the method you added via the [`contextBridge`][] above. In `renderer.js` set up the renderer process to handle drag events by calling the method you added via the [`contextBridge`][] above.
```javascript @ts-expect-error=[3] ```js @ts-expect-error=[3]
document.getElementById('drag').ondragstart = (event) => { document.getElementById('drag').ondragstart = (event) => {
event.preventDefault() event.preventDefault()
window.electron.startDrag('drag-and-drop.md') window.electron.startDrag('drag-and-drop.md')
@@ -56,15 +56,55 @@ document.getElementById('drag').ondragstart = (event) => {
In the Main process (`main.js` file), expand the received event with a path to the file that is In the Main process (`main.js` file), expand the received event with a path to the file that is
being dragged and an icon: being dragged and an icon:
```javascript fiddle='docs/fiddles/features/drag-and-drop' ```fiddle docs/fiddles/features/drag-and-drop
const { ipcMain } = require('electron') const { app, BrowserWindow, ipcMain } = require('electron/main')
const path = require('node:path')
const fs = require('node:fs')
const https = require('node:https')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
const iconName = path.join(__dirname, 'iconForDragAndDrop.png')
const icon = fs.createWriteStream(iconName)
// Create a new file to copy - you can also copy existing files.
fs.writeFileSync(path.join(__dirname, 'drag-and-drop-1.md'), '# First file to test drag and drop')
fs.writeFileSync(path.join(__dirname, 'drag-and-drop-2.md'), '# Second file to test drag and drop')
https.get('https://img.icons8.com/ios/452/drag-and-drop.png', (response) => {
response.pipe(icon)
})
app.whenReady().then(createWindow)
ipcMain.on('ondragstart', (event, filePath) => { ipcMain.on('ondragstart', (event, filePath) => {
event.sender.startDrag({ event.sender.startDrag({
file: filePath, file: path.join(__dirname, filePath),
icon: '/path/to/icon.png' icon: iconName
}) })
}) })
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
``` ```
After launching the Electron application, try dragging and dropping After launching the Electron application, try dragging and dropping

View File

@@ -30,16 +30,38 @@ new Notification({
Here's a full example that you can open with Electron Fiddle: Here's a full example that you can open with Electron Fiddle:
```javascript fiddle='docs/fiddles/features/notifications/main' ```fiddle docs/fiddles/features/notifications/main
const { Notification } = require('electron') const { app, BrowserWindow, Notification } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
const NOTIFICATION_TITLE = 'Basic Notification' const NOTIFICATION_TITLE = 'Basic Notification'
const NOTIFICATION_BODY = 'Notification from the Main process' const NOTIFICATION_BODY = 'Notification from the Main process'
new Notification({ function showNotification () {
title: NOTIFICATION_TITLE, new Notification({ title: NOTIFICATION_TITLE, body: NOTIFICATION_BODY }).show()
body: NOTIFICATION_BODY }
}).show()
app.whenReady().then(createWindow).then(showNotification)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
``` ```
### Show notifications in the renderer process ### Show notifications in the renderer process
@@ -59,14 +81,13 @@ new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY }).onclick =
Here's a full example that you can open with Electron Fiddle: Here's a full example that you can open with Electron Fiddle:
```javascript fiddle='docs/fiddles/features/notifications/renderer' ```fiddle docs/fiddles/features/notifications/renderer|focus=renderer.js
const NOTIFICATION_TITLE = 'Title' const NOTIFICATION_TITLE = 'Title'
const NOTIFICATION_BODY = const NOTIFICATION_BODY = 'Notification from the Renderer process. Click to log to console.'
'Notification from the Renderer process. Click to log to console.' const CLICK_MESSAGE = 'Notification clicked!'
const CLICK_MESSAGE = 'Notification clicked'
new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY }).onclick = new window.Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY })
() => console.log(CLICK_MESSAGE) .onclick = () => { document.getElementById('output').innerText = CLICK_MESSAGE }
``` ```
## Platform considerations ## Platform considerations

View File

@@ -39,22 +39,44 @@ To enable this mode, GPU acceleration has to be disabled by calling the
## Example ## Example
```javascript fiddle='docs/fiddles/features/offscreen-rendering' ```fiddle docs/fiddles/features/offscreen-rendering
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron/main')
const fs = require('node:fs') const fs = require('node:fs')
const path = require('node:path')
app.disableHardwareAcceleration() app.disableHardwareAcceleration()
let win function createWindow () {
const win = new BrowserWindow({
app.whenReady().then(() => { width: 800,
win = new BrowserWindow({ webPreferences: { offscreen: true } }) height: 600,
webPreferences: {
offscreen: true
}
})
win.loadURL('https://github.com') win.loadURL('https://github.com')
win.webContents.on('paint', (event, dirty, image) => { win.webContents.on('paint', (event, dirty, image) => {
fs.writeFileSync('ex.png', image.toPNG()) fs.writeFileSync('ex.png', image.toPNG())
}) })
win.webContents.setFrameRate(60) win.webContents.setFrameRate(60)
console.log(`The screenshot has been successfully saved to ${path.join(process.cwd(), 'ex.png')}`)
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
}) })
``` ```

View File

@@ -50,12 +50,12 @@ See the [API documentation for more options and modes][setprogressbar].
In this example, we add a progress bar to the main window that increments over time In this example, we add a progress bar to the main window that increments over time
using Node.js timers. using Node.js timers.
```javascript fiddle='docs/fiddles/features/progress-bar' ```fiddle docs/fiddles/features/progress-bar
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron/main')
let progressInterval let progressInterval
const createWindow = () => { function createWindow () {
const win = new BrowserWindow({ const win = new BrowserWindow({
width: 800, width: 800,
height: 600 height: 600
@@ -73,8 +73,11 @@ const createWindow = () => {
win.setProgressBar(c) win.setProgressBar(c)
// increment or reset progress bar // increment or reset progress bar
if (c < 2) c += INCREMENT if (c < 2) {
else c = 0 c += INCREMENT
} else {
c = (-INCREMENT * 5) // reset to a bit less than 0 to show reset state
}
}, INTERVAL_DELAY) }, INTERVAL_DELAY)
} }

View File

@@ -24,12 +24,12 @@ the application via JumpList or dock menu, respectively.
### Managing recent documents ### Managing recent documents
```javascript fiddle='docs/fiddles/features/recent-documents' ```fiddle docs/fiddles/features/recent-documents
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron/main')
const fs = require('node:fs') const fs = require('node:fs')
const path = require('node:path') const path = require('node:path')
const createWindow = () => { function createWindow () {
const win = new BrowserWindow({ const win = new BrowserWindow({
width: 800, width: 800,
height: 600 height: 600
@@ -116,7 +116,7 @@ following code snippet to your menu template:
Make sure the application menu is added after the [`'ready'`](../api/app.md#event-ready) Make sure the application menu is added after the [`'ready'`](../api/app.md#event-ready)
event and not before, or the menu item will be disabled: event and not before, or the menu item will be disabled:
```javascript ```js
const { app, Menu } = require('electron') const { app, Menu } = require('electron')
const template = [ const template = [

View File

@@ -27,22 +27,30 @@ To set the represented file of window, you can use the
## Example ## Example
```javascript fiddle='docs/fiddles/features/represented-file' ```fiddle docs/fiddles/features/represented-file
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron/main')
const os = require('node:os') const os = require('node:os')
const createWindow = () => { function createWindow () {
const win = new BrowserWindow({ const win = new BrowserWindow({
width: 800, width: 800,
height: 600 height: 600
}) })
}
app.whenReady().then(() => {
const win = new BrowserWindow()
win.setRepresentedFilename(os.homedir()) win.setRepresentedFilename(os.homedir())
win.setDocumentEdited(true) win.setDocumentEdited(true)
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
}) })
app.on('window-all-closed', () => { app.on('window-all-closed', () => {
@@ -50,12 +58,6 @@ app.on('window-all-closed', () => {
app.quit() app.quit()
} }
}) })
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
``` ```
After launching the Electron application, click on the title with `Command` or After launching the Electron application, click on the title with `Command` or

View File

@@ -375,7 +375,7 @@ which can be set using Electron's
[`webRequest.onHeadersReceived`](../api/web-request.md#webrequestonheadersreceivedfilter-listener) [`webRequest.onHeadersReceived`](../api/web-request.md#webrequestonheadersreceivedfilter-listener)
handler: handler:
```javascript title='main.js (Main Process)' ```js title='main.js (Main Process)'
const { session } = require('electron') const { session } = require('electron')
session.defaultSession.webRequest.onHeadersReceived((details, callback) => { session.defaultSession.webRequest.onHeadersReceived((details, callback) => {

View File

@@ -16,7 +16,7 @@ There are three ways to create a `.snap` file:
1) Using [Electron Forge][electron-forge] or 1) Using [Electron Forge][electron-forge] or
[`electron-builder`][electron-builder], both tools that come with `snap` [`electron-builder`][electron-builder], both tools that come with `snap`
support out of the box. This is the easiest option. support out of the box. This is the easiest option.
2) Using `electron-installer-snap`, which takes `electron-packager`'s output. 2) Using `electron-installer-snap`, which takes `@electron/packager`'s output.
3) Using an already created `.deb` package. 3) Using an already created `.deb` package.
In some cases, you will need to have the `snapcraft` tool installed. In some cases, you will need to have the `snapcraft` tool installed.
@@ -35,7 +35,7 @@ npm install --save-dev electron-installer-snap
### Step 1: Package Your Electron Application ### Step 1: Package Your Electron Application
Package the application using [electron-packager][electron-packager] (or a Package the application using [@electron/packager][electron-packager] (or a
similar tool). Make sure to remove `node_modules` that you don't need in your similar tool). Make sure to remove `node_modules` that you don't need in your
final application, since any module you don't actually need will increase final application, since any module you don't actually need will increase
your application's size. your application's size.
@@ -79,7 +79,7 @@ snap(options)
.then(snapPath => console.log(`Created snap at ${snapPath}!`)) .then(snapPath => console.log(`Created snap at ${snapPath}!`))
``` ```
## Using `snapcraft` with `electron-packager` ## Using `snapcraft` with `@electron/packager`
### Step 1: Create Sample Snapcraft Project ### Step 1: Create Sample Snapcraft Project
@@ -113,7 +113,7 @@ parts:
plugin: nil plugin: nil
source: https://github.com/electron/electron-quick-start.git source: https://github.com/electron/electron-quick-start.git
override-build: | override-build: |
npm install electron electron-packager npm install electron @electron/packager
npx electron-packager . --overwrite --platform=linux --output=release-build --prune=true npx electron-packager . --overwrite --platform=linux --output=release-build --prune=true
cp -rv ./electron-quick-start-linux-* $SNAPCRAFT_PART_INSTALL/electron-quick-start cp -rv ./electron-quick-start-linux-* $SNAPCRAFT_PART_INSTALL/electron-quick-start
build-snaps: build-snaps:
@@ -266,7 +266,7 @@ Finally, configure your application's environment for PipeWire:
``` ```
[snapcraft-syntax]: https://docs.snapcraft.io/build-snaps/syntax [snapcraft-syntax]: https://docs.snapcraft.io/build-snaps/syntax
[electron-packager]: https://github.com/electron/electron-packager [electron-packager]: https://github.com/electron/packager
[electron-forge]: https://github.com/electron/forge [electron-forge]: https://github.com/electron/forge
[electron-builder]: https://github.com/electron-userland/electron-builder [electron-builder]: https://github.com/electron-userland/electron-builder
[electron-installer-debian]: https://github.com/electron-userland/electron-installer-debian [electron-installer-debian]: https://github.com/electron-userland/electron-installer-debian

View File

@@ -243,11 +243,11 @@ const { app, BrowserWindow } = require('electron/main')
For more information, see the [Process Model docs](../tutorial/process-model.md#process-specific-module-aliases-typescript). For more information, see the [Process Model docs](../tutorial/process-model.md#process-specific-module-aliases-typescript).
</details> </details>
:::warning ES Modules in Electron :::info ES Modules in Electron
[ECMAScript modules](https://nodejs.org/api/esm.html) (i.e. using `import` to load a module) [ECMAScript modules](https://nodejs.org/api/esm.html) (i.e. using `import` to load a module)
are currently not directly supported in Electron. You can find more information about the are supported in Electron as of Electron 28. You can find more information about the
state of ESM in Electron in [electron/electron#21457](https://github.com/electron/electron/issues/21457). state of ESM in Electron and how to use them in our app in [our ESM guide](../tutorial/esm.md).
::: :::

View File

@@ -35,7 +35,7 @@ as a **distributable**). Distributables can be either installers (e.g. MSI on Wi
portable executable files (e.g. `.app` on macOS). portable executable files (e.g. `.app` on macOS).
Electron Forge is an all-in-one tool that handles the packaging and distribution of Electron Electron Forge is an all-in-one tool that handles the packaging and distribution of Electron
apps. Under the hood, it combines a lot of existing Electron tools (e.g. [`electron-packager`][], apps. Under the hood, it combines a lot of existing Electron tools (e.g. [`@electron/packager`][],
[`@electron/osx-sign`][], [`electron-winstaller`][], etc.) into a single interface so you do not [`@electron/osx-sign`][], [`electron-winstaller`][], etc.) into a single interface so you do not
have to worry about wiring them all together. have to worry about wiring them all together.
@@ -200,7 +200,7 @@ information.
[`@electron/osx-sign`]: https://github.com/electron/osx-sign [`@electron/osx-sign`]: https://github.com/electron/osx-sign
[application packaging]: ./application-distribution.md [application packaging]: ./application-distribution.md
[`electron-packager`]: https://github.com/electron/electron-packager [`@electron/packager`]: https://github.com/electron/packager
[`electron-winstaller`]: https://github.com/electron/windows-installer [`electron-winstaller`]: https://github.com/electron/windows-installer
[electron forge]: https://www.electronforge.io [electron forge]: https://www.electronforge.io
[electron forge cli documentation]: https://www.electronforge.io/cli#commands [electron forge cli documentation]: https://www.electronforge.io/cli#commands

View File

@@ -81,14 +81,14 @@ You can use the [app.isPackaged](../api/app.md#appispackaged-readonly) API to ch
::: :::
```javascript title='main.js' ```js title='main.js'
const { app, autoUpdater, dialog } = require('electron') const { app, autoUpdater, dialog } = require('electron')
``` ```
Next, construct the URL of the update server feed and tell Next, construct the URL of the update server feed and tell
[autoUpdater](../api/auto-updater.md) about it: [autoUpdater](../api/auto-updater.md) about it:
```javascript title='main.js' ```js title='main.js'
const server = 'https://your-deployment-url.com' const server = 'https://your-deployment-url.com'
const url = `${server}/update/${process.platform}/${app.getVersion()}` const url = `${server}/update/${process.platform}/${app.getVersion()}`
@@ -97,7 +97,7 @@ autoUpdater.setFeedURL({ url })
As the final step, check for updates. The example below will check every minute: As the final step, check for updates. The example below will check every minute:
```javascript title='main.js' ```js title='main.js'
setInterval(() => { setInterval(() => {
autoUpdater.checkForUpdates() autoUpdater.checkForUpdates()
}, 60000) }, 60000)
@@ -113,7 +113,7 @@ Now that you've configured the basic update mechanism for your application, you
need to ensure that the user will get notified when there's an update. This need to ensure that the user will get notified when there's an update. This
can be achieved using the [autoUpdater API events](../api/auto-updater.md#events): can be achieved using the [autoUpdater API events](../api/auto-updater.md#events):
```javascript title="main.js" @ts-expect-error=[11] ```js title="main.js" @ts-expect-error=[11]
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => { autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {
const dialogOpts = { const dialogOpts = {
type: 'info', type: 'info',
@@ -134,7 +134,7 @@ Also make sure that errors are
[being handled](../api/auto-updater.md#event-error). Here's an example [being handled](../api/auto-updater.md#event-error). Here's an example
for logging them to `stderr`: for logging them to `stderr`:
```javascript title="main.js" ```js title="main.js"
autoUpdater.on('error', (message) => { autoUpdater.on('error', (message) => {
console.error('There was a problem updating the application') console.error('There was a problem updating the application')
console.error(message) console.error(message)

View File

@@ -169,5 +169,5 @@ environment variable.
[abi]: https://en.wikipedia.org/wiki/Application_binary_interface [abi]: https://en.wikipedia.org/wiki/Application_binary_interface
[@electron/rebuild]: https://github.com/electron/rebuild [@electron/rebuild]: https://github.com/electron/rebuild
[electron-forge]: https://electronforge.io/ [electron-forge]: https://electronforge.io/
[electron-packager]: https://github.com/electron/electron-packager [electron-packager]: https://github.com/electron/packager
[node-pre-gyp]: https://github.com/mapbox/node-pre-gyp [node-pre-gyp]: https://github.com/mapbox/node-pre-gyp

View File

@@ -14,7 +14,7 @@ that are not a part of the web page.
To create a frameless window, you need to set `frame` to `false` in the `BrowserWindow` To create a frameless window, you need to set `frame` to `false` in the `BrowserWindow`
constructor. constructor.
```javascript title='main.js' ```js title='main.js'
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ frame: false }) const win = new BrowserWindow({ frame: false })
``` ```
@@ -28,7 +28,7 @@ option in the `BrowserWindow` constructor.
Applying the `hidden` title bar style results in a hidden title bar and a full-size Applying the `hidden` title bar style results in a hidden title bar and a full-size
content window. content window.
```javascript title='main.js' ```js title='main.js'
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' }) const win = new BrowserWindow({ titleBarStyle: 'hidden' })
``` ```
@@ -44,7 +44,7 @@ The `customButtonsOnHover` title bar style will hide the traffic lights until yo
over them. This is useful if you want to create custom traffic lights in your HTML but still over them. This is useful if you want to create custom traffic lights in your HTML but still
use the native UI to control the window. use the native UI to control the window.
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' }) const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })
``` ```
@@ -57,7 +57,7 @@ options available.
Applying `hiddenInset` title bar style will shift the vertical inset of the traffic lights Applying `hiddenInset` title bar style will shift the vertical inset of the traffic lights
by a fixed amount. by a fixed amount.
```javascript title='main.js' ```js title='main.js'
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' }) const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
``` ```
@@ -66,7 +66,7 @@ If you need more granular control over the positioning of the traffic lights, yo
a set of coordinates to the `trafficLightPosition` option in the `BrowserWindow` a set of coordinates to the `trafficLightPosition` option in the `BrowserWindow`
constructor. constructor.
```javascript title='main.js' ```js title='main.js'
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ const win = new BrowserWindow({
titleBarStyle: 'hidden', titleBarStyle: 'hidden',
@@ -80,7 +80,7 @@ You can also show and hide the traffic lights programmatically from the main pro
The `win.setWindowButtonVisibility` forces traffic lights to be show or hidden depending The `win.setWindowButtonVisibility` forces traffic lights to be show or hidden depending
on the value of its boolean parameter. on the value of its boolean parameter.
```javascript title='main.js' ```js title='main.js'
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
// hides the traffic lights // hides the traffic lights
@@ -106,7 +106,7 @@ The `titleBarOverlay` option accepts two different value formats.
Specifying `true` on either platform will result in an overlay region with default Specifying `true` on either platform will result in an overlay region with default
system colors: system colors:
```javascript title='main.js' ```js title='main.js'
// on macOS or Windows // on macOS or Windows
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ const win = new BrowserWindow({
@@ -119,7 +119,7 @@ On either platform `titleBarOverlay` can also be an object. On both macOS and Wi
If a color option is not specified, the color will default to its system color for the window control buttons. Similarly, if the height option is not specified it will default to the default height: If a color option is not specified, the color will default to its system color for the window control buttons. Similarly, if the height option is not specified it will default to the default height:
```javascript title='main.js' ```js title='main.js'
// on Windows // on Windows
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ const win = new BrowserWindow({
@@ -140,7 +140,7 @@ const win = new BrowserWindow({
By setting the `transparent` option to `true`, you can make a fully transparent window. By setting the `transparent` option to `true`, you can make a fully transparent window.
```javascript title='main.js' ```js title='main.js'
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true }) const win = new BrowserWindow({ transparent: true })
``` ```
@@ -169,7 +169,7 @@ To create a click-through window, i.e. making the window ignore all mouse
events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events] events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events]
API: API:
```javascript title='main.js' ```js title='main.js'
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
win.setIgnoreMouseEvents(true) win.setIgnoreMouseEvents(true)
@@ -182,7 +182,7 @@ meaning that mouse movement events will not be emitted. On Windows and macOS, an
optional parameter can be used to forward mouse move messages to the web page, optional parameter can be used to forward mouse move messages to the web page,
allowing events such as `mouseleave` to be emitted: allowing events such as `mouseleave` to be emitted:
```javascript title='main.js' ```js title='main.js'
const { BrowserWindow, ipcMain } = require('electron') const { BrowserWindow, ipcMain } = require('electron')
const path = require('node:path') const path = require('node:path')
@@ -198,7 +198,7 @@ ipcMain.on('set-ignore-mouse-events', (event, ignore, options) => {
}) })
``` ```
```javascript title='preload.js' ```js title='preload.js'
window.addEventListener('DOMContentLoaded', () => { window.addEventListener('DOMContentLoaded', () => {
const el = document.getElementById('clickThroughElement') const el = document.getElementById('clickThroughElement')
el.addEventListener('mouseenter', () => { el.addEventListener('mouseenter', () => {

View File

@@ -42,7 +42,7 @@ npm install -g electron-windows-store
## Step 1: Package Your Electron Application ## Step 1: Package Your Electron Application
Package the application using [electron-packager][electron-packager] (or a similar tool). Package the application using [`@electron/packager`][electron-packager] (or a similar tool).
Make sure to remove `node_modules` that you don't need in your final application, since Make sure to remove `node_modules` that you don't need in your final application, since
any module you don't actually need will increase your application's size. any module you don't actually need will increase your application's size.
@@ -151,7 +151,7 @@ Once installation succeeded, you can move on to compiling your Electron app.
[windows-sdk]: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/ [windows-sdk]: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
[app-converter]: https://learn.microsoft.com/en-us/windows/msix/packaging-tool/tool-overview [app-converter]: https://learn.microsoft.com/en-us/windows/msix/packaging-tool/tool-overview
[add-appxpackage]: https://learn.microsoft.com/en-us/previous-versions//hh856048(v=technet.10)?redirectedfrom=MSDN [add-appxpackage]: https://learn.microsoft.com/en-us/previous-versions//hh856048(v=technet.10)?redirectedfrom=MSDN
[electron-packager]: https://github.com/electron/electron-packager [electron-packager]: https://github.com/electron/packager
[electron-windows-store]: https://github.com/electron-userland/electron-windows-store [electron-windows-store]: https://github.com/electron-userland/electron-windows-store
[background-task]: https://github.com/felixrieseberg/electron-uwp-background [background-task]: https://github.com/felixrieseberg/electron-uwp-background
[centennial-campaigns]: https://developer.microsoft.com/en-us/windows/projects/campaigns/desktop-bridge [centennial-campaigns]: https://developer.microsoft.com/en-us/windows/projects/campaigns/desktop-bridge

View File

@@ -60,7 +60,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the [Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines: following lines:
```javascript ```js
const { app } = require('electron') const { app } = require('electron')
app.setUserTasks([ app.setUserTasks([
@@ -80,7 +80,7 @@ app.setUserTasks([
To clear your tasks list, you need to call `app.setUserTasks` with an empty To clear your tasks list, you need to call `app.setUserTasks` with an empty
array in the `main.js` file. array in the `main.js` file.
```javascript ```js
const { app } = require('electron') const { app } = require('electron')
app.setUserTasks([]) app.setUserTasks([])
@@ -124,7 +124,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the [Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines: following lines:
```javascript ```js
const { BrowserWindow, nativeImage } = require('electron') const { BrowserWindow, nativeImage } = require('electron')
const path = require('node:path') const path = require('node:path')
@@ -149,7 +149,7 @@ win.setThumbarButtons([
To clear thumbnail toolbar buttons, you need to call To clear thumbnail toolbar buttons, you need to call
`BrowserWindow.setThumbarButtons` with an empty array in the `main.js` file. `BrowserWindow.setThumbarButtons` with an empty array in the `main.js` file.
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
@@ -188,7 +188,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the [Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines: following lines:
```javascript ```js
const { BrowserWindow, nativeImage } = require('electron') const { BrowserWindow, nativeImage } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
@@ -217,7 +217,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the [Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines: following lines:
```javascript ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()

View File

@@ -199,6 +199,8 @@ filenames = {
"shell/common/language_util_mac.mm", "shell/common/language_util_mac.mm",
"shell/common/mac/main_application_bundle.h", "shell/common/mac/main_application_bundle.h",
"shell/common/mac/main_application_bundle.mm", "shell/common/mac/main_application_bundle.mm",
"shell/common/mac/codesign_util.cc",
"shell/common/mac/codesign_util.h",
"shell/common/node_bindings_mac.cc", "shell/common/node_bindings_mac.cc",
"shell/common/node_bindings_mac.h", "shell/common/node_bindings_mac.h",
"shell/common/platform_util_mac.mm", "shell/common/platform_util_mac.mm",
@@ -660,6 +662,7 @@ filenames = {
"shell/common/node_includes.h", "shell/common/node_includes.h",
"shell/common/node_util.cc", "shell/common/node_util.cc",
"shell/common/node_util.h", "shell/common/node_util.h",
"shell/common/node_util_mac.mm",
"shell/common/options_switches.cc", "shell/common/options_switches.cc",
"shell/common/options_switches.h", "shell/common/options_switches.h",
"shell/common/platform_util.cc", "shell/common/platform_util.cc",
@@ -709,6 +712,8 @@ filenames = {
] ]
lib_sources_extensions = [ lib_sources_extensions = [
"shell/browser/extensions/api/extension_action/extension_action_api.cc",
"shell/browser/extensions/api/extension_action/extension_action_api.h",
"shell/browser/extensions/api/management/electron_management_api_delegate.cc", "shell/browser/extensions/api/management/electron_management_api_delegate.cc",
"shell/browser/extensions/api/management/electron_management_api_delegate.h", "shell/browser/extensions/api/management/electron_management_api_delegate.h",
"shell/browser/extensions/api/resources_private/resources_private_api.cc", "shell/browser/extensions/api/resources_private/resources_private_api.cc",

View File

@@ -95,7 +95,9 @@ libcxx_headers = [
"//third_party/libc++/src/include/__algorithm/pstl_generate.h", "//third_party/libc++/src/include/__algorithm/pstl_generate.h",
"//third_party/libc++/src/include/__algorithm/pstl_is_partitioned.h", "//third_party/libc++/src/include/__algorithm/pstl_is_partitioned.h",
"//third_party/libc++/src/include/__algorithm/pstl_merge.h", "//third_party/libc++/src/include/__algorithm/pstl_merge.h",
"//third_party/libc++/src/include/__algorithm/pstl_move.h",
"//third_party/libc++/src/include/__algorithm/pstl_replace.h", "//third_party/libc++/src/include/__algorithm/pstl_replace.h",
"//third_party/libc++/src/include/__algorithm/pstl_rotate_copy.h",
"//third_party/libc++/src/include/__algorithm/pstl_sort.h", "//third_party/libc++/src/include/__algorithm/pstl_sort.h",
"//third_party/libc++/src/include/__algorithm/pstl_stable_sort.h", "//third_party/libc++/src/include/__algorithm/pstl_stable_sort.h",
"//third_party/libc++/src/include/__algorithm/pstl_transform.h", "//third_party/libc++/src/include/__algorithm/pstl_transform.h",
@@ -510,6 +512,7 @@ libcxx_headers = [
"//third_party/libc++/src/include/__mdspan/extents.h", "//third_party/libc++/src/include/__mdspan/extents.h",
"//third_party/libc++/src/include/__mdspan/layout_left.h", "//third_party/libc++/src/include/__mdspan/layout_left.h",
"//third_party/libc++/src/include/__mdspan/layout_right.h", "//third_party/libc++/src/include/__mdspan/layout_right.h",
"//third_party/libc++/src/include/__mdspan/layout_stride.h",
"//third_party/libc++/src/include/__mdspan/mdspan.h", "//third_party/libc++/src/include/__mdspan/mdspan.h",
"//third_party/libc++/src/include/__memory/addressof.h", "//third_party/libc++/src/include/__memory/addressof.h",
"//third_party/libc++/src/include/__memory/align.h", "//third_party/libc++/src/include/__memory/align.h",
@@ -840,6 +843,7 @@ libcxx_headers = [
"//third_party/libc++/src/include/__utility/cmp.h", "//third_party/libc++/src/include/__utility/cmp.h",
"//third_party/libc++/src/include/__utility/convert_to_integral.h", "//third_party/libc++/src/include/__utility/convert_to_integral.h",
"//third_party/libc++/src/include/__utility/declval.h", "//third_party/libc++/src/include/__utility/declval.h",
"//third_party/libc++/src/include/__utility/empty.h",
"//third_party/libc++/src/include/__utility/exception_guard.h", "//third_party/libc++/src/include/__utility/exception_guard.h",
"//third_party/libc++/src/include/__utility/exchange.h", "//third_party/libc++/src/include/__utility/exchange.h",
"//third_party/libc++/src/include/__utility/forward.h", "//third_party/libc++/src/include/__utility/forward.h",
@@ -852,8 +856,8 @@ libcxx_headers = [
"//third_party/libc++/src/include/__utility/piecewise_construct.h", "//third_party/libc++/src/include/__utility/piecewise_construct.h",
"//third_party/libc++/src/include/__utility/priority_tag.h", "//third_party/libc++/src/include/__utility/priority_tag.h",
"//third_party/libc++/src/include/__utility/rel_ops.h", "//third_party/libc++/src/include/__utility/rel_ops.h",
"//third_party/libc++/src/include/__utility/small_buffer.h",
"//third_party/libc++/src/include/__utility/swap.h", "//third_party/libc++/src/include/__utility/swap.h",
"//third_party/libc++/src/include/__utility/terminate_on_exception.h",
"//third_party/libc++/src/include/__utility/to_underlying.h", "//third_party/libc++/src/include/__utility/to_underlying.h",
"//third_party/libc++/src/include/__utility/unreachable.h", "//third_party/libc++/src/include/__utility/unreachable.h",
"//third_party/libc++/src/include/__variant/monostate.h", "//third_party/libc++/src/include/__variant/monostate.h",
@@ -956,7 +960,6 @@ libcxx_headers = [
"//third_party/libc++/src/include/latch", "//third_party/libc++/src/include/latch",
"//third_party/libc++/src/include/libcxx.imp", "//third_party/libc++/src/include/libcxx.imp",
"//third_party/libc++/src/include/limits", "//third_party/libc++/src/include/limits",
"//third_party/libc++/src/include/limits.h",
"//third_party/libc++/src/include/list", "//third_party/libc++/src/include/list",
"//third_party/libc++/src/include/locale", "//third_party/libc++/src/include/locale",
"//third_party/libc++/src/include/locale.h", "//third_party/libc++/src/include/locale.h",
@@ -981,7 +984,6 @@ libcxx_headers = [
"//third_party/libc++/src/include/scoped_allocator", "//third_party/libc++/src/include/scoped_allocator",
"//third_party/libc++/src/include/semaphore", "//third_party/libc++/src/include/semaphore",
"//third_party/libc++/src/include/set", "//third_party/libc++/src/include/set",
"//third_party/libc++/src/include/setjmp.h",
"//third_party/libc++/src/include/shared_mutex", "//third_party/libc++/src/include/shared_mutex",
"//third_party/libc++/src/include/source_location", "//third_party/libc++/src/include/source_location",
"//third_party/libc++/src/include/span", "//third_party/libc++/src/include/span",

View File

@@ -261,6 +261,14 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
fs.writeSync(logFDs.get(asarPath), `${offset}: ${filePath}\n`); fs.writeSync(logFDs.get(asarPath), `${offset}: ${filePath}\n`);
}; };
const shouldThrowStatError = (options: any) => {
if (options && typeof options === 'object' && options.throwIfNoEntry === false) {
return false;
}
return true;
};
const { lstatSync } = fs; const { lstatSync } = fs;
fs.lstatSync = (pathArgument: string, options: any) => { fs.lstatSync = (pathArgument: string, options: any) => {
const pathInfo = splitPath(pathArgument); const pathInfo = splitPath(pathArgument);
@@ -268,10 +276,16 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
const { asarPath, filePath } = pathInfo; const { asarPath, filePath } = pathInfo;
const archive = getOrCreateArchive(asarPath); const archive = getOrCreateArchive(asarPath);
if (!archive) throw createError(AsarError.INVALID_ARCHIVE, { asarPath }); if (!archive) {
if (shouldThrowStatError(options)) throw createError(AsarError.INVALID_ARCHIVE, { asarPath });
return null;
}
const stats = archive.stat(filePath); const stats = archive.stat(filePath);
if (!stats) throw createError(AsarError.NOT_FOUND, { asarPath, filePath }); if (!stats) {
if (shouldThrowStatError(options)) throw createError(AsarError.NOT_FOUND, { asarPath, filePath });
return null;
}
return asarStatsToFsStats(stats); return asarStatsToFsStats(stats);
}; };

View File

@@ -187,149 +187,57 @@ WebContents.prototype.executeJavaScriptInIsolatedWorld = async function (worldId
return ipcMainUtils.invokeInWebContents(this, IPC_MESSAGES.RENDERER_WEB_FRAME_METHOD, 'executeJavaScriptInIsolatedWorld', worldId, code, !!hasUserGesture); return ipcMainUtils.invokeInWebContents(this, IPC_MESSAGES.RENDERER_WEB_FRAME_METHOD, 'executeJavaScriptInIsolatedWorld', worldId, code, !!hasUserGesture);
}; };
function checkType<T> (value: T, type: 'number' | 'boolean' | 'string' | 'object', name: string): T {
// eslint-disable-next-line valid-typeof
if (typeof value !== type) {
throw new TypeError(`${name} must be a ${type}`);
}
return value;
}
function parsePageSize (pageSize: string | ElectronInternal.PageSize) {
if (typeof pageSize === 'string') {
const format = paperFormats[pageSize.toLowerCase()];
if (!format) {
throw new Error(`Invalid pageSize ${pageSize}`);
}
return { paperWidth: format.width, paperHeight: format.height };
} else if (typeof pageSize === 'object') {
if (typeof pageSize.width !== 'number' || typeof pageSize.height !== 'number') {
throw new TypeError('width and height properties are required for pageSize');
}
return { paperWidth: pageSize.width, paperHeight: pageSize.height };
} else {
throw new TypeError('pageSize must be a string or an object');
}
}
// Translate the options of printToPDF. // Translate the options of printToPDF.
let pendingPromise: Promise<any> | undefined; let pendingPromise: Promise<any> | undefined;
WebContents.prototype.printToPDF = async function (options) { WebContents.prototype.printToPDF = async function (options) {
const printSettings: Record<string, any> = { const margins = checkType(options.margins ?? {}, 'object', 'margins');
const printSettings = {
requestID: getNextId(), requestID: getNextId(),
landscape: false, landscape: checkType(options.landscape ?? false, 'boolean', 'landscape'),
displayHeaderFooter: false, displayHeaderFooter: checkType(options.displayHeaderFooter ?? false, 'boolean', 'displayHeaderFooter'),
headerTemplate: '', headerTemplate: checkType(options.headerTemplate ?? '', 'string', 'headerTemplate'),
footerTemplate: '', footerTemplate: checkType(options.footerTemplate ?? '', 'string', 'footerTemplate'),
printBackground: false, printBackground: checkType(options.printBackground ?? false, 'boolean', 'printBackground'),
scale: 1.0, scale: checkType(options.scale ?? 1.0, 'number', 'scale'),
paperWidth: 8.5, marginTop: checkType(margins.top ?? 0.4, 'number', 'margins.top'),
paperHeight: 11.0, marginBottom: checkType(margins.bottom ?? 0.4, 'number', 'margins.bottom'),
marginTop: 0.4, marginLeft: checkType(margins.left ?? 0.4, 'number', 'margins.left'),
marginBottom: 0.4, marginRight: checkType(margins.right ?? 0.4, 'number', 'margins.right'),
marginLeft: 0.4, pageRanges: checkType(options.pageRanges ?? '', 'string', 'pageRanges'),
marginRight: 0.4, preferCSSPageSize: checkType(options.preferCSSPageSize ?? false, 'boolean', 'preferCSSPageSize'),
pageRanges: '', generateTaggedPDF: checkType(options.generateTaggedPDF ?? false, 'boolean', 'generateTaggedPDF'),
preferCSSPageSize: false, ...parsePageSize(options.pageSize ?? 'letter')
shouldGenerateTaggedPDF: false
}; };
if (options.landscape !== undefined) {
if (typeof options.landscape !== 'boolean') {
throw new Error('landscape must be a Boolean');
}
printSettings.landscape = options.landscape;
}
if (options.displayHeaderFooter !== undefined) {
if (typeof options.displayHeaderFooter !== 'boolean') {
throw new Error('displayHeaderFooter must be a Boolean');
}
printSettings.displayHeaderFooter = options.displayHeaderFooter;
}
if (options.printBackground !== undefined) {
if (typeof options.printBackground !== 'boolean') {
throw new Error('printBackground must be a Boolean');
}
printSettings.shouldPrintBackgrounds = options.printBackground;
}
if (options.scale !== undefined) {
if (typeof options.scale !== 'number') {
throw new Error('scale must be a Number');
}
printSettings.scale = options.scale;
}
const { pageSize } = options;
if (pageSize !== undefined) {
if (typeof pageSize === 'string') {
const format = paperFormats[pageSize.toLowerCase()];
if (!format) {
throw new Error(`Invalid pageSize ${pageSize}`);
}
printSettings.paperWidth = format.width;
printSettings.paperHeight = format.height;
} else if (typeof options.pageSize === 'object') {
if (!pageSize.height || !pageSize.width) {
throw new Error('height and width properties are required for pageSize');
}
printSettings.paperWidth = pageSize.width;
printSettings.paperHeight = pageSize.height;
} else {
throw new Error('pageSize must be a String or Object');
}
}
const { margins } = options;
if (margins !== undefined) {
if (typeof margins !== 'object') {
throw new Error('margins must be an Object');
}
if (margins.top !== undefined) {
if (typeof margins.top !== 'number') {
throw new Error('margins.top must be a Number');
}
printSettings.marginTop = margins.top;
}
if (margins.bottom !== undefined) {
if (typeof margins.bottom !== 'number') {
throw new Error('margins.bottom must be a Number');
}
printSettings.marginBottom = margins.bottom;
}
if (margins.left !== undefined) {
if (typeof margins.left !== 'number') {
throw new Error('margins.left must be a Number');
}
printSettings.marginLeft = margins.left;
}
if (margins.right !== undefined) {
if (typeof margins.right !== 'number') {
throw new Error('margins.right must be a Number');
}
printSettings.marginRight = margins.right;
}
}
if (options.pageRanges !== undefined) {
if (typeof options.pageRanges !== 'string') {
throw new Error('pageRanges must be a String');
}
printSettings.pageRanges = options.pageRanges;
}
if (options.headerTemplate !== undefined) {
if (typeof options.headerTemplate !== 'string') {
throw new Error('headerTemplate must be a String');
}
printSettings.headerTemplate = options.headerTemplate;
}
if (options.footerTemplate !== undefined) {
if (typeof options.footerTemplate !== 'string') {
throw new Error('footerTemplate must be a String');
}
printSettings.footerTemplate = options.footerTemplate;
}
if (options.preferCSSPageSize !== undefined) {
if (typeof options.preferCSSPageSize !== 'boolean') {
throw new Error('preferCSSPageSize must be a Boolean');
}
printSettings.preferCSSPageSize = options.preferCSSPageSize;
}
if (options.generateTaggedPDF !== undefined) {
if (typeof options.generateTaggedPDF !== 'boolean') {
throw new Error('generateTaggedPDF must be a Boolean');
}
printSettings.shouldGenerateTaggedPDF = options.generateTaggedPDF;
}
if (this._printToPDF) { if (this._printToPDF) {
if (pendingPromise) { if (pendingPromise) {
pendingPromise = pendingPromise.then(() => this._printToPDF(printSettings)); pendingPromise = pendingPromise.then(() => this._printToPDF(printSettings));
@@ -346,7 +254,7 @@ WebContents.prototype.printToPDF = async function (options) {
// print param logic into new file shared between printToPDF and print // print param logic into new file shared between printToPDF and print
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions, callback) { WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions, callback) {
if (typeof options !== 'object') { if (typeof options !== 'object') {
throw new Error('webContents.print(): Invalid print settings specified.'); throw new TypeError('webContents.print(): Invalid print settings specified.');
} }
const printSettings: Record<string, any> = { ...options }; const printSettings: Record<string, any> = { ...options };
@@ -361,7 +269,7 @@ WebContents.prototype.print = function (options: ElectronInternal.WebContentsPri
const height = Math.ceil(pageSize.height); const height = Math.ceil(pageSize.height);
const width = Math.ceil(pageSize.width); const width = Math.ceil(pageSize.width);
if (!isValidCustomPageSize(width, height)) { if (!isValidCustomPageSize(width, height)) {
throw new Error('height and width properties must be minimum 352 microns.'); throw new RangeError('height and width properties must be minimum 352 microns.');
} }
printSettings.mediaSize = { printSettings.mediaSize = {

View File

@@ -89,10 +89,10 @@
"lint:objc": "node ./script/lint.js --objc", "lint:objc": "node ./script/lint.js --objc",
"lint:py": "node ./script/lint.js --py", "lint:py": "node ./script/lint.js --py",
"lint:gn": "node ./script/lint.js --gn", "lint:gn": "node ./script/lint.js --gn",
"lint:docs": "remark docs -qf && npm run lint:js-in-markdown && npm run create-typescript-definitions && npm run lint:ts-check-js-in-markdown && npm run lint:docs-fiddles && npm run lint:docs-relative-links && npm run lint:markdownlint", "lint:docs": "remark docs -qf && npm run lint:js-in-markdown && npm run create-typescript-definitions && npm run lint:ts-check-js-in-markdown && npm run lint:docs-fiddles && npm run lint:docs-relative-links && npm run lint:markdown",
"lint:docs-fiddles": "standard \"docs/fiddles/**/*.js\"", "lint:docs-fiddles": "standard \"docs/fiddles/**/*.js\"",
"lint:docs-relative-links": "electron-lint-markdown-links --root docs \"**/*.md\"", "lint:docs-relative-links": "electron-lint-markdown-links --root docs \"**/*.md\"",
"lint:markdownlint": "electron-markdownlint \"*.md\" \"docs/**/*.md\"", "lint:markdown": "node ./script/lint.js --md",
"lint:ts-check-js-in-markdown": "electron-lint-markdown-ts-check --root docs \"**/*.md\" --ignore \"breaking-changes.md\"", "lint:ts-check-js-in-markdown": "electron-lint-markdown-ts-check --root docs \"**/*.md\" --ignore \"breaking-changes.md\"",
"lint:js-in-markdown": "electron-lint-markdown-standard --root docs \"**/*.md\"", "lint:js-in-markdown": "electron-lint-markdown-standard --root docs \"**/*.md\"",
"create-api-json": "node script/create-api-json.js", "create-api-json": "node script/create-api-json.js",

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