Compare commits

...

297 Commits

Author SHA1 Message Date
Electron Bot
4ad03dc60a Bump v9.0.3 2020-06-05 11:55:50 -07:00
Electron Bot
72dbe13f76 chore: bump chromium in DEPS to 83.0.4103.100 (#23986) 2020-06-05 11:09:24 -07:00
trop[bot]
e6616d62e0 fix: use acceptLanguages argument in session.setUserAgent() (#23962)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-06-05 10:11:33 -07:00
Electron Bot
aa301f76d9 chore: bump chromium in DEPS to 83.0.4103.99 (#23967) 2020-06-04 16:21:58 -04:00
trop[bot]
058e2e73bb feat: add V8CacheOptions webpreference (#23868)
* feat: add V8CacheOptions webpreference

* address review comments

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-06-04 12:08:40 -04:00
trop[bot]
59538c9b36 fix: Make the --disable-color-correct-rendering switch work again (#23900)
* fix: Make the `--disable-color-correct-rendering` switch work again

This regressed once again in Electron 8 due to Chromium changes.

Test Plan:

- Confirm that test case from https://github.com/electron/electron/pull/15898#issuecomment-443191770 now works

Notes: Fix disabling color correct rendering with `--disable-color-correct-rendering`

* update patches

Co-authored-by: Biru Mohanathas <birunthan@mohanathas.com>
Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-06-03 11:23:53 -07:00
trop[bot]
455228bed5 fix: restore original GTK/appindicator implementation of tray icons (#23926)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-06-03 11:07:37 -07:00
Electron Bot
f9d18015e0 chore: bump chromium in DEPS to 83.0.4103.98 (#23943) 2020-06-03 10:53:27 -07:00
trop[bot]
8fd0c11513 fix: correctly support the --inspect-brk-node flag (#23920)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-06-03 17:01:45 +09:00
Electron Bot
d40162e4bd chore: bump chromium to 83.0.4103.97 (9-x-y) (#23907)
* chore: bump chromium in DEPS to 83.0.4103.97

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-06-02 15:37:31 -04:00
trop[bot]
a57e7eb2e5 docs: default of allowRendererProcessReuse is true (#23913)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2020-06-02 12:02:51 -07:00
Electron Bot
12afb18487 Bump v9.0.2 2020-06-02 11:14:21 -07:00
trop[bot]
89340008ee fix: add patch to prevent crash during frame swap with ctx isolation enabled (#23895)
* fix: add patch to prevent crash during frame swap with ctx isolation enabled

* Update .patches

* chore: update patches

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2020-06-02 10:52:39 -07:00
trop[bot]
dd7c9fb55b build: make electron renderer init scripts profilable (#23892)
The devtools profiler is not attached at the point we run out init scripts (or our apps preload scripts), we do not really want to change when we run these init scripts but for when a dev is doing performance work it makes sense to give them an option to make the devtools profiler actually work on both our init scripts and their preload script.  This PR adds that logic behind an environment variable ELECTRON_PROFILE_INIT_SCRIPTS.

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-06-01 17:37:54 -07:00
trop[bot]
26c6c81540 fix: do not use CONTEXT_MENU flag for tray menu (#23880)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-06-01 12:24:29 -05:00
Electron Bot
7f769ec325 Bump v9.0.1 2020-06-01 09:32:10 -07:00
Electron Bot
32ecaae8a8 chore: bump chromium in DEPS to 83.0.4103.94 (#23875) 2020-06-01 11:13:02 -04:00
Electron Bot
7d0cc5edd8 chore: bump chromium to 83.0.4103.93 (9-x-y) (#23858)
* chore: bump chromium in DEPS to 83.0.4103.92

* chore: bump chromium in DEPS to 83.0.4103.93
2020-05-31 14:37:58 -07:00
Electron Bot
c09083b1d8 chore: bump chromium to 83.0.4103.91 (9-x-y) (#23848)
* chore: bump chromium in DEPS to 83.0.4103.91

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-05-29 15:24:23 -04:00
Shelley Vohr
718bbf137c fix: nativeImage remote serialization (#23796) 2020-05-28 13:21:28 -07:00
trop[bot]
568d38c61a fix: weakly reference MenuModel from MenuController (#23808)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-28 09:47:56 -07:00
Electron Bot
68a01398d9 chore: bump chromium in DEPS to 83.0.4103.89 (#23825) 2020-05-28 09:46:55 -07:00
trop[bot]
d0495f5fd4 fix: handle asynchronous URL loading in bw proxy (#23805)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-28 09:41:49 -07:00
Alexey Kuzmin
314cfa7aec test: refactor how spec files are collected (#23814)
(cherry picked from commit 3a7775fa73)
2020-05-28 09:41:25 -07:00
trop[bot]
ff4cc4dc16 fix: volume key globalShortcut registration (#23824)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-28 09:40:38 -07:00
trop[bot]
af1253392b fix: only bezel frameless windows (#23810)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-28 08:54:02 -04:00
Cheng Zhao
4f2699f4d9 Revert "fix: trigger activate event when app is activated via app switcher (#23773)" (#23821)
This reverts commit b5baafdab6.
2020-05-28 08:37:00 -04:00
trop[bot]
ca76da9f14 fix: pass correct buffer length (#23801)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-05-27 13:31:48 -07:00
Electron Bot
0814e72012 chore: bump chromium in DEPS to 83.0.4103.87 (#23790) 2020-05-27 08:41:01 -07:00
trop[bot]
b5baafdab6 fix: trigger activate event when app is activated via app switcher (#23773)
When application is activated thru macOS app switcher (cmd+tab) the
App's activate event is note emitted. The reason is that
`applicationShouldHandleReopen:hasVisibleWindows:` is sent only when app
is activated via Dock. Using `applicationDidBecomeActive:` is handling
all cases properly.

Co-authored-by: Lukas Weber <luweber@microsoft.com>
2020-05-27 09:52:30 +09:00
trop[bot]
0f96402c78 ci: deflake WOA tests (#23770)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-05-26 08:46:54 -07:00
Electron Bot
5d357e87b4 chore: bump chromium in DEPS to 83.0.4103.86 (#23765) 2020-05-26 08:46:19 -07:00
Electron Bot
448a645128 chore: bump chromium in DEPS to 83.0.4103.85 (#23750) 2020-05-25 12:03:40 -07:00
Electron Bot
7f1e492a68 chore: bump chromium to 83.0.4103.84 (9-x-y) (#23733)
* chore: bump chromium in DEPS to 83.0.4103.82

* chore: bump chromium in DEPS to 83.0.4103.84
2020-05-24 15:34:54 -07:00
Alexey Kuzmin
8803c12715 test: do not run spellchecker tests if the feature is disabled (9-x-y) (#23724)
* test: do not run SpellChecker tests if the features is disabled at build time

* fixup! test: do not run SpellChecker tests if the features is disabled at build time

* fixup! test: do not run SpellChecker tests if the features is disabled at build time
2020-05-23 11:05:37 -07:00
Electron Bot
98033f8520 chore: bump chromium in DEPS to 83.0.4103.81 (#23725) 2020-05-22 21:09:02 -07:00
trop[bot]
be6c102fa1 fix: trigger about panel for about role on on win (#23715)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-21 21:09:05 -04:00
trop[bot]
85aa3e9c3e fix: read GTK dark theme setting on Linux (#23712)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-05-21 20:39:29 -04:00
trop[bot]
2a5c92f534 test: multiple processes may crash in crashReporter test (#23705)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-05-21 15:41:06 -07:00
trop[bot]
525179dbfc docs: errors in isolated world are not dispatched (#23706)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-05-21 15:40:46 -07:00
Electron Bot
55c4de8723 chore: bump chromium in DEPS to 83.0.4103.77 (#23700) 2020-05-21 12:42:08 -07:00
Alexey Kuzmin
2241b146a0 test: call "expect()" on a correct call stack (#23696)
(cherry picked from commit 33d6a99d40)
2020-05-21 11:42:41 -04:00
Charles Kerr
14945be56c fix: don't run environment bootstrapper (#23689)
* chore: remove node "split CreateEnvironment" patch

* chore: remove `environment.js` from electron-node

* chore: don't call the electron-node API we removed

* fix: don't prepareMainExecution twice

* test: re-enable some node tests

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-21 11:27:34 -04:00
trop[bot]
0aa104ed9c fix: make sure hunspell file is not destroyed in UI thread (#23660)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-05-21 10:27:25 -04:00
LuoJinghua
c21c9b64e2 net: Don't ignore the referer header in net.request (#23685) 2020-05-20 20:27:27 -04:00
Electron Bot
935f5ca081 chore: bump chromium in DEPS to 83.0.4103.76 (#23679) 2020-05-20 09:41:09 -07:00
trop[bot]
a02d3c80a0 feat: add enableWebSQL webpreference (#23580)
* feat: add enableWebSQL webpreference

* chore: update indexedDB test

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-05-19 15:44:14 -04:00
Electron Bot
0b12642826 chore: bump chromium in DEPS to 83.0.4103.75 (#23657) 2020-05-19 11:18:41 -07:00
trop[bot]
011b2733d6 build: save mksnapshot args on Windows (#23641)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-05-19 09:28:40 -04:00
Milan Burda
90833d372f build: allow use of BUILDFLAG directives from within JS code (#23496) 2020-05-19 09:26:59 -04:00
trop[bot]
69a343e276 refactor: improve MoveItemToTrash error description (#23628)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-18 18:35:32 -07:00
Electron Bot
4da01641ce Bump v9.0.0 2020-05-18 14:17:08 -07:00
Charles Kerr
9d46395940 refactor: revert release notes changes (#23649)
* refactor: undo the "look harder for commit PRs" notes changes

* chore: chmod +x the notes script
2020-05-18 16:12:09 -05:00
Electron Bot
67a905c090 Revert "Bump v9.0.0"
This reverts commit dcdca6a014.
2020-05-18 13:37:51 -07:00
Electron Bot
dcdca6a014 Bump v9.0.0 2020-05-18 13:36:41 -07:00
Charles Kerr
7db9c35fa8 fix: eat octokit 422 errs when scraping commit PRs (#23643) 2020-05-18 16:33:23 -04:00
Electron Bot
5c03d05b8e Revert "Bump v9.0.0"
This reverts commit 0ac262dc2d.
2020-05-18 13:16:26 -07:00
Electron Bot
0ac262dc2d Bump v9.0.0 2020-05-18 13:04:48 -07:00
trop[bot]
4de54b412f ci: use longer mocha timeout on WOA testing (#23636)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-05-18 14:07:30 -04:00
Electron Bot
29af2312ca Revert "Bump v9.0.0-beta.25"
This reverts commit 1a4c34bb13.
2020-05-18 08:42:10 -07:00
Electron Bot
1a4c34bb13 Bump v9.0.0-beta.25 2020-05-18 08:32:13 -07:00
Electron Bot
8556eaab9b chore: bump chromium to 83.0.4103.64 (9-x-y) (#23623)
* chore: bump chromium in DEPS to 83.0.4103.61

* chore: bump chromium in DEPS to 83.0.4103.62

* chore: bump chromium in DEPS to 83.0.4103.64
2020-05-18 11:03:53 -04:00
trop[bot]
b22c44fef7 test: skip remote module related tests when enable_remote_module = false (#23568)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-05-18 10:45:38 +09:00
trop[bot]
c084b128dc fix: exclude crashpad_handler binary on linux (#23575)
* fix: exclude crashpad_handler binary on linux

* Update build/zip.py

Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
Co-authored-by: Jeremy Apthorp <jeremya@chromium.org>
2020-05-18 10:30:30 +09:00
trop[bot]
fcf50849f3 test: remove usage of the remote module from tests (#23577)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-05-18 10:29:52 +09:00
trop[bot]
9988beabb5 feat: look harder for a commit's pull request. (#23596)
PR numbers are almost always listed parenthetically in the commit message;
but when something is committed manually, it could be missing. This change
uses octokit's listPullRequestsAssociatedWithCommit() as a second approach
to finding a commit's PR.

Last night's Releases WG meeting noted that "re-enable pdf viewer" was
missing from the notes. This PR fixes that omission.

Co-authored-by: Charles Kerr <charles@charleskerr.com>
2020-05-18 10:12:09 +09:00
trop[bot]
32bc081ba5 build: remove unused header from a patch (#23590)
It can cause build failures because the header is generated
and there's no explicit dependency on a target that creates it.

Co-authored-by: Aleksei Kuzmin <alkuzmin@microsoft.com>
2020-05-17 08:53:52 -07:00
Samuel Attard
320487080f refactor: remove the RenderFrameFunctionStore and use privates to memory manage (#23592) (#23617) 2020-05-15 16:33:44 -07:00
Electron Bot
a143339d35 chore: bump chromium in DEPS to 83.0.4103.59 (#23606) 2020-05-15 12:44:33 -07:00
Electron Bot
9011d5e7fc chore: bump chromium in DEPS to 83.0.4103.57 (#23588) 2020-05-14 19:37:57 -04:00
Electron Bot
73e1fceb39 Revert "Bump v9.0.0-beta.25"
This reverts commit 3dbebcb285.
2020-05-14 09:06:05 -07:00
Electron Bot
3dbebcb285 Bump v9.0.0-beta.25 2020-05-14 08:33:20 -07:00
trop[bot]
3a51ee5ce5 fix: generate symbols for the correct crashpad handler binary (#23573)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-05-14 10:42:59 -04:00
trop[bot]
a3256facea fix: leave behind the unmodified XDG_CURRENT_DESKTOP variable (#23554)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2020-05-13 12:37:50 -04:00
Electron Bot
3698f000c2 chore: bump chromium in DEPS to 83.0.4103.56 (#23559) 2020-05-13 09:12:41 -07:00
Milan Burda
810b54854a fix: expose v8util.createIDWeakMap() regardless of enable_remote_module (#23546) (#23556) 2020-05-13 09:12:15 -07:00
trop[bot]
56e84acab9 build: use correct v8_context_snapshot_generator in mksnapshot zip (#23540)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-05-13 09:40:44 -04:00
trop[bot]
8252565979 fix: run Node.js at-exit callbacks in renderer proc (#23544)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-12 18:32:29 -07:00
trop[bot]
169c87bfc1 fix: do not destroy thread in UI thread (#23535)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-05-13 09:18:52 +09:00
trop[bot]
cded93ae8e build: fix building with enable_remote_module = false (#23533)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-05-13 09:18:41 +09:00
Electron Bot
ab34627723 chore: bump chromium in DEPS to 83.0.4103.53 (#23524) 2020-05-12 14:18:07 -07:00
trop[bot]
d313998cdb test: skip "handles Promise timeouts correctly" when ELECTRON_RUN_AS_NODE is disabled (#23500)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-05-12 09:53:04 -05:00
Electron Bot
b8460f11fa chore: bump chromium to 83.0.4103.50 (9-x-y) (#23469)
* chore: bump chromium in DEPS to 83.0.4103.46

* chore: bump chromium in DEPS to 83.0.4103.48

* chore: bump chromium in DEPS to 83.0.4103.49

* chore: bump chromium in DEPS to 83.0.4103.50

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-05-11 14:17:18 -04:00
Alexey Kuzmin
6d75e7aac6 spec: fix conditions for some tests (#23489) (#23494)
(cherry picked from commit dc3de49a08)
2020-05-11 12:08:25 -04:00
Electron Bot
8cf55a674e Bump v9.0.0-beta.24 2020-05-11 08:31:56 -07:00
Erick Zhao
4542e2eef9 docs: document supported extensions apis (#22021) (#23434)
* docs: document supported extensions apis

* Update extensions.md

* Update README.md

* Apply suggestions from code review

Co-Authored-By: Mark Lee <malept@users.noreply.github.com>

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

Co-authored-by: Jeremy Apthorp <jeremya@chromium.org>
Co-authored-by: Mark Lee <malept@users.noreply.github.com>
2020-05-11 10:49:32 +09:00
trop[bot]
5009538045 fix: do not initialize extension system in in-memory sessions (#23472)
* fix: do not initialize any extension related logic in OffTheRecord contexts

* chore: fix linting

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-05-08 12:43:07 -07:00
Jeremy Apthorp
2f8150891b fix: crashReporter incompatible with sandbox on Linux (#23265) (#23461) 2020-05-08 11:41:42 -07:00
Charles Kerr
4b9df8c248 feat: add force option to app.focus() (#22612) (#23447)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-07 12:16:24 -07:00
trop[bot]
0920d01c9c fix: multiple extension filters on macOS (#23450)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-05-07 11:57:45 -07:00
Electron Bot
520e0bcc43 chore: bump chromium in DEPS to 83.0.4103.45 (#23446) 2020-05-07 08:56:40 -07:00
Electron Bot
6be41c2f8e Bump v9.0.0-beta.23 2020-05-07 08:32:03 -07:00
Electron Bot
b997c562f7 chore: bump chromium in DEPS to 83.0.4103.44 (#23424) 2020-05-06 11:00:45 -07:00
Electron Bot
2c9fe0b951 chore: bump chromium to 83.0.4103.42 (9-x-y) (#23416)
* chore: bump chromium in DEPS to 83.0.4103.42

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-05-05 10:35:19 -07:00
Charles Kerr
4445182739 chore: remove redundant release note items. (#23408)
Backport of #23335. See that PR for details.
2020-05-05 08:38:16 -07:00
Charles Kerr
e549aec5fc fix: respect system language preferences on Win/macOS (#23247) (#23405)
This commit fixes https://github.com/electron/electron/issues/18829

Previously the full preferences set to OS was not given to Chromium.

Also, this commit improves fallback font selection for CJK text.
Chromium uses browser languages to determine fallback fonts on Windows,
especially kanji/han characters in CJK.

For instance, when user sets 'en-US, ja-JP' to Accept-Language,
while Chromium chooses Japanese font for kanji text, but Electron
chooses Chinese font.  This is because only the first language was given
to Accept-Language on Electron.

This patch is based on https://github.com/electron/electron/pull/15532

Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>

Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>

Co-authored-by: Sorah Fukumori <her@sorah.jp>
Co-authored-by: Nitish Sakhawalkar <nitsakh@icloud.com>
Co-authored-by: Kasumi Hanazuki <kasumi@rollingapple.net>
2020-05-04 19:41:17 -07:00
trop[bot]
c1311480c0 fix: guard pdf behind correct buildflags (#23406)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-05-04 19:38:24 -07:00
Shelley Vohr
6c78c9274a refactor: return null when passing empty menu templates (#23401) 2020-05-04 14:39:58 -05:00
Electron Bot
d50fb2938b chore: bump chromium to 83.0.4103.41 (9-x-y) (#23378)
* chore: bump chromium in DEPS to 83.0.4103.38

* chore: bump chromium in DEPS to 83.0.4103.39

* chore: bump chromium in DEPS to 83.0.4103.40

* chore: bump chromium in DEPS to 83.0.4103.41
2020-05-04 08:13:12 -07:00
trop[bot]
5414c8dd7e fix: hold browser_context instead of render_frame_host to fix lifetime issues (#23375)
Co-authored-by: Paul Frazee <pfrazee@gmail.com>
2020-05-03 16:19:52 -07:00
trop[bot]
ee68e1a787 fix: ensure guest-embedder map is updated when webview is removed (#23374)
There are use cases of webview where the container holding the webview is not
actually destroyed first, instead just webview gets removed from DOM, in such
situations the browser process map is not updated accordingly and holds reference
to stale guest contents, and any window operations like scroll, resize or keyboard
events that has to chain through browser embedder will lead to UAF crash.

Ref: https://github.com/microsoft/vscode/issues/92420

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-05-01 12:32:35 -07:00
Charles Kerr
e3d4f999ca fix: undo and redo broken in webviews (#23370)
* fix: undo and redo broken in webviews

Backport upstream fix https://chromium-review.googlesource.com/c/chromium/src/+/2135187 to 9-x-y.

* chore: re-run git-export-patches to refresh patch
2020-04-30 17:18:27 -05:00
trop[bot]
b62df312f2 docs: event.newGuest for new-window in WebContents and webContents in BrowsweWindow's constructor (#23356)
* docs: `newGuest` in `WebContents` and `webContents` in `BrowsweWindow`

According to the example codes in the documentation of `new-window`
event in `WebContents`, `webContents` in `BrowsweWindow` constructor
options and `newGuest` in `event` argument of `new-window` handler are
both existing but documented. This patch is for adding the related
documentations. Also, it provides typescript-definitations for these
two properties.

* Remove the documnent of `webContents` in BrowserWindow constructor option.

Co-authored-by: Sean Lee <sean.l@canva.com>
2020-04-30 15:42:14 -05:00
trop[bot]
9ba491116c ci: make sure msedge isn't running at end of woa test (#23361)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-04-30 14:14:20 -04:00
Electron Bot
c74dd6eee7 chore: bump chromium in DEPS to 83.0.4103.36 (#23348) 2020-04-30 11:02:09 -07:00
Electron Bot
2d888dc7b5 Bump v9.0.0-beta.22 2020-04-30 08:33:00 -07:00
trop[bot]
1024544573 fix: do not leak IPC or context bridge promises (#23338)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-04-29 17:23:25 -07:00
trop[bot]
ebbd3081b9 fix: build when some buildflags are disabled (#23337)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2020-04-29 16:09:42 -07:00
trop[bot]
dc3dc81beb feat: support fullScreen BrowserWindow property (#23330)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-29 12:16:11 -07:00
Electron Bot
6babb8a9fe chore: bump chromium in DEPS to 83.0.4103.34 (#23326) 2020-04-29 14:06:23 -04:00
trop[bot]
088e23d604 menu-item.md remove duplicate options (#23296)
Co-authored-by: szTheory <szTheory@users.noreply.github.com>
2020-04-28 23:17:11 -07:00
Electron Bot
d0a764bd16 chore: bump chromium to 83.0.4103.31 (9-x-y) (#23270)
* chore: bump chromium in DEPS to 83.0.4103.27

* chore: bump chromium in DEPS to 83.0.4103.28

* chore: bump chromium in DEPS to 83.0.4103.29

* chore: bump chromium in DEPS to 83.0.4103.30

* chore: bump chromium in DEPS to 83.0.4103.31

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-04-28 17:20:24 -07:00
Electron Bot
d47b788e03 Bump v9.0.0-beta.21 2020-04-27 18:23:30 -07:00
Samuel Attard
a985865f65 refactor: port window-setup to use ctx bridge instead of being run in the main world (#23299)
* refactor: port parts of window-setup to use ctx bridge instead of being run in the main world (#23194)

* refactor: port parts of window-setup to use ctx bridge instead of being run in the main world

* chore: update ctx bridge specs for new base numbers

* refactor: port window.open and window.opener to use ctx bridge instead of hole punching (#23235)

* refactor: port window.open and window.opener to use ctx bridge instead of hole punching

* refactor: only run the isolated init bundle when webview is enabled
2020-04-27 14:42:14 -07:00
trop[bot]
729019b974 style: use build/include_directory for NOLINT (#23300)
build/include linter was splitted to build/include_directory at
depot_tools upstream.

https://crrev.com/c/2159690
https://crbug.com/1073191

Co-authored-by: Sorah Fukumori <her@sorah.jp>
2020-04-27 13:28:41 -07:00
Electron Bot
e83d6be20c Bump v9.0.0-beta.20 2020-04-27 08:58:50 -07:00
trop[bot]
69eddfb2f9 fix: set default menu in will-finish-launching event (#23263)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-04-24 20:43:46 +09:00
Electron Bot
71c3c2b65e chore: bump chromium in DEPS to 83.0.4103.26 (#23256) 2020-04-23 14:03:37 -04:00
trop[bot]
cf230bc709 ci: robustify doc only change check (#23259)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-04-23 10:54:46 -07:00
Charles Kerr
6d3a6ce307 docs: minor grammar & spelling fixes (#22851) (#23262) 2020-04-23 10:52:51 -07:00
Charles Kerr
3d8b2af151 refactor: precache the IsWindowStateEvent() XAtom (#22706) (#23260)
* refactor: precache the IsWindowStateEvent() atom

XAtoms never change after creation so we can perload the atoms we need.
This is useful in WindowStateWatcher's XEvent handler, which is called
on every XEvent, e.g. mouse movement...

* empty commit for ci
2020-04-23 10:50:09 -07:00
shelley vohr
45174dfc19 feat: add property support for remainder of BrowserWindow (#23208)
Adds property-based support for the remainder of primitive getter/setter pairs on `BrowserWindow`.

Namely:
- `win.simpleFullScreen`
- `win.title`
- `win.visibleOnAllWorkspaces`
- `win.documentEdited`
- `win.representedFilename`
- `win.shadow`
- `win.kiosk`
- `win.menuBarVisible`
2020-04-23 10:34:20 -07:00
Electron Bot
5bdb5b821b Bump v9.0.0-beta.19 2020-04-23 08:32:16 -07:00
Samuel Attard
0cce079c8f fix: do not mutate ipc instances across contexts (#23238) 2020-04-22 17:11:37 -07:00
Samuel Attard
0c67a1de8c fix: do not allow child windows to specify their own preload script (#23227) 2020-04-22 17:07:22 -07:00
trop[bot]
963ef4dbe7 fix: block custom window.open when nativeWindowOpen is true (#23222)
* fix: block custom window.open when nativeWindowOpen is true

* Update guest-window-manager.js

Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
Co-authored-by: Jeremy Apthorp <jeremya@chromium.org>
2020-04-22 17:07:10 -07:00
trop[bot]
e559af3616 fix: cherry-pick 04dab5a91b61 from chromium (#23190)
* Make HitTestResult::LocalPoint() for inline element as same as legacy layout

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

* update patches

* update patches

Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-04-22 13:30:49 -04:00
trop[bot]
ed2bc5a4aa fix: ensure that functions are not retained beyond their context being released (#23209)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-04-22 09:09:18 -07:00
Electron Bot
edb22be8d4 chore: bump chromium in DEPS to 83.0.4103.24 (#23218) 2020-04-22 10:37:18 -04:00
Charles Kerr
74d391baae fix: use Node's microtasks policy in node_main.cc (#23154)
Fixes #21515.
2020-04-21 13:42:59 -07:00
Electron Bot
b35a98ce2a chore: bump chromium in DEPS to 83.0.4103.21 (#23198) 2020-04-21 13:48:07 -04:00
trop[bot]
9bc01adbd5 spec: fix type errors in devToolsWebContents (#23189)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-20 20:22:35 -07:00
Electron Bot
af43d065d2 chore: bump chromium to 83.0.4103.20 (9-x-y) (#23155)
* chore: bump chromium in DEPS to 83.0.4103.17

* chore: bump chromium in DEPS to 83.0.4103.18

* chore: bump chromium in DEPS to 83.0.4103.19

* chore: bump chromium in DEPS to 83.0.4103.20
2020-04-20 12:02:42 -07:00
Shelley Vohr
6f4412a317 fix: wasm codegen in script.runInNewContext (#23146) 2020-04-20 15:01:30 -04:00
trop[bot]
f0a34a2f91 docs: fix devToolsWebContents union type (#23170)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-20 11:35:57 -07:00
Shelley Vohr
30e68263ed fix: print from PDF viewer not working (#23173) 2020-04-20 11:32:28 -07:00
Electron Bot
73a6d507a7 Bump v9.0.0-beta.18 2020-04-20 08:32:24 -07:00
trop[bot]
ff6e411973 fix: don't assign NSAlert to window which is not visible (#23090) 2020-04-16 20:25:47 -07:00
Electron Bot
fe5af34acc chore: bump chromium to 83.0.4103.16 (9-x-y) (#23121) 2020-04-16 14:17:12 -07:00
Electron Bot
cd359127c9 Bump v9.0.0-beta.17 2020-04-16 14:15:56 -07:00
Samuel Attard
248beeb7a5 Merge pull request from GHSA-h9jc-284h-533g 2020-04-16 14:10:18 -07:00
Samuel Attard
bb2773bf66 Revert "Bump v9.0.0-beta.17"
This reverts commit 27367fb553.
2020-04-16 14:06:24 -07:00
trop[bot]
914a8d02b4 docs: explain the swipe event on macOS (#23135)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-16 10:55:25 -07:00
Electron Bot
27367fb553 Bump v9.0.0-beta.17 2020-04-16 08:31:59 -07:00
Electron Bot
f193d9a34f chore: bump chromium to 83.0.4103.14 (9-x-y) (#23095)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-04-14 17:14:59 -07:00
trop[bot]
bcb7fbd9c5 build: improve patch filename remembering (#23092)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-04-13 14:59:31 -07:00
Electron Bot
9762f6e7fd Bump v9.0.0-beta.16 2020-04-13 08:32:34 -07:00
trop[bot]
aef7986c64 fix: persist maximizable state when toggling fullscreen (#23021)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-10 09:40:26 -07:00
trop[bot]
82b65dcca7 fix: reset node env earlier during shutdown (#23068)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-04-10 09:37:04 -07:00
Eryk Rakowski
afeda19d15 fix(extensions): add more properties to port.sender.tab (#23008) 2020-04-09 12:21:03 -07:00
Electron Bot
1c791f9056 Bump v9.0.0-beta.15 2020-04-09 08:33:07 -07:00
Jeremy Apthorp
359110a651 ci: auto-3way patches and detect changes (#23031)
* ci: auto-3way patches and detect changes (#22976)

* bust cache

* update-index || true

* update patches

* lint

* idk what is up with lint

* idek

* update patches

Co-authored-by: Electron Bot <anonymous@electronjs.org>
2020-04-09 11:06:57 -04:00
Jeremy Apthorp
7894ae9c01 chore: bump chromium to 83.0.4102.3 (#22941)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Andy Locascio <andy@slack-corp.com>
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-04-08 14:37:31 -07:00
trop[bot]
ab41460616 fix: nullptr check when closing windows (#23023) 2020-04-07 22:10:28 -07:00
trop[bot]
8a4d41cd46 build: set merge=union for .patches (#22991)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-04-07 09:55:17 -07:00
trop[bot]
41f33edd9e fix: webframe crashes for removed render frame (#22949)
* fix: webframe crashes for removed render frame

* Make errors more descriptive

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-04-06 11:38:44 -07:00
Electron Bot
21f78af43f Bump v9.0.0-beta.14 2020-04-06 08:32:24 -07:00
Electron Bot
c09bfb5a79 chore: bump chromium in DEPS to 82.0.4085.27 (#22932) 2020-04-02 17:53:33 -07:00
Electron Bot
fb5871ccf0 Bump v9.0.0-beta.13 2020-04-02 08:31:38 -07:00
Cheng Zhao
f255d47073 fix: webRequest module should work with file:// protocol (9-x-y) (#22919)
* fix: webRequest module should work with file:// protocol

* test: do not trigger unhandled promise rejections
2020-04-01 13:36:24 -07:00
trop[bot]
050844dc38 fix: screen module should still be creatable if the first create is before the ready event (#22912)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-04-01 11:37:12 -07:00
trop[bot]
317f1a3d3a fix: ensure standard schemes are registered in nw service process (#22917)
* fix: ensure standard schemes are registered in nw service process

Refs https://github.com/electron/electron/pull/20546

* chore: add test

* chore: apply suggestions from code review

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

Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Jeremy Apthorp <jeremya@chromium.org>
2020-03-31 21:25:45 -07:00
trop[bot]
b4675ce0ae fix: dialog fails to show after modal close (#22890)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-03-31 14:50:11 -07:00
trop[bot]
3f6227c61a fix: propagate preferred color scheme to the renderer (#22900)
* fix: do not crash if the window is closed syncronously with a nativeTheme change

* fix: propogate preferred color scheme to the renderer and keep it up to date

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-03-31 14:46:15 -07:00
Electron Bot
bfc069e5c0 Bump v9.0.0-beta.12 2020-03-30 08:32:46 -07:00
trop[bot]
6cb495034e fix: don't try to hide host which has set flag disable_hidden_ (#22852)
Lack of this change will lead to freeze after call to hide/show
on window which has set flag disable_hidden_. To reproduce the
problem it's necessary to create some number of windows (how many
it depends on number of windows being cached by Chromium's
FrameEvictionManager).

Co-authored-by: Cezary Kulakowski <cezary@openfin.co>
2020-03-27 11:42:20 -07:00
trop[bot]
6d2cf47797 fix: heap-use-after-free in tray.popUpContextMenu (#22855)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-03-27 15:34:18 +09:00
Electron Bot
e06880a90e Bump v9.0.0-beta.11 2020-03-26 08:32:00 -07:00
trop[bot]
0600420bac fix: don't allow window to go behind menu bar on mac (#22828)
Co-authored-by: Cezary Kulakowski <cezary@openfin.co>
2020-03-25 10:45:32 -05:00
trop[bot]
a6ff42c190 fix: workaround for hang when preventDefault-ing nativeWindowOpen (#22750)
* fix: enable workaround for nativeWindowOpen hang

* add test

* test: ensure window doesn't leak into other test

* update to use new webcontents delegate methods

Co-authored-by: Andy Locascio <andy@slack-corp.com>
2020-03-25 10:40:12 +09:00
trop[bot]
969579070f refactor: migrate base::ThreadPool() as trait to base::ThreadPool:: API (#22607) 2020-03-24 15:09:28 -07:00
trop[bot]
9ee656f856 build: fix missing pdf dep in chromium_src (#22814)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-03-24 09:00:51 -04:00
Samuel Attard
7e4475cf51 Revert "fix: better window hierarchy checks"
This reverts commit 792fe833d1.
2020-03-23 19:35:21 -07:00
Samuel Attard
79d9bd3a29 Revert "Bump v9.0.0-beta.11"
This reverts commit 50debf8595.
2020-03-23 19:35:12 -07:00
Electron Bot
50debf8595 Bump v9.0.0-beta.11 2020-03-23 15:30:19 -07:00
Electron Bot
2d68a4d2ee Revert "Bump v9.0.0-beta.11"
This reverts commit 6ce0062c0e.
2020-03-23 15:25:54 -07:00
Electron Bot
6ce0062c0e Bump v9.0.0-beta.11 2020-03-23 14:27:00 -07:00
Samuel Attard
86aa0dfc45 build: fix beta version bumper logic for betas beyond 10 2020-03-23 14:25:54 -07:00
Samuel Attard
792fe833d1 fix: better window hierarchy checks 2020-03-23 14:13:00 -07:00
Samuel Attard
9b14ae770d feat: add support for net requests to use the session cookie store (#22806)
* chore: refactor all the net specs to be async with better error handling (#22731)

* chore: fix net specs when rerunning locally (#22745)

* feat: add support for net requests to use the session cookie store (#22704)

* fix: allow net requests to use Same-Site cookies (#22788)
2020-03-23 10:53:40 -07:00
Samuel Attard
5a34ad4e21 build: enable JS semicolons (#22785) 2020-03-23 09:18:28 -07:00
Eryk Rakowski
edd7e97dd9 feat(extensions): add more properties to extension object (#22595) 2020-03-21 10:28:05 +09:00
Electron Bot
b92734d912 chore: bump chromium to 82.0.4085.14 (9-x-y) (#22743) 2020-03-20 15:58:36 -07:00
Shelley Vohr
dc25ad2ef0 chore: update app module property support (#22747) 2020-03-20 16:09:47 +09:00
Charles Kerr
54a8258c1c refactor: omit duplicates from app's x11 icon list (#22736) 2020-03-19 14:12:07 -07:00
trop[bot]
02eff88e1b chore: revert deprecated WebContents properties (#22682) 2020-03-19 14:11:41 -07:00
trop[bot]
09ca564bf4 fix: prevent crash in ListValue v8 converter when conversion fails (#22759) 2020-03-19 14:02:31 -07:00
trop[bot]
54e31956f8 chore: more modules to dual prop/fn support (#22734) 2020-03-19 09:27:39 -07:00
Electron Bot
c6539f0d01 Bump v9.0.0-beta.10 2020-03-19 08:31:11 -07:00
trop[bot]
bef8448393 build: auto-generate the codesigning cert used for macOS CI testing runs (#22762)
* build: auto-generate the codesigning cert used for macOS CI testing runs

* build: give the cert ALL the trust values

* chore: also import public key

* idek

Co-authored-by: Samuel Attard <sattard@slack-corp.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-03-19 16:34:57 +09:00
trop[bot]
27619e8ab0 test: no need to loadURL in menu test (#22765)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-03-19 16:33:57 +09:00
trop[bot]
89c23f313f fix: crash when destroying WebContentsView during GC (#22764)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-03-19 16:33:22 +09:00
Cheng Zhao
a9b9016b99 fix: avoid double-free in TrackableObject (#22768) 2020-03-19 16:32:46 +09:00
trop[bot]
f1c1542958 chore: support props/fns for BrowserWindow (#22733) 2020-03-18 19:53:11 -07:00
Сковорода Никита Андреевич
cb90ef47bb feat: add disableDialogs option to WebPreferences (#22664)
Allows to disable dialogs completely in a similar way of how safeDialogs option can be used. Overrides safeDialogs option.
2020-03-18 20:02:29 -04:00
trop[bot]
a345fe2b4f fix: persist maximizable state through theme change (#22724)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-03-18 09:39:00 +09:00
trop[bot]
0cf02dd78b fix: remove bad usages of for-in and guard against it (#22727)
* fix: remove bad usages of for-in and guard against it

* Apply suggestions from code review

Co-Authored-By: Samuel Maddock <samuel.maddock@gmail.com>

* Apply suggestions from code review

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

* Update remote.js

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>
Co-authored-by: Jeremy Apthorp <jeremya@chromium.org>
2020-03-18 09:38:26 +09:00
Electron Bot
3d941fc464 chore: bump chromium to 82.0.4085.10 (9-x-y) (#22506)
* chore: bump chromium in DEPS to 82.0.4076.1

* update patches

* chore: bump chromium in DEPS to 82.0.4077.1

* update v8 patches

* Remove deprecated wasm module type check

https://chromium-review.googlesource.com/c/v8/v8/+/2033170

* chore: bump chromium in DEPS to 82.0.4078.0

* chore: bump chromium in DEPS to 82.0.4079.0

* chore: bump chromium in DEPS to 82.0.4080.0

* chore: bump chromium in DEPS to 82.0.4080.1

* chore: bump chromium in DEPS to 82.0.4081.2

* Update patches

* chore: bump chromium in DEPS to 82.0.4082.1

* Remove cursor_types.h in favor of cursor_type.mojom

https://chromium-review.googlesource.com/c/chromium/src/+/2052103
(cherry picked from commit 3b6e4d4a1a)

* Refactor extensions report in management disclosure page

https://chromium-review.googlesource.com/c/chromium/src/+/2038774
(cherry picked from commit b2ae06307d)

* Rename an old referrer policy value

https://chromium-review.googlesource.com/c/chromium/src/+/2082856
(cherry picked from commit 3cb8af2515)

* Fixup compiler errors

* Move GLHelper to gpu::

https://chromium-review.googlesource.com/c/chromium/src/+/2023282
(cherry picked from commit ea8e347088)

* [api] Remove deprecated wasm module type check

https://chromium-review.googlesource.com/c/v8/v8/+/2033170
(cherry picked from commit 937988e6ce)

* Replace blink::WebCursorInfo with ui::Cursor

https://chromium-review.googlesource.com/c/chromium/src/+/1997138
(cherry picked from commit 3e348c4d59)

* DownloadURLParameters: Remove NetworkIsolationKey parameter.

https://chromium-review.googlesource.com/c/chromium/src/+/2050987
(cherry picked from commit 9b4aae745e)

* Convert FrameHostMsg_UpdateFaviconURL to mojo

https://chromium-review.googlesource.com/c/chromium/src/+/2043181
(cherry picked from commit 11b9c27eee)

* Merge ui::ContextFactoryPrivate with ui::ContextFactory

https://chromium-review.googlesource.com/c/chromium/src/+/2047728
(cherry picked from commit 176876f243)

* fix pdf viewer tests by binding more mojo things

(cherry picked from commit 74def418df)

* chore: bump chromium in DEPS to 82.0.4083.1

* Update electron_swiftshader_binaries deps

https://chromium-review.googlesource.com/c/chromium/src/+/2056931
(cherry picked from commit 312f11129f)

* Update patches

* Use Promise with RequestPointerLock calls

https://chromium-review.googlesource.com/c/chromium/src/+/2069199
(cherry picked from commit 34350db4bd)

* chore: bump chromium in DEPS to 82.0.4084.1

* Replace content::CursorInfo with ui::Cursor

https://chromium-review.googlesource.com/c/chromium/src/+/1999201
(cherry picked from commit 6b3b850692)

* Convert MaterialDesignController to a true singleton.

https://chromium-review.googlesource.com/c/chromium/src/+/2090877
(cherry picked from commit 21ced9206d)

* Drop WebContentsView::RenderViewCreated hook

https://chromium-review.googlesource.com/c/chromium/src/+/2093535
(cherry picked from commit 9ff4e65053)

* Update patches

* Splitting context_menu_params.h into separate browser VS common parts.

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

* Fix DCHECK on OnThemeChanged()

https://chromium-review.googlesource.com/c/chromium/src/+/2090713
(cherry picked from commit fcec5f74d1)

* chore: bump chromium in DEPS to 82.0.4085.1

* chore: bump chromium in DEPS to 82.0.4085.5

* chore: bump chromium in DEPS to 82.0.4085.7

* chore: bump chromium in DEPS to 82.0.4085.9

* Add debugging for TAB tests

* update patches

* fix: add patch to fix linux arm build (#22523)


(cherry picked from commit 479354e721)

* chore: bump chromium in DEPS to 82.0.4085.10

* Check PointerLock requests for new options and update accordingly

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

* Update for changes from master roller review

* FIXME: skip Menu.setApplicationMenu(null) test

(cherry picked from commit 305f167889)

* Revert "Add debugging for TAB tests"

This reverts commit af393c1b0b.

Co-authored-by: Jeremy Apthorp <jeremya@chromium.org>
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2020-03-17 16:56:25 -04:00
Erick Zhao
d32e1f8d97 fix: prevent in-memory sessions from writing to custom spellchecker dictionary (#22157) (#22683)
* fix: prevent in-memory sessions from writing to custom dictionary

* docs

* spec
2020-03-17 10:50:00 -05:00
Shelley Vohr
b798e1ff54 fix: crash on invalid zoomFactor (#22708) 2020-03-17 10:43:06 -05:00
Electron Bot
bcb1d529ff Bump v9.0.0-beta.9 2020-03-16 08:31:53 -07:00
trop[bot]
e217a9416a fix: when building with enable_pepper_flash = false (#22692)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-03-15 11:59:34 -07:00
Erick Zhao
4be52b8f78 test: add specs for custom dictionary API (#22681) 2020-03-13 14:53:37 -04:00
Electron Bot
2bc7aaf2ef Bump v9.0.0-beta.8 2020-03-12 08:32:27 -07:00
Erick Zhao
1114954cbf fix: guard against duplicate TouchBarItem IDs (#22644) 2020-03-12 10:48:17 +09:00
trop[bot]
a76ea622b9 build: fix broken Views build (#22642)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-03-11 16:00:55 +09:00
trop[bot]
7ee7890fd8 test: test setPath for errors thrown (#22639)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-03-10 10:03:36 -07:00
trop[bot]
851ed7a6e7 fix: when building with enable_pdf_viewer = false (#22631)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2020-03-10 10:54:07 -04:00
loc
16c4d6e487 fix: port CL that fixes ARIA tree impl for macOS (#22421) 2020-03-10 19:53:39 +09:00
trop[bot]
56c0ba138b chore: don't delete nightly tag after draft (#22624)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-03-10 17:04:34 +09:00
Alexey Kuzmin
1883edd869 build: fix build without built-in spellchecker (#22610)
(cherry picked from commit 385d778a8b4e97c1cffa8f31efcf9748e82e3d94)
2020-03-10 16:59:39 +09:00
trop[bot]
9b5f2159a2 build: upload sentry src bundles to symbol S3 bucket (#22617)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2020-03-09 16:24:44 -07:00
Samuel Maddock
60f16eaf95 fix: disallow loading extensions in temp sessions (#22090) (#22571)
Co-authored-by: Jeremy Apthorp <jeremya@chromium.org>
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-03-09 11:33:23 -07:00
Electron Bot
0f08c6c874 Bump v9.0.0-beta.7 2020-03-09 08:31:47 -07:00
trop[bot]
e227578ae0 optional typically sync callback for WebFrame#executeJavaScript* (#22501)
Co-authored-by: bughit <bughit@users.noreply.github.com>
2020-03-06 19:07:46 +09:00
trop[bot]
f413cda758 feat(extensions): add chrome.tabs.connect API (#22549)
* feat(extensions): add chrome.tabs.connect API

* test(extensions): verify that chrome.tabs.connect port communication works

Co-authored-by: samuelmaddock <samuel.maddock@gmail.com>
2020-03-06 19:06:40 +09:00
trop[bot]
c41b543842 feat: add events for spellcheck dictionary downloads (#22556)
Co-authored-by: Samuel Attard <sattard@slack-corp.com>
2020-03-06 19:04:52 +09:00
trop[bot]
7bb430dc44 docs: clean up dark mode related docs (#22562)
* docs: clean up systemPreferences.effectiveAppearance text

* Grammar fixes
* Add links for Electron Packager & Electron Forge
* Update Packager API links, given https://github.com/electron/electron-packager/pull/1131

* docs: clean up Dark Mode guide

* Grammar fixes
* Add links for Electron Packager & Electron Forge

* docs: adjust based on Electron 8 using 10.14 SDK

Co-authored-by: Mark Lee <electronjs@lazymalevolence.com>
2020-03-06 19:04:31 +09:00
Samuel Maddock
231f5af1a1 feat(extensions): add chrome.i18n API (#22570)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>

Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-03-06 19:03:38 +09:00
Samuel Attard
539ca773de feat: programmatically modify traffic light positioning (#22533) (#22566)
* setter

* getter

* specs and docs

* fixup

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

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-03-05 16:59:00 -08:00
Samuel Attard
1fc197bedb fix: allow persistent media salts (#22386) (#22567)
* fix: allow persistent media salts

* chore: add regression test for persistent media device ids across reloads

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-03-05 16:58:39 -08:00
Samuel Attard
926bea232d fix: reposition traffic lights on theme change (#22560)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-03-05 14:02:23 -08:00
Electron Bot
db664f3433 Bump v9.0.0-beta.6 2020-03-05 07:31:44 -08:00
Cheng Zhao
9ec73a3dcf fix: destroy node platform after destroying wrappers (#22535)
Co-authored-by: Cheng Zhao <zcbenz@electronjs.org>
2020-03-05 13:07:48 +09:00
Samuel Attard
c1c1ac2b2e fix: disable contextBridge object identity caching (#22525)
* fix: disable contextBridge object identity caching

* cleanup

* chore: make non-const references raw pointers

* fix: zero-param constructors are not explicit

* refactor: use base::LinkedList

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-03-04 16:54:05 -08:00
trop[bot]
9c931136d0 fix: do not reposition traffic lights when fullscreened (#22509)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-03-04 20:08:43 +09:00
trop[bot]
f01ee72ea5 fix: properly forward properties to webview (#22511)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-03-04 20:08:19 +09:00
trop[bot]
f6b4c39195 fix: bail early if no printers on the network (#22519)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-03-04 16:19:37 +09:00
Cheng Zhao
578f59532d chore: remove unneeded header (#22520) 2020-03-04 12:31:46 +09:00
trop[bot]
dcf9e4b2dd docs: add documentation on case insensitive dictionary hosting (#22487)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-03-03 14:30:30 -08:00
Shelley Vohr
2021f25453 chore: ensure correct scopes are in place (#22479) 2020-03-03 11:30:52 +09:00
John Kleinschmidt
faee8a092d fix: revive offscreen rendering support (#22160) (#22425)
(cherry picked from commit 36f982aee2)

Co-authored-by: Andy Dill <andy@discordapp.com>
2020-03-02 20:17:48 -05:00
Erick Zhao
3d65d84193 feat: add session.removeWordFromSpellCheckerDictionary API (#22368)
* feat: add session.removeWordFromSpellCheckerDictionary API

* rebase fixup
2020-03-02 14:46:19 -08:00
Jeremy Apthorp
5e05df9f71 chore: update chromium to 82.0.4058.2 (#22198)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: loc <andy@slack-corp.com>
Co-authored-by: Robo <hop2deep@gmail.com>
2020-03-02 11:21:22 -08:00
Electron Bot
df2d03fe9b Bump v9.0.0-beta.5 2020-03-02 07:31:48 -08:00
trop[bot]
80967287ad fix: make webRequest work for CORS preflight requests (#22468)
* fix: support CORS preflight

* test: webRequest should work for CORS requests

Co-authored-by: Cheng Zhao <zcbenz@electronjs.org>
2020-03-02 20:25:28 +09:00
trop[bot]
2855f1d237 fix: do not call close on sheets themselves (#22445)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-03-02 16:50:22 +09:00
trop[bot]
5e25649e77 fix: Add ContentsView to AXChildren (#22469)
Co-authored-by: Felix Rieseberg <felix@felixrieseberg.com>
2020-03-02 16:28:38 +09:00
trop[bot]
3e90e523eb fix: add patch to set the base download URL rather than override it completely (#22385)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-02-28 17:00:44 -08:00
trop[bot]
c702aec1f8 fix: dictionaries download path should be in userdata (#22447)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-02-28 17:00:15 -08:00
Electron Bot
ede40f260e Bump v9.0.0-beta.4 2020-02-27 16:37:59 -08:00
Samuel Attard
ca53cc8380 fix: backport v8 patch for type inference issue (#22426) 2020-02-27 12:48:23 -08:00
Samuel Attard
7ec9b4e252 feat: set app.enableRendererProcessReuse to true by default (#22336) (#22401)
* feat: set app.enableRendererProcessReuse to true by default

* chore: add context aware info to breaking changes doc

* spec: fix nodeIntegration in child windows test for rendererprocessreuse

* spec: fix remote listeners in destroyed renderers spec as the error is now async

* Update api-browser-window-spec.ts

* chore: deprecate affinity

* chore: fix docs

* spec: handle tests crashing without an exist code

* spec: update tests for new rendererprocessreuse default

* spec: with renderer process re-use we get to destroy less views
2020-02-27 12:19:31 -08:00
trop[bot]
0d7e13d2a6 feat: add API for receiving logs from service workers (#22313)
* feat: add API for receiving logs from service workers

* feat: add new serviceWorkerContext APIs

* chore: add missing #include's

* refactor: rename serviceWorkerContext to serviceWorkers

* chore: clean up based on review

* chore: remove native_mate

* chore: add tests for the service worker module

* Update spec-main/api-service-workers-spec.ts

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

* chore: fix linting

* chore: handle renames

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-02-27 11:02:31 -08:00
Electron Bot
a5c56684b9 Revert "Bump v9.0.0-beta.4"
This reverts commit 68d96459c3.
2020-02-27 10:01:45 -08:00
Electron Bot
68d96459c3 Bump v9.0.0-beta.4 2020-02-27 09:14:14 -08:00
trop[bot]
6cf4757019 docs: improve documentation on spellchecker download URL (#22402)
* docs: improve documentation on spellchecker download URL

* Update session.md

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-02-26 23:09:43 -08:00
trop[bot]
6e80d6fba5 fix: pass safeDialogs preference properly (#22378)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-02-26 13:34:42 -08:00
trop[bot]
ec07954d5d test: disable clipboard tests for WOA (#22387)
Co-authored-by: Cheng Zhao <zcbenz@github.com>
2020-02-26 18:04:32 +09:00
Electron Bot
7fd2d39f72 Bump v9.0.0-beta.3 2020-02-25 14:03:20 -08:00
trop[bot]
64880c75a3 fix: emit will-navigate for sandboxed contents (#22327)
* fix: emit will-navigate for sandboxed contents

* uncomment test

* more tests

* use ShouldFork instead of browser_handles_all_top_level_requests

* forward post data in OpenURLFromTab

* align OpenURLFromTab with chrome's version (browser_navigator.cc/LoadURLInContents)

* add tests for navigating from file: and about:blank to http:

Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-02-25 11:11:33 +09:00
trop[bot]
cc94689db1 chore: allow custom node-spec-runner options (#22331)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-02-25 11:10:02 +09:00
trop[bot]
806e483049 fix(extensions): set lowest isolated world id (#22355)
* fix(extensions): set lowest isolated world id

* refactor: move world IDs into separate header file

Several files are including electron_render_frame_observer.h just for the world IDs.

Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>
2020-02-25 11:01:30 +09:00
Jeremy Apthorp
8129e92d2b refactor: saner blink_initialization_order.patch (#22054) (#22366) 2020-02-24 13:19:33 -08:00
trop[bot]
660706ba2c fix: disable remote layer APIs in MAS build (#22354)
* fix: add patch to disable remote layer APIs

* fix: use --disable-gpu-memory-buffer-compositor-resources for MAS build

Co-authored-by: Cheng Zhao <zcbenz@github.com>
2020-02-24 19:29:15 +09:00
trop[bot]
2feca9d35a fix: revert {Atom => Electron}Application rename (#22325)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-02-24 12:29:10 +09:00
trop[bot]
3a4118703a docs: clean up protocol docs (#22308)
* docs: clean up protocol docs

* Fix capitalization

Co-authored-by: Mark Lee <malept@users.noreply.github.com>
2020-02-24 12:28:29 +09:00
Jeremy Apthorp
bd669f72ee feat: [extensions] support extension.getBackgroundPage (#21951) (#22177) 2020-02-21 14:33:28 -08:00
trop[bot]
1f3c3eee83 fix: typo in crash reporter constructor (#22322) 2020-02-21 17:50:32 +00:00
trop[bot]
6e84ebee8e chore: remove libcc from release not generator (#22294)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-02-20 10:17:41 -05:00
trop[bot]
f22376ef32 fix: add patch to route mouse event navigations through the WebContentsDelegate (#22204)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-02-19 13:46:15 +09:00
trop[bot]
324b49a5eb doc: remove accidental deprecation (#22264)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2020-02-19 13:44:45 +09:00
John Kleinschmidt
0e9727e8d5 ci: enable goma for all testing builds (#21992) (#22203)
(cherry picked from commit e7982623ec)
2020-02-18 12:03:33 -05:00
trop[bot]
44ee90e5cf fix: don't include breakpad_symbols dir in dsym.zip (#22221)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-02-18 11:57:33 -05:00
Electron Bot
2b9ef75d82 Bump v9.0.0-beta.2 2020-02-15 16:07:17 -08:00
John Kleinschmidt
4dc2b4d55f Revert "Bump v9.0.0-beta.2"
This reverts commit 69f77d309d.
2020-02-14 16:50:33 -05:00
Electron Bot
69f77d309d Bump v9.0.0-beta.2 2020-02-14 12:39:21 -08:00
John Kleinschmidt
9cd1744a2b Revert "Bump v9.0.0-beta.2"
This reverts commit 8b11adc6f2.
2020-02-14 15:37:16 -05:00
trop[bot]
c6e411173e build: fix release script to work with sudowoodo (#22200)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-02-14 15:35:10 -05:00
Electron Bot
8b11adc6f2 Bump v9.0.0-beta.2 2020-02-14 12:29:44 -08:00
trop[bot]
57ec30e459 feat: add session.listWordsFromSpellCheckerDictionary API (#22128)
* doesn't work yet but compiles.

* works

* fixup

Co-authored-by: Erick Zhao <erick@hotmail.ca>
2020-02-14 15:26:17 -05:00
trop[bot]
c4a836f95a fix: crash on custom printing margins (#22185)
Co-authored-by: Shelley Vohr <codebytere@github.com>
2020-02-14 15:40:01 +09:00
trop[bot]
9b2de2583e fix: no-arg console.log is undefined (#22171)
Co-authored-by: Shelley Vohr <codebytere@github.com>
2020-02-14 15:31:49 +09:00
Samuel Attard
7b2bfb4a0f chore: update NMV for Electron 9 (#22189) 2020-02-13 13:18:22 -08:00
Jeremy Apthorp
0e31826043 feat: enable pdf viewer 2020-02-13 10:09:29 -08:00
trop[bot]
7b3c073b3e fix RTL bug when used with traffic light repositioning (#22163)
Co-authored-by: tonyfwoo <55114329+tonyfwoo@users.noreply.github.com>
2020-02-12 11:29:03 -06:00
trop[bot]
2dc900b95d ci: Speed up release (#22159) 2020-02-12 07:27:21 +00:00
trop[bot]
f41423501a fix: make webRequest work with WebSocket (#22133)
* fix: web request support proxying websocket

* fix: make tests work

* chore: do not use api:: code outside api/ folder

* chore: do not create proxy when no listener

* test: use separate session to avoid conflicts

* chore: address review

Co-authored-by: Cheng Zhao <zcbenz@github.com>
2020-02-11 15:56:00 -05:00
trop[bot]
07d9728b63 build: fix spellchecker deps (#22155)
Co-authored-by: Alexey Kuzmin <alex.s.kuzmin@gmail.com>
2020-02-11 15:45:46 -05:00
trop[bot]
d4c90e80a5 refactor: use NSVisualEffectMaterial* constants directly (#22148) 2020-02-11 17:48:44 +00:00
trop[bot]
91141028e6 chore: print more logging for failed tests (#22116)
Co-authored-by: Cheng Zhao <zcbenz@github.com>
2020-02-11 15:07:54 +09:00
Electron Bot
9d69d4b9ef Bump v9.0.0-beta.1 2020-02-10 06:50:08 -08:00
Electron Bot
d57d5c544e Revert "Bump v9.0.0-beta.2"
This reverts commit 74d4dab157.
2020-02-10 06:38:44 -08:00
Electron Bot
74d4dab157 Bump v9.0.0-beta.2 2020-02-10 04:32:41 -08:00
trop[bot]
94246dabe3 ci: fix build failure on doc only changes (#22089)
* ci: fix build failure on doc only changes

* ci: fix doc-only check when CI fires on branch before PR is created

Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-02-10 17:09:35 +09:00
trop[bot]
4fe91e56ac chore: remove debugging log (#22095)
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-02-10 17:05:34 +09:00
trop[bot]
0d7440d676 build: preserve timestamps when stripping files (#22098)
* build: preserve timestamps when stripping files

Resolves an issue where the binaries in mksnapshot.zip were not getting stripped.

* Add missing comma

* Update script/strip-binaries.py

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

* Don't try to run strip on macOS

Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
Co-authored-by: Jeremy Apthorp <nornagon@nornagon.net>
2020-02-10 17:05:04 +09:00
trop[bot]
60edd2d3b1 build: try using newer version of xcode/macOS sdk (#22106)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-02-10 16:48:51 +09:00
trop[bot]
d4d06660f3 fix: flash plugin (#22111)
* fix: flash plugin

Fixes https://github.com/electron/electron/issues/20744

* cleanup

* fix linting issue

Co-authored-by: t57ser <seve@live.at>
2020-02-10 10:50:56 +09:00
trop[bot]
8d8f15121b fix: use a WeakPtr so we do not UAF the store in FunctionLifetimeMonitor (#22113)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2020-02-10 10:47:23 +09:00
trop[bot]
1f8cb5144d build: copy chromedriver to correct location (#22092)
* build: copy chromedriver to correct location

* build: try to free up disk space for macos releases

* get verbose mode working on strip-binaries

* Only use separate chromedriver build arm/arm64

* fixup circleci config

Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-02-07 16:49:04 -05:00
trop[bot]
667ee359a1 test: get native unit tests running (#22086)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-02-07 10:53:09 -05:00
trop[bot]
4b009159ba docs: clarify requirements for GOOGLE_API_KEY (#22071)
* docs: clarify requirements for GOOGLE_API_KEY

* Update docs/api/environment-variables.md

Co-Authored-By: Mark Lee <malept@users.noreply.github.com>

* Update docs/api/environment-variables.md

Co-Authored-By: Mark Lee <malept@users.noreply.github.com>

* Update docs/api/environment-variables.md

Co-Authored-By: Mark Lee <malept@users.noreply.github.com>

* update

Co-authored-by: Erick Zhao <erick@hotmail.ca>
Co-authored-by: Mark Lee <malept@users.noreply.github.com>
2020-02-06 15:25:28 -05:00
John Kleinschmidt
89f66bd00c Revert "Bump v9.0.0-beta.1"
This reverts commit 68346fec55.
2020-02-06 15:19:27 -05:00
trop[bot]
2d542c6028 build: copy chromedriver to proper directory for release (#22073)
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2020-02-06 15:07:46 -05:00
Electron Bot
68346fec55 Bump v9.0.0-beta.1 2020-02-05 13:46:21 -08:00
Samuel Attard
23f32ca9f3 chore: prepare for 9.0.0-beta.1 2020-02-05 13:44:23 -08:00
846 changed files with 38111 additions and 28162 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -6,9 +6,11 @@
"browser": true "browser": true
}, },
"rules": { "rules": {
"semi": ["error", "always"],
"no-var": "error", "no-var": "error",
"no-unused-vars": 0, "no-unused-vars": 0,
"no-global-assign": 0, "no-global-assign": 0,
"guard-for-in": 2,
"@typescript-eslint/no-unused-vars": ["error", { "@typescript-eslint/no-unused-vars": ["error", {
"vars": "all", "vars": "all",
"args": "after-used", "args": "after-used",
@@ -25,7 +27,12 @@
"sourceType": "module" "sourceType": "module"
}, },
"globals": { "globals": {
"standardScheme": "readonly" "standardScheme": "readonly",
"BUILDFLAG": "readonly",
"ENABLE_DESKTOP_CAPTURER": "readonly",
"ENABLE_ELECTRON_EXTENSIONS": "readonly",
"ENABLE_REMOTE_MODULE": "readonly",
"ENABLE_VIEW_API": "readonly"
}, },
"overrides": [ "overrides": [
{ {

1
.gitattributes vendored
View File

@@ -1,3 +1,4 @@
# `git apply` and friends don't understand CRLF, even on windows. Force those # `git apply` and friends don't understand CRLF, even on windows. Force those
# files to be checked out with LF endings even if core.autocrlf is true. # files to be checked out with LF endings even if core.autocrlf is true.
*.patch text eol=lf *.patch text eol=lf
patches/**/.patches merge=union

123
BUILD.gn
View File

@@ -3,6 +3,7 @@ import("//build/config/ui.gni")
import("//build/config/win/manifest.gni") import("//build/config/win/manifest.gni")
import("//components/spellcheck/spellcheck_build_features.gni") import("//components/spellcheck/spellcheck_build_features.gni")
import("//content/public/app/mac_helpers.gni") import("//content/public/app/mac_helpers.gni")
import("//extensions/buildflags/buildflags.gni")
import("//pdf/features.gni") import("//pdf/features.gni")
import("//ppapi/buildflags/buildflags.gni") import("//ppapi/buildflags/buildflags.gni")
import("//printing/buildflags/buildflags.gni") import("//printing/buildflags/buildflags.gni")
@@ -58,6 +59,17 @@ if (is_mas_build) {
"It doesn't make sense to build a MAS build on a non-mac platform") "It doesn't make sense to build a MAS build on a non-mac platform")
} }
if (enable_pdf_viewer) {
assert(enable_pdf, "PDF viewer support requires enable_pdf=true")
assert(enable_electron_extensions,
"PDF viewer support requires enable_electron_extensions=true")
}
if (enable_electron_extensions) {
assert(enable_extensions,
"Chrome extension support requires enable_extensions=true")
}
config("branding") { config("branding") {
defines = [ defines = [
"ELECTRON_PRODUCT_NAME=\"$electron_product_name\"", "ELECTRON_PRODUCT_NAME=\"$electron_product_name\"",
@@ -224,7 +236,6 @@ grit("resources") {
] ]
# Mojo manifest overlays are generated. # Mojo manifest overlays are generated.
source_is_generated = true
grit_flags = [ grit_flags = [
"-E", "-E",
"target_gen_dir=" + rebase_path(target_gen_dir, root_build_dir), "target_gen_dir=" + rebase_path(target_gen_dir, root_build_dir),
@@ -322,16 +333,21 @@ source_set("electron_lib") {
"shell/common/api:mojo", "shell/common/api:mojo",
"//base:base_static", "//base:base_static",
"//base/allocator:buildflags", "//base/allocator:buildflags",
"//chrome/app:command_ids",
"//chrome/app/resources:platform_locale_settings", "//chrome/app/resources:platform_locale_settings",
"//chrome/services/printing/public/mojom", "//chrome/services/printing/public/mojom",
"//components/certificate_transparency", "//components/certificate_transparency",
"//components/crash/core/app",
"//components/language/core/browser", "//components/language/core/browser",
"//components/net_log", "//components/net_log",
"//components/network_hints/browser", "//components/network_hints/browser",
"//components/network_hints/common:mojo_bindings", "//components/network_hints/common:mojo_bindings",
"//components/network_hints/renderer", "//components/network_hints/renderer",
"//components/network_session_configurator/common", "//components/network_session_configurator/common",
"//components/pref_registry",
"//components/prefs", "//components/prefs",
"//components/upload_list",
"//components/user_prefs",
"//components/viz/host", "//components/viz/host",
"//components/viz/service", "//components/viz/service",
"//content/public/browser", "//content/public/browser",
@@ -444,10 +460,15 @@ source_set("electron_lib") {
] ]
} }
if (is_linux) {
deps += [ "//components/crash/content/browser" ]
}
if (is_mac) { if (is_mac) {
deps += [ deps += [
"//components/remote_cocoa/app_shim", "//components/remote_cocoa/app_shim",
"//content/common:mac_helpers", "//content/common:mac_helpers",
"//third_party/crashpad/crashpad/client",
"//ui/accelerated_widget_mac", "//ui/accelerated_widget_mac",
] ]
@@ -469,11 +490,7 @@ source_set("electron_lib") {
] ]
if (is_mas_build) { if (is_mas_build) {
sources += [ "shell/browser/api/electron_api_app_mas.mm" ] sources += [ "shell/browser/api/electron_api_app_mas.mm" ]
sources -= [ sources -= [ "shell/browser/auto_updater_mac.mm" ]
"shell/browser/auto_updater_mac.mm",
"shell/common/crash_reporter/crash_reporter_mac.h",
"shell/common/crash_reporter/crash_reporter_mac.mm",
]
defines += [ "MAS_BUILD" ] defines += [ "MAS_BUILD" ]
} else { } else {
libs += [ libs += [
@@ -494,17 +511,21 @@ source_set("electron_lib") {
deps += [ deps += [
":libnotify_loader", ":libnotify_loader",
"//build/config/linux/gtk", "//build/config/linux/gtk",
"//chrome/browser/ui/gtk",
"//dbus", "//dbus",
"//device/bluetooth", "//device/bluetooth",
"//third_party/breakpad:client",
"//ui/events/devices/x11", "//ui/events/devices/x11",
"//ui/events/platform/x11", "//ui/events/platform/x11",
"//ui/gtk",
"//ui/views/controls/webview", "//ui/views/controls/webview",
"//ui/wm", "//ui/wm",
] ]
if (use_x11) {
deps += [
"//ui/gfx/x",
"//ui/gtk:x",
]
}
configs += [ ":gio_unix" ] configs += [ ":gio_unix" ]
include_dirs += [ "//third_party/breakpad" ]
configs += [ "//build/config/linux:x11" ] configs += [ "//build/config/linux:x11" ]
defines += [ defines += [
# Disable warnings for g_settings_list_schemas. # Disable warnings for g_settings_list_schemas.
@@ -513,6 +534,16 @@ source_set("electron_lib") {
sources += filenames.lib_sources_nss sources += filenames.lib_sources_nss
sources += [ sources += [
"shell/browser/ui/gtk/app_indicator_icon.cc",
"shell/browser/ui/gtk/app_indicator_icon.h",
"shell/browser/ui/gtk/app_indicator_icon_menu.cc",
"shell/browser/ui/gtk/app_indicator_icon_menu.h",
"shell/browser/ui/gtk/gtk_status_icon.cc",
"shell/browser/ui/gtk/gtk_status_icon.h",
"shell/browser/ui/gtk/menu_util.cc",
"shell/browser/ui/gtk/menu_util.h",
"shell/browser/ui/gtk/status_icon.cc",
"shell/browser/ui/gtk/status_icon.h",
"shell/browser/ui/gtk_util.cc", "shell/browser/ui/gtk_util.cc",
"shell/browser/ui/gtk_util.h", "shell/browser/ui/gtk_util.h",
] ]
@@ -520,6 +551,7 @@ source_set("electron_lib") {
if (is_win) { if (is_win) {
libs += [ "dwmapi.lib" ] libs += [ "dwmapi.lib" ]
deps += [ deps += [
"//components/crash/core/app:crash_export_thunks",
"//ui/native_theme:native_theme_browser", "//ui/native_theme:native_theme_browser",
"//ui/views/controls/webview", "//ui/views/controls/webview",
"//ui/wm", "//ui/wm",
@@ -531,14 +563,6 @@ source_set("electron_lib") {
] ]
} }
if ((is_mac && !is_mas_build) || is_win) {
sources += [
"shell/common/crash_reporter/crash_reporter_crashpad.cc",
"shell/common/crash_reporter/crash_reporter_crashpad.h",
]
deps += [ "//third_party/crashpad/crashpad/client" ]
}
if (enable_plugins) { if (enable_plugins) {
deps += [ "chromium_src:plugins" ] deps += [ "chromium_src:plugins" ]
sources += [ sources += [
@@ -578,8 +602,6 @@ source_set("electron_lib") {
if (enable_remote_module) { if (enable_remote_module) {
sources += [ sources += [
"shell/common/api/remote/object_life_monitor.cc",
"shell/common/api/remote/object_life_monitor.h",
"shell/common/api/remote/remote_callback_freer.cc", "shell/common/api/remote/remote_callback_freer.cc",
"shell/common/api/remote/remote_callback_freer.h", "shell/common/api/remote/remote_callback_freer.h",
"shell/common/api/remote/remote_object_freer.cc", "shell/common/api/remote/remote_object_freer.cc",
@@ -629,25 +651,29 @@ source_set("electron_lib") {
deps += [ "//components/printing/common:mojo_interfaces" ] deps += [ "//components/printing/common:mojo_interfaces" ]
} }
deps += [ "shell/common/extensions/api:extensions_features" ]
deps += [ "shell/common/extensions/api" ]
deps += [
"//components/pref_registry",
"//components/user_prefs",
"//extensions/browser",
"//extensions/browser:core_api_provider",
"//extensions/common",
"//extensions/common:core_api_provider",
"//extensions/renderer",
]
if (enable_electron_extensions) { if (enable_electron_extensions) {
sources += filenames.lib_sources_extensions sources += filenames.lib_sources_extensions
deps += [
"shell/browser/extensions/api:api_registration",
"shell/common/extensions/api",
"shell/common/extensions/api:extensions_features",
"//chrome/browser/resources:component_extension_resources",
"//components/zoom",
"//extensions/browser",
"//extensions/browser:core_api_provider",
"//extensions/common",
"//extensions/common:core_api_provider",
"//extensions/renderer",
]
} }
if (enable_pdf) { if (enable_pdf) {
# Printing depends on some //pdf code, so it needs to be built even if the # Printing depends on some //pdf code, so it needs to be built even if the
# pdf viewer isn't enabled. # pdf viewer isn't enabled.
deps += [ "//pdf" ] deps += [
"//pdf",
"//pdf:features",
]
} }
if (enable_pdf_viewer) { if (enable_pdf_viewer) {
deps += [ deps += [
@@ -728,9 +754,14 @@ if (is_mac) {
sources = [ sources = [
"$root_out_dir/egl_intermediates/libswiftshader_libEGL.dylib", "$root_out_dir/egl_intermediates/libswiftshader_libEGL.dylib",
"$root_out_dir/egl_intermediates/libswiftshader_libGLESv2.dylib", "$root_out_dir/egl_intermediates/libswiftshader_libGLESv2.dylib",
"$root_out_dir/vk_intermediates/libvk_swiftshader.dylib",
"$root_out_dir/vk_intermediates/vk_swiftshader_icd.json",
] ]
outputs = [ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" ] outputs = [ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" ]
public_deps = [ "//ui/gl:swiftshader_library_copy" ] public_deps = [
"//ui/gl:swiftshader_egl_library_copy",
"//ui/gl:swiftshader_vk_library_copy",
]
} }
} }
group("electron_angle_library") { group("electron_angle_library") {
@@ -746,11 +777,17 @@ if (is_mac) {
} }
bundle_data("electron_crashpad_helper") { bundle_data("electron_crashpad_helper") {
sources = [ "$root_out_dir/crashpad_handler" ] sources = [ "$root_out_dir/chrome_crashpad_handler" ]
outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ] outputs = [ "{{bundle_contents_dir}}/Helpers/{{source_file_part}}" ]
public_deps = [ "//third_party/crashpad/crashpad/handler:crashpad_handler" ] public_deps = [ "//components/crash/core/app:chrome_crashpad_handler" ]
if (is_asan) {
# crashpad_handler requires the ASan runtime at its @executable_path.
sources += [ "$root_out_dir/libclang_rt.asan_osx_dynamic.dylib" ]
public_deps += [ "//build/config/sanitizers:copy_asan_runtime" ]
}
} }
mac_framework_bundle("electron_framework") { mac_framework_bundle("electron_framework") {
@@ -759,6 +796,7 @@ if (is_mac) {
framework_contents = [ framework_contents = [
"Resources", "Resources",
"Libraries", "Libraries",
"Helpers",
] ]
public_deps = [ public_deps = [
":electron_framework_libraries", ":electron_framework_libraries",
@@ -783,6 +821,7 @@ if (is_mac) {
include_dirs = [ "." ] include_dirs = [ "." ]
sources = filenames.framework_sources sources = filenames.framework_sources
libs = []
if (enable_osr) { if (enable_osr) {
libs += [ "IOSurface.framework" ] libs += [ "IOSurface.framework" ]
@@ -981,10 +1020,10 @@ if (is_mac) {
} }
extract_symbols("crashpad_handler_syms") { extract_symbols("crashpad_handler_syms") {
binary = "$root_out_dir/crashpad_handler" binary = "$root_out_dir/chrome_crashpad_handler"
symbol_dir = "$root_out_dir/breakpad_symbols" symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/crashpad_handler.dSYM/Contents/Resources/DWARF/crashpad_handler" dsym_file = "$root_out_dir/chrome_crashpad_handler.dSYM/Contents/Resources/DWARF/chrome_crashpad_handler"
deps = [ "//third_party/crashpad/crashpad/handler:crashpad_handler" ] deps = [ "//components/crash/core/app:chrome_crashpad_handler" ]
} }
group("electron_symbols") { group("electron_symbols") {
@@ -1025,6 +1064,7 @@ if (is_mac) {
":electron_app_manifest", ":electron_app_manifest",
":electron_lib", ":electron_lib",
":packed_resources", ":packed_resources",
"//components/crash/core/app",
"//content:sandbox_helper_win", "//content:sandbox_helper_win",
"//electron/buildflags", "//electron/buildflags",
"//ui/strings", "//ui/strings",
@@ -1054,6 +1094,11 @@ if (is_mac) {
"shell/browser/resources/win/resource.h", "shell/browser/resources/win/resource.h",
] ]
deps += [
"//components/browser_watcher:browser_watcher_client",
"//components/crash/core/app:run_as_crashpad_handler",
]
libs = [ libs = [
"comctl32.lib", "comctl32.lib",
"uiautomationcore.lib", "uiautomationcore.lib",
@@ -1257,7 +1302,7 @@ dist_zip("electron_chromedriver_zip") {
mksnapshot_deps = [ mksnapshot_deps = [
":licenses", ":licenses",
"//tools/v8_context_snapshot:v8_context_snapshot_generator", "//tools/v8_context_snapshot:v8_context_snapshot_generator($v8_snapshot_toolchain)",
"//v8:mksnapshot($v8_snapshot_toolchain)", "//v8:mksnapshot($v8_snapshot_toolchain)",
] ]

4
DEPS
View File

@@ -12,7 +12,7 @@ gclient_gn_args = [
vars = { vars = {
'chromium_version': 'chromium_version':
'2102ff0fb03469ca5ff317a168e6ad99ca0f23f1', '83.0.4103.100',
'node_version': 'node_version':
'v12.14.1', 'v12.14.1',
'nan_version': 'nan_version':
@@ -155,3 +155,5 @@ hooks = [
recursedeps = [ recursedeps = [
'src', 'src',
] ]
# Touch DEPS again to bust cache

View File

@@ -1 +1 @@
9.0.0-nightly.20200205 9.0.3

View File

@@ -118,29 +118,43 @@ build_script:
} }
} }
- ps: >- - ps: >-
if (Test-Path 'env:RAW_GOMA_AUTH') { if ($env:GN_CONFIG -ne 'release') {
$env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config" if (Test-Path 'env:RAW_GOMA_AUTH') {
$env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE $env:GOMA_OAUTH2_CONFIG_FILE = "$pwd\.goma_oauth2_config"
.\src\electron\script\start-goma.ps1 -gomaDir "$pwd\src\electron\external_binaries\goma" $env:RAW_GOMA_AUTH | Set-Content $env:GOMA_OAUTH2_CONFIG_FILE
}
git clone https://github.com/electron/build-tools.git
cd build-tools
npm install
mkdir third_party
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
$env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
$env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
cd ..
.\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
} }
- cd src - cd src
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn - set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
- if DEFINED RAW_GOMA_AUTH (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"//electron/build/args/goma.gn\") %GN_EXTRA_ARGS% ") else (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\"") - if DEFINED GN_GOMA_FILE (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") import(\"%GN_GOMA_FILE%\") %GN_EXTRA_ARGS% ") else (gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") %GN_EXTRA_ARGS% cc_wrapper=\"%SCCACHE_PATH%\"")
- gn check out/Default //electron:electron_lib - gn check out/Default //electron:electron_lib
- gn check out/Default //electron:electron_app - gn check out/Default //electron:electron_app
- gn check out/Default //electron:manifests - gn check out/Default //electron:manifests
- gn check out/Default //electron/shell/common/api:mojo - gn check out/Default //electron/shell/common/api:mojo
- if DEFINED RAW_GOMA_AUTH (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app) - if DEFINED GN_GOMA_FILE (ninja -j 300 -C out/Default electron:electron_app) else (ninja -C out/Default electron:electron_app)
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default ) - if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%" - gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") %GN_EXTRA_ARGS%"
- ninja -C out/ffmpeg electron:electron_ffmpeg_zip - ninja -C out/ffmpeg electron:electron_ffmpeg_zip
- ninja -C out/Default electron:electron_dist_zip - ninja -C out/Default electron:electron_dist_zip
- ninja -C out/Default shell_browser_ui_unittests - ninja -C out/Default shell_browser_ui_unittests
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
- ninja -C out/Default electron:electron_mksnapshot_zip - ninja -C out/Default electron:electron_mksnapshot_zip
- cd out\Default
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
- cd ..\..
- ninja -C out/Default electron:hunspell_dictionaries_zip - ninja -C out/Default electron:hunspell_dictionaries_zip
- ninja -C out/Default electron:electron_chromedriver_zip - ninja -C out/Default electron:electron_chromedriver_zip
- ninja -C out/Default third_party/electron_node:headers - ninja -C out/Default third_party/electron_node:headers
- if DEFINED RAW_GOMA_AUTH (python electron\external_binaries\goma\goma_ctl.py stat) - if "%GN_CONFIG%"=="testing" ( python %LOCAL_GOMA_DIR%\goma_ctl.py stat )
- python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json - python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
- appveyor PushArtifact out/Default/windows_toolchain_profile.json - appveyor PushArtifact out/Default/windows_toolchain_profile.json
- appveyor PushArtifact out/Default/dist.zip - appveyor PushArtifact out/Default/dist.zip
@@ -187,8 +201,7 @@ test_script:
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --enable-logging) - if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --enable-logging)
- cd .. - cd ..
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg ) - if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
- echo "About to verify mksnapshot" - echo "About to verify mksnapshot"
- if "%RUN_TESTS%"=="true" ( gn desc out\Default v8:run_mksnapshot_default args > out\Default\mksnapshot_args )
- if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% ) - if "%RUN_TESTS%"=="true" ( echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd% )
- echo "Done verifying mksnapshot" - echo "Done verifying mksnapshot"
- if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% ) - if "%RUN_TESTS%"=="true" ( echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd% )

View File

@@ -88,5 +88,6 @@ steps:
- powershell: | - powershell: |
Get-Process | Where Name Like "electron*" | Stop-Process Get-Process | Where Name Like "electron*" | Stop-Process
Get-Process | Where Name Like "MicrosoftEdge*" | Stop-Process Get-Process | Where Name Like "MicrosoftEdge*" | Stop-Process
Get-Process | Where Name Like "msedge*" | Stop-Process
displayName: 'Kill processes left running from last test run' displayName: 'Kill processes left running from last test run'
condition: always() condition: always()

View File

@@ -2,7 +2,7 @@ is_electron_build = true
root_extra_deps = [ "//electron" ] root_extra_deps = [ "//electron" ]
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json # Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
node_module_version = 76 node_module_version = 80
v8_promise_internal_field_count = 1 v8_promise_internal_field_count = 1
v8_typed_array_max_size_in_heap = 0 v8_typed_array_max_size_in_heap = 0
@@ -20,8 +20,3 @@ angle_enable_vulkan_validation_layers = false
dawn_enable_vulkan_validation_layers = false dawn_enable_vulkan_validation_layers = false
is_cfi = false is_cfi = false
# TODO: disabled due to crashes. re-enable.
enable_osr = false
enable_electron_extensions = true

View File

@@ -1,3 +1,4 @@
const fs = require('fs');
const path = require('path') const path = require('path')
const webpack = require('webpack') const webpack = require('webpack')
@@ -9,6 +10,9 @@ config.output = {
filename: path.basename(outPath) filename: path.basename(outPath)
} }
const { wrapInitWithProfilingTimeout } = config;
delete config.wrapInitWithProfilingTimeout;
webpack(config, (err, stats) => { webpack(config, (err, stats) => {
if (err) { if (err) {
console.error(err) console.error(err)
@@ -17,6 +21,18 @@ webpack(config, (err, stats) => {
console.error(stats.toString('normal')) console.error(stats.toString('normal'))
process.exit(1) process.exit(1)
} else { } else {
if (wrapInitWithProfilingTimeout) {
const contents = fs.readFileSync(outPath, 'utf8');
const newContents = `function ___electron_webpack_init__() {
${contents}
};
if ((globalThis.process || binding.process).argv.includes("--profile-electron-init")) {
setTimeout(___electron_webpack_init__, 0);
} else {
___electron_webpack_init__();
}`;
fs.writeFileSync(outPath, newContents);
}
process.exit(0) process.exit(0)
} }
}) })

View File

@@ -20,11 +20,78 @@ class AccessDependenciesPlugin {
} }
} }
const defines = {
BUILDFLAG: ''
}
const buildFlagsPrefix = '--buildflags='
const buildFlagArg = process.argv.find(arg => arg.startsWith(buildFlagsPrefix))
if (buildFlagArg) {
const buildFlagPath = buildFlagArg.substr(buildFlagsPrefix.length)
const flagFile = fs.readFileSync(buildFlagPath, 'utf8')
for (const line of flagFile.split(/(\r\n|\r|\n)/g)) {
const flagMatch = line.match(/#define BUILDFLAG_INTERNAL_(.+?)\(\) \(([01])\)/)
if (flagMatch) {
const flagName = flagMatch[1]
const flagValue = flagMatch[2]
defines[flagName] = JSON.stringify(Boolean(parseInt(flagValue, 10)))
}
}
}
const ignoredModules = []
if (defines['ENABLE_DESKTOP_CAPTURER'] === 'false') {
ignoredModules.push(
'@electron/internal/browser/desktop-capturer',
'@electron/internal/renderer/api/desktop-capturer'
)
}
if (defines['ENABLE_REMOTE_MODULE'] === 'false') {
ignoredModules.push(
'@electron/internal/browser/remote/server',
'@electron/internal/renderer/api/remote'
)
}
if (defines['ENABLE_VIEW_API'] === 'false') {
ignoredModules.push(
'@electron/internal/browser/api/views/box-layout',
'@electron/internal/browser/api/views/button',
'@electron/internal/browser/api/views/label-button',
'@electron/internal/browser/api/views/layout-manager',
'@electron/internal/browser/api/views/md-text-button',
'@electron/internal/browser/api/views/resize-area',
'@electron/internal/browser/api/views/text-field'
)
}
if (defines['ENABLE_ELECTRON_EXTENSIONS'] === 'false') {
ignoredModules.push(
'@electron/internal/@browser/chrome-extension-shim'
)
} else {
ignoredModules.push(
'@electron/internal/browser/chrome-extension',
'@electron/internal/renderer/chrome-api',
'@electron/internal/renderer/content-scripts-injector'
)
}
const alias = {}
for (const ignoredModule of ignoredModules) {
alias[ignoredModule] = path.resolve(electronRoot, 'lib/common/dummy.js')
}
module.exports = ({ module.exports = ({
alwaysHasNode, alwaysHasNode,
loadElectronFromAlternateTarget, loadElectronFromAlternateTarget,
targetDeletesNodeGlobals, targetDeletesNodeGlobals,
target target,
wrapInitWithProfilingTimeout
}) => { }) => {
let entry = path.resolve(electronRoot, 'lib', target, 'init.ts') let entry = path.resolve(electronRoot, 'lib', target, 'init.ts')
if (!fs.existsSync(entry)) { if (!fs.existsSync(entry)) {
@@ -39,8 +106,10 @@ module.exports = ({
output: { output: {
filename: `${target}.bundle.js` filename: `${target}.bundle.js`
}, },
wrapInitWithProfilingTimeout,
resolve: { resolve: {
alias: { alias: {
...alias,
'@electron/internal': path.resolve(electronRoot, 'lib'), '@electron/internal': path.resolve(electronRoot, 'lib'),
'electron': path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts'), 'electron': path.resolve(electronRoot, 'lib', loadElectronFromAlternateTarget || target, 'api', 'exports', 'electron.ts'),
// Force timers to resolve to our dependency that doens't use window.postMessage // Force timers to resolve to our dependency that doens't use window.postMessage
@@ -78,6 +147,7 @@ module.exports = ({
new webpack.ProvidePlugin({ new webpack.ProvidePlugin({
Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise'], Promise: ['@electron/internal/common/webpack-globals-provider', 'Promise'],
}), }),
new webpack.DefinePlugin(defines),
] ]
}) })
} }

View File

@@ -1,5 +1,6 @@
module.exports = require('./webpack.config.base')({ module.exports = require('./webpack.config.base')({
target: 'renderer', target: 'renderer',
alwaysHasNode: true, alwaysHasNode: true,
targetDeletesNodeGlobals: true targetDeletesNodeGlobals: true,
wrapInitWithProfilingTimeout: true
}) })

View File

@@ -1,4 +1,5 @@
module.exports = require('./webpack.config.base')({ module.exports = require('./webpack.config.base')({
target: 'sandboxed_renderer', target: 'sandboxed_renderer',
alwaysHasNode: false alwaysHasNode: false,
wrapInitWithProfilingTimeout: true,
}) })

View File

@@ -16,6 +16,7 @@ template("webpack_build") {
inputs = [ inputs = [
invoker.config_file, invoker.config_file,
"//electron/build/webpack/webpack.config.base.js", "//electron/build/webpack/webpack.config.base.js",
"//electron/build/webpack/run-compiler.js",
"//electron/tsconfig.json", "//electron/tsconfig.json",
"//electron/yarn.lock", "//electron/yarn.lock",
"//electron/typings/internal-ambient.d.ts", "//electron/typings/internal-ambient.d.ts",
@@ -25,7 +26,9 @@ template("webpack_build") {
args = [ args = [
rebase_path(invoker.config_file), rebase_path(invoker.config_file),
rebase_path(invoker.out_file), rebase_path(invoker.out_file),
"--buildflags=" + rebase_path("$target_gen_dir/buildflags/buildflags.h"),
] ]
deps += [ "buildflags" ]
outputs = [ invoker.out_file ] outputs = [ invoker.out_file ]
} }

View File

@@ -25,6 +25,13 @@ PATHS_TO_SKIP = [
# //chrome/browser/resources/ssl/ssl_error_assistant, but we don't need to # //chrome/browser/resources/ssl/ssl_error_assistant, but we don't need to
# ship it. # ship it.
'pyproto', 'pyproto',
# On Windows, this binary doesn't exist (the crashpad handler is built-in).
# On MacOS, the binary is called 'chrome_crashpad_handler' and is inside the
# app bundle.
# On Linux, we don't use crashpad, but this binary is still built for some
# reason. Exclude it from the zip.
'./crashpad_handler',
] ]
def skip_path(dep, dist_zip, target_cpu): def skip_path(dep, dist_zip, target_cpu):

View File

@@ -14,7 +14,7 @@ declare_args() {
enable_view_api = false enable_view_api = false
enable_pdf_viewer = false enable_pdf_viewer = true
enable_tts = true enable_tts = true
@@ -32,7 +32,7 @@ declare_args() {
enable_pepper_flash = true enable_pepper_flash = true
# Enable Chrome extensions support. # Enable Chrome extensions support.
enable_electron_extensions = false enable_electron_extensions = true
# Enable Spellchecker support # Enable Spellchecker support
enable_builtin_spellchecker = true enable_builtin_spellchecker = true

View File

@@ -14,6 +14,8 @@ static_library("chrome") {
sources = [ sources = [
"//chrome/browser/browser_process.cc", "//chrome/browser/browser_process.cc",
"//chrome/browser/browser_process.h", "//chrome/browser/browser_process.h",
"//chrome/browser/crash_upload_list/crash_upload_list_crashpad.cc",
"//chrome/browser/crash_upload_list/crash_upload_list_crashpad.h",
"//chrome/browser/devtools/devtools_contents_resizing_strategy.cc", "//chrome/browser/devtools/devtools_contents_resizing_strategy.cc",
"//chrome/browser/devtools/devtools_contents_resizing_strategy.h", "//chrome/browser/devtools/devtools_contents_resizing_strategy.h",
"//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc", "//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc",
@@ -51,10 +53,12 @@ static_library("chrome") {
"//chrome/browser/ssl/security_state_tab_helper.cc", "//chrome/browser/ssl/security_state_tab_helper.cc",
"//chrome/browser/ssl/security_state_tab_helper.h", "//chrome/browser/ssl/security_state_tab_helper.h",
"//chrome/browser/ssl/tls_deprecation_config.cc", "//chrome/browser/ssl/tls_deprecation_config.cc",
"//chrome/browser/ui/autofill/popup_view_common.cc", "//chrome/browser/ui/views/autofill/autofill_popup_view_utils.cc",
"//chrome/browser/ui/autofill/popup_view_common.h", "//chrome/browser/ui/views/autofill/autofill_popup_view_utils.h",
"//chrome/browser/win/chrome_process_finder.cc", "//chrome/browser/win/chrome_process_finder.cc",
"//chrome/browser/win/chrome_process_finder.h", "//chrome/browser/win/chrome_process_finder.h",
"//chrome/child/v8_crashpad_support_win.cc",
"//chrome/child/v8_crashpad_support_win.h",
"//extensions/browser/app_window/size_constraints.cc", "//extensions/browser/app_window/size_constraints.cc",
"//extensions/browser/app_window/size_constraints.h", "//extensions/browser/app_window/size_constraints.h",
] ]
@@ -68,8 +72,8 @@ static_library("chrome") {
] ]
deps = [ deps = [
"//chrome/browser:resource_prefetch_predictor_proto", "//chrome/browser:resource_prefetch_predictor_proto",
"//chrome/browser/ssl:proto",
"//components/feature_engagement:buildflags", "//components/feature_engagement:buildflags",
"//components/optimization_guide/proto:optimization_guide_proto",
] ]
if (is_linux) { if (is_linux) {
@@ -110,11 +114,15 @@ static_library("chrome") {
] ]
if (use_aura) { if (use_aura) {
sources += [ sources += [ "//chrome/browser/platform_util_aura.cc" ]
"//chrome/browser/platform_util_aura.cc",
"//chrome/browser/ui/views/color_chooser_aura.cc", if (!is_win) {
"//chrome/browser/ui/views/color_chooser_aura.h", sources += [
] "//chrome/browser/ui/views/color_chooser_aura.cc",
"//chrome/browser/ui/views/color_chooser_aura.h",
]
}
deps += [ "//components/feature_engagement" ] deps += [ "//components/feature_engagement" ]
} }
@@ -233,11 +241,24 @@ static_library("chrome") {
if (enable_electron_extensions) { if (enable_electron_extensions) {
sources += [ sources += [
"//chrome/browser/extensions/chrome_url_request_util.cc",
"//chrome/browser/extensions/chrome_url_request_util.h",
"//chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc",
"//chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h",
"//chrome/renderer/extensions/extension_hooks_delegate.cc", "//chrome/renderer/extensions/extension_hooks_delegate.cc",
"//chrome/renderer/extensions/extension_hooks_delegate.h", "//chrome/renderer/extensions/extension_hooks_delegate.h",
"//chrome/renderer/extensions/tabs_hooks_delegate.cc", "//chrome/renderer/extensions/tabs_hooks_delegate.cc",
"//chrome/renderer/extensions/tabs_hooks_delegate.h", "//chrome/renderer/extensions/tabs_hooks_delegate.h",
] ]
if (enable_pdf_viewer) {
sources += [
"//chrome/browser/pdf/pdf_extension_util.cc",
"//chrome/browser/pdf/pdf_extension_util.h",
"//chrome/renderer/pepper/chrome_pdf_print_client.cc",
"//chrome/renderer/pepper/chrome_pdf_print_client.h",
]
}
} }
} }
@@ -261,6 +282,9 @@ source_set("plugins") {
"//ppapi/proxy:ipc", "//ppapi/proxy:ipc",
"//services/device/public/mojom", "//services/device/public/mojom",
] ]
if (enable_pdf_viewer) {
deps += [ "//components/pdf/browser" ]
}
if (enable_pepper_flash) { if (enable_pepper_flash) {
sources += [ sources += [
"//chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc", "//chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc",
@@ -293,8 +317,6 @@ source_set("plugins") {
sources += [ sources += [
"//chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc", "//chrome/renderer/pepper/pepper_flash_drm_renderer_host.cc",
"//chrome/renderer/pepper/pepper_flash_drm_renderer_host.h", "//chrome/renderer/pepper/pepper_flash_drm_renderer_host.h",
"//chrome/renderer/pepper/pepper_flash_font_file_host.cc",
"//chrome/renderer/pepper/pepper_flash_font_file_host.h",
"//chrome/renderer/pepper/pepper_flash_fullscreen_host.cc", "//chrome/renderer/pepper/pepper_flash_fullscreen_host.cc",
"//chrome/renderer/pepper/pepper_flash_fullscreen_host.h", "//chrome/renderer/pepper/pepper_flash_fullscreen_host.h",
"//chrome/renderer/pepper/pepper_flash_menu_host.cc", "//chrome/renderer/pepper/pepper_flash_menu_host.cc",
@@ -303,6 +325,15 @@ source_set("plugins") {
"//chrome/renderer/pepper/pepper_flash_renderer_host.h", "//chrome/renderer/pepper/pepper_flash_renderer_host.h",
] ]
} }
if (enable_pepper_flash || enable_pdf_viewer) {
sources += [
"//chrome/renderer/pepper/pepper_flash_font_file_host.cc",
"//chrome/renderer/pepper/pepper_flash_font_file_host.h",
]
if (enable_pdf_viewer) {
deps += [ "//components/pdf/renderer" ]
}
}
deps += [ deps += [
"//components/strings", "//components/strings",
"//media:media_buildflags", "//media:media_buildflags",

View File

@@ -1,48 +1,48 @@
import { app, dialog, BrowserWindow, shell, ipcMain } from 'electron' import { app, dialog, BrowserWindow, shell, ipcMain } from 'electron';
import * as path from 'path' import * as path from 'path';
let mainWindow: BrowserWindow | null = null let mainWindow: BrowserWindow | null = null;
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', () => { app.on('window-all-closed', () => {
app.quit() app.quit();
}) });
function decorateURL (url: string) { function decorateURL (url: string) {
// safely add `?utm_source=default_app // safely add `?utm_source=default_app
const parsedUrl = new URL(url) const parsedUrl = new URL(url);
parsedUrl.searchParams.append('utm_source', 'default_app') parsedUrl.searchParams.append('utm_source', 'default_app');
return parsedUrl.toString() return parsedUrl.toString();
} }
// Find the shortest path to the electron binary // Find the shortest path to the electron binary
const absoluteElectronPath = process.execPath const absoluteElectronPath = process.execPath;
const relativeElectronPath = path.relative(process.cwd(), absoluteElectronPath) const relativeElectronPath = path.relative(process.cwd(), absoluteElectronPath);
const electronPath = absoluteElectronPath.length < relativeElectronPath.length const electronPath = absoluteElectronPath.length < relativeElectronPath.length
? absoluteElectronPath ? absoluteElectronPath
: relativeElectronPath : relativeElectronPath;
const indexPath = path.resolve(app.getAppPath(), 'index.html') const indexPath = path.resolve(app.getAppPath(), 'index.html');
function isTrustedSender (webContents: Electron.WebContents) { function isTrustedSender (webContents: Electron.WebContents) {
if (webContents !== (mainWindow && mainWindow.webContents)) { if (webContents !== (mainWindow && mainWindow.webContents)) {
return false return false;
} }
const parsedUrl = new URL(webContents.getURL()) const parsedUrl = new URL(webContents.getURL());
const urlPath = process.platform === 'win32' const urlPath = process.platform === 'win32'
// Strip the prefixed "/" that occurs on windows // Strip the prefixed "/" that occurs on windows
? path.resolve(parsedUrl.pathname.substr(1)) ? path.resolve(parsedUrl.pathname.substr(1))
: parsedUrl.pathname : parsedUrl.pathname;
return parsedUrl.protocol === 'file:' && urlPath === indexPath return parsedUrl.protocol === 'file:' && urlPath === indexPath;
} }
ipcMain.handle('bootstrap', (event) => { ipcMain.handle('bootstrap', (event) => {
return isTrustedSender(event.sender) ? electronPath : null return isTrustedSender(event.sender) ? electronPath : null;
}) });
async function createWindow () { async function createWindow () {
await app.whenReady() await app.whenReady();
const options: Electron.BrowserWindowConstructorOptions = { const options: Electron.BrowserWindowConstructorOptions = {
width: 900, width: 900,
@@ -57,46 +57,46 @@ async function createWindow () {
}, },
useContentSize: true, useContentSize: true,
show: false show: false
} };
if (process.platform === 'linux') { if (process.platform === 'linux') {
options.icon = path.join(__dirname, 'icon.png') options.icon = path.join(__dirname, 'icon.png');
} }
mainWindow = new BrowserWindow(options) mainWindow = new BrowserWindow(options);
mainWindow.on('ready-to-show', () => mainWindow!.show()) mainWindow.on('ready-to-show', () => mainWindow!.show());
mainWindow.webContents.on('new-window', (event, url) => { mainWindow.webContents.on('new-window', (event, url) => {
event.preventDefault() event.preventDefault();
shell.openExternal(decorateURL(url)) shell.openExternal(decorateURL(url));
}) });
mainWindow.webContents.session.setPermissionRequestHandler((webContents, permission, done) => { mainWindow.webContents.session.setPermissionRequestHandler((webContents, permission, done) => {
const parsedUrl = new URL(webContents.getURL()) const parsedUrl = new URL(webContents.getURL());
const options: Electron.MessageBoxOptions = { const options: Electron.MessageBoxOptions = {
title: 'Permission Request', title: 'Permission Request',
message: `Allow '${parsedUrl.origin}' to access '${permission}'?`, message: `Allow '${parsedUrl.origin}' to access '${permission}'?`,
buttons: ['OK', 'Cancel'], buttons: ['OK', 'Cancel'],
cancelId: 1 cancelId: 1
} };
dialog.showMessageBox(mainWindow!, options).then(({ response }) => { dialog.showMessageBox(mainWindow!, options).then(({ response }) => {
done(response === 0) done(response === 0);
}) });
}) });
return mainWindow return mainWindow;
} }
export const loadURL = async (appUrl: string) => { export const loadURL = async (appUrl: string) => {
mainWindow = await createWindow() mainWindow = await createWindow();
mainWindow.loadURL(appUrl) mainWindow.loadURL(appUrl);
mainWindow.focus() mainWindow.focus();
} };
export const loadFile = async (appPath: string) => { export const loadFile = async (appPath: string) => {
mainWindow = await createWindow() mainWindow = await createWindow();
mainWindow.loadFile(appPath) mainWindow.loadFile(appPath);
mainWindow.focus() mainWindow.focus();
} };

View File

@@ -1,8 +1,8 @@
import { app, dialog } from 'electron' import { app, dialog } from 'electron';
import * as fs from 'fs' import * as fs from 'fs';
import * as path from 'path' import * as path from 'path';
import * as url from 'url' import * as url from 'url';
type DefaultAppOptions = { type DefaultAppOptions = {
file: null | string; file: null | string;
@@ -14,10 +14,10 @@ type DefaultAppOptions = {
modules: string[]; modules: string[];
} }
const Module = require('module') const Module = require('module');
// Parse command line options. // Parse command line options.
const argv = process.argv.slice(1) const argv = process.argv.slice(1);
const option: DefaultAppOptions = { const option: DefaultAppOptions = {
file: null, file: null,
@@ -27,50 +27,50 @@ const option: DefaultAppOptions = {
interactive: false, interactive: false,
abi: false, abi: false,
modules: [] modules: []
} };
let nextArgIsRequire = false let nextArgIsRequire = false;
for (const arg of argv) { for (const arg of argv) {
if (nextArgIsRequire) { if (nextArgIsRequire) {
option.modules.push(arg) option.modules.push(arg);
nextArgIsRequire = false nextArgIsRequire = false;
continue continue;
} else if (arg === '--version' || arg === '-v') { } else if (arg === '--version' || arg === '-v') {
option.version = true option.version = true;
break break;
} else if (arg.match(/^--app=/)) { } else if (arg.match(/^--app=/)) {
option.file = arg.split('=')[1] option.file = arg.split('=')[1];
break break;
} else if (arg === '--interactive' || arg === '-i' || arg === '-repl') { } else if (arg === '--interactive' || arg === '-i' || arg === '-repl') {
option.interactive = true option.interactive = true;
} else if (arg === '--test-type=webdriver') { } else if (arg === '--test-type=webdriver') {
option.webdriver = true option.webdriver = true;
} else if (arg === '--require' || arg === '-r') { } else if (arg === '--require' || arg === '-r') {
nextArgIsRequire = true nextArgIsRequire = true;
continue continue;
} else if (arg === '--abi' || arg === '-a') { } else if (arg === '--abi' || arg === '-a') {
option.abi = true option.abi = true;
continue continue;
} else if (arg === '--no-help') { } else if (arg === '--no-help') {
option.noHelp = true option.noHelp = true;
continue continue;
} else if (arg[0] === '-') { } else if (arg[0] === '-') {
continue continue;
} else { } else {
option.file = arg option.file = arg;
break break;
} }
} }
if (nextArgIsRequire) { if (nextArgIsRequire) {
console.error('Invalid Usage: --require [file]\n\n"file" is required') console.error('Invalid Usage: --require [file]\n\n"file" is required');
process.exit(1) process.exit(1);
} }
// Set up preload modules // Set up preload modules
if (option.modules.length > 0) { if (option.modules.length > 0) {
Module._preloadModules(option.modules) Module._preloadModules(option.modules);
} }
function loadApplicationPackage (packagePath: string) { function loadApplicationPackage (packagePath: string) {
@@ -79,102 +79,102 @@ function loadApplicationPackage (packagePath: string) {
configurable: false, configurable: false,
enumerable: true, enumerable: true,
value: true value: true
}) });
try { try {
// Override app name and version. // Override app name and version.
packagePath = path.resolve(packagePath) packagePath = path.resolve(packagePath);
const packageJsonPath = path.join(packagePath, 'package.json') const packageJsonPath = path.join(packagePath, 'package.json');
let appPath let appPath;
if (fs.existsSync(packageJsonPath)) { if (fs.existsSync(packageJsonPath)) {
let packageJson let packageJson;
try { try {
packageJson = require(packageJsonPath) packageJson = require(packageJsonPath);
} catch (e) { } catch (e) {
showErrorMessage(`Unable to parse ${packageJsonPath}\n\n${e.message}`) showErrorMessage(`Unable to parse ${packageJsonPath}\n\n${e.message}`);
return return;
} }
if (packageJson.version) { if (packageJson.version) {
app.setVersion(packageJson.version) app.setVersion(packageJson.version);
} }
if (packageJson.productName) { if (packageJson.productName) {
app.name = packageJson.productName app.name = packageJson.productName;
} else if (packageJson.name) { } else if (packageJson.name) {
app.name = packageJson.name app.name = packageJson.name;
} }
appPath = packagePath appPath = packagePath;
} }
try { try {
const filePath = Module._resolveFilename(packagePath, module, true) const filePath = Module._resolveFilename(packagePath, module, true);
app._setDefaultAppPaths(appPath || path.dirname(filePath)) app._setDefaultAppPaths(appPath || path.dirname(filePath));
} catch (e) { } catch (e) {
showErrorMessage(`Unable to find Electron app at ${packagePath}\n\n${e.message}`) showErrorMessage(`Unable to find Electron app at ${packagePath}\n\n${e.message}`);
return return;
} }
// Run the app. // Run the app.
Module._load(packagePath, module, true) Module._load(packagePath, module, true);
} catch (e) { } catch (e) {
console.error('App threw an error during load') console.error('App threw an error during load');
console.error(e.stack || e) console.error(e.stack || e);
throw e throw e;
} }
} }
function showErrorMessage (message: string) { function showErrorMessage (message: string) {
app.focus() app.focus();
dialog.showErrorBox('Error launching app', message) dialog.showErrorBox('Error launching app', message);
process.exit(1) process.exit(1);
} }
async function loadApplicationByURL (appUrl: string) { async function loadApplicationByURL (appUrl: string) {
const { loadURL } = await import('./default_app') const { loadURL } = await import('./default_app');
loadURL(appUrl) loadURL(appUrl);
} }
async function loadApplicationByFile (appPath: string) { async function loadApplicationByFile (appPath: string) {
const { loadFile } = await import('./default_app') const { loadFile } = await import('./default_app');
loadFile(appPath) loadFile(appPath);
} }
function startRepl () { function startRepl () {
if (process.platform === 'win32') { if (process.platform === 'win32') {
console.error('Electron REPL not currently supported on Windows') console.error('Electron REPL not currently supported on Windows');
process.exit(1) process.exit(1);
} }
// prevent quitting // prevent quitting
app.on('window-all-closed', () => {}) app.on('window-all-closed', () => {});
const repl = require('repl') const repl = require('repl');
repl.start('> ').on('exit', () => { repl.start('> ').on('exit', () => {
process.exit(0) process.exit(0);
}) });
} }
// Start the specified app if there is one specified in command line, otherwise // Start the specified app if there is one specified in command line, otherwise
// start the default app. // start the default app.
if (option.file && !option.webdriver) { if (option.file && !option.webdriver) {
const file = option.file const file = option.file;
const protocol = url.parse(file).protocol const protocol = url.parse(file).protocol;
const extension = path.extname(file) const extension = path.extname(file);
if (protocol === 'http:' || protocol === 'https:' || protocol === 'file:' || protocol === 'chrome:') { if (protocol === 'http:' || protocol === 'https:' || protocol === 'file:' || protocol === 'chrome:') {
loadApplicationByURL(file) loadApplicationByURL(file);
} else if (extension === '.html' || extension === '.htm') { } else if (extension === '.html' || extension === '.htm') {
loadApplicationByFile(path.resolve(file)) loadApplicationByFile(path.resolve(file));
} else { } else {
loadApplicationPackage(file) loadApplicationPackage(file);
} }
} else if (option.version) { } else if (option.version) {
console.log('v' + process.versions.electron) console.log('v' + process.versions.electron);
process.exit(0) process.exit(0);
} else if (option.abi) { } else if (option.abi) {
console.log(process.versions.modules) console.log(process.versions.modules);
process.exit(0) process.exit(0);
} else if (option.interactive) { } else if (option.interactive) {
startRepl() startRepl();
} else { } else {
if (!option.noHelp) { if (!option.noHelp) {
const welcomeMessage = ` const welcomeMessage = `
@@ -192,10 +192,10 @@ Options:
-i, --interactive Open a REPL to the main process. -i, --interactive Open a REPL to the main process.
-r, --require Module to preload (option can be repeated). -r, --require Module to preload (option can be repeated).
-v, --version Print the version. -v, --version Print the version.
-a, --abi Print the Node ABI version.` -a, --abi Print the Node ABI version.`;
console.log(welcomeMessage) console.log(welcomeMessage);
} }
loadApplicationByFile('index.html') loadApplicationByFile('index.html');
} }

View File

@@ -1,53 +1,53 @@
import { ipcRenderer, contextBridge } from 'electron' import { ipcRenderer, contextBridge } from 'electron';
async function getOcticonSvg (name: string) { async function getOcticonSvg (name: string) {
try { try {
const response = await fetch(`octicon/${name}.svg`) const response = await fetch(`octicon/${name}.svg`);
const div = document.createElement('div') const div = document.createElement('div');
div.innerHTML = await response.text() div.innerHTML = await response.text();
return div return div;
} catch { } catch {
return null return null;
} }
} }
async function loadSVG (element: HTMLSpanElement) { async function loadSVG (element: HTMLSpanElement) {
for (const cssClass of element.classList) { for (const cssClass of element.classList) {
if (cssClass.startsWith('octicon-')) { if (cssClass.startsWith('octicon-')) {
const icon = await getOcticonSvg(cssClass.substr(8)) const icon = await getOcticonSvg(cssClass.substr(8));
if (icon) { if (icon) {
for (const elemClass of element.classList) { for (const elemClass of element.classList) {
icon.classList.add(elemClass) icon.classList.add(elemClass);
} }
element.before(icon) element.before(icon);
element.remove() element.remove();
break break;
} }
} }
} }
} }
async function initialize () { async function initialize () {
const electronPath = await ipcRenderer.invoke('bootstrap') const electronPath = await ipcRenderer.invoke('bootstrap');
function replaceText (selector: string, text: string) { function replaceText (selector: string, text: string) {
const element = document.querySelector<HTMLElement>(selector) const element = document.querySelector<HTMLElement>(selector);
if (element) { if (element) {
element.innerText = text element.innerText = text;
} }
} }
replaceText('.electron-version', `Electron v${process.versions.electron}`) replaceText('.electron-version', `Electron v${process.versions.electron}`);
replaceText('.chrome-version', `Chromium v${process.versions.chrome}`) replaceText('.chrome-version', `Chromium v${process.versions.chrome}`);
replaceText('.node-version', `Node v${process.versions.node}`) replaceText('.node-version', `Node v${process.versions.node}`);
replaceText('.v8-version', `v8 v${process.versions.v8}`) replaceText('.v8-version', `v8 v${process.versions.v8}`);
replaceText('.command-example', `${electronPath} path-to-app`) replaceText('.command-example', `${electronPath} path-to-app`);
for (const element of document.querySelectorAll<HTMLSpanElement>('.octicon')) { for (const element of document.querySelectorAll<HTMLSpanElement>('.octicon')) {
loadSVG(element) loadSVG(element);
} }
} }
contextBridge.exposeInMainWorld('electronDefaultApp', { contextBridge.exposeInMainWorld('electronDefaultApp', {
initialize initialize
}) });

View File

@@ -112,6 +112,7 @@ These individual tutorials expand on topics discussed in the guide above.
* [Process Object](api/process.md) * [Process Object](api/process.md)
* [Supported Command Line Switches](api/command-line-switches.md) * [Supported Command Line Switches](api/command-line-switches.md)
* [Environment Variables](api/environment-variables.md) * [Environment Variables](api/environment-variables.md)
* [Chrome Extensions Support](api/extensions.md)
* [Breaking API Changes](breaking-changes.md) * [Breaking API Changes](breaking-changes.md)
### Custom DOM Elements: ### Custom DOM Elements:

View File

@@ -54,7 +54,7 @@ The `Super` key is mapped to the `Windows` key on Windows and Linux and
* `0` to `9` * `0` to `9`
* `A` to `Z` * `A` to `Z`
* `F1` to `F24` * `F1` to `F24`
* Punctuations like `~`, `!`, `@`, `#`, `$`, etc. * Punctuation like `~`, `!`, `@`, `#`, `$`, etc.
* `Plus` * `Plus`
* `Space` * `Space`
* `Tab` * `Tab`

View File

@@ -75,7 +75,7 @@ Returns:
* `event` Event * `event` Event
Emitted when all windows have been closed and the application will quit. Emitted when all windows have been closed and the application will quit.
Calling `event.preventDefault()` will prevent the default behaviour, which is Calling `event.preventDefault()` will prevent the default behavior, which is
terminating the application. terminating the application.
See the description of the `window-all-closed` event for the differences between See the description of the `window-all-closed` event for the differences between
@@ -204,7 +204,7 @@ Returns:
[`NSUserActivity.activityType`][activity-type]. [`NSUserActivity.activityType`][activity-type].
* `userInfo` unknown - Contains app-specific state stored by the activity. * `userInfo` unknown - Contains app-specific state stored by the activity.
Emitted when [Handoff][handoff] is about to be resumed on another device. If you need to update the state to be transferred, you should call `event.preventDefault()` immediately, construct a new `userInfo` dictionary and call `app.updateCurrentActiviy()` in a timely manner. Otherwise, the operation will fail and `continue-activity-error` will be called. Emitted when [Handoff][handoff] is about to be resumed on another device. If you need to update the state to be transferred, you should call `event.preventDefault()` immediately, construct a new `userInfo` dictionary and call `app.updateCurrentActivity()` in a timely manner. Otherwise, the operation will fail and `continue-activity-error` will be called.
### Event: 'new-window-for-tab' _macOS_ ### Event: 'new-window-for-tab' _macOS_
@@ -554,11 +554,17 @@ Returns `Promise<void>` - fulfilled when Electron is initialized.
May be used as a convenient alternative to checking `app.isReady()` May be used as a convenient alternative to checking `app.isReady()`
and subscribing to the `ready` event if the app is not ready yet. and subscribing to the `ready` event if the app is not ready yet.
### `app.focus()` ### `app.focus([options])`
* `options` Object (optional)
* `steal` Boolean _macOS_ - Make the receiver the active app even if another app is
currently active.
On Linux, focuses on the first visible window. On macOS, makes the application On Linux, focuses on the first visible window. On macOS, makes the application
the active app. On Windows, focuses on the application's first window. the active app. On Windows, focuses on the application's first window.
You should seek to use the `steal` option as sparingly as possible.
### `app.hide()` _macOS_ ### `app.hide()` _macOS_
Hides all application windows without minimizing them. Hides all application windows without minimizing them.
@@ -602,6 +608,7 @@ Returns `String` - The current application directory.
* `videos` Directory for a user's videos. * `videos` Directory for a user's videos.
* `logs` Directory for your app's log folder. * `logs` Directory for your app's log folder.
* `pepperFlashSystemPlugin` Full path to the system version of the Pepper Flash plugin. * `pepperFlashSystemPlugin` Full path to the system version of the Pepper Flash plugin.
* `crashDumps` Directory where crash dumps are stored.
Returns `String` - A path to a special directory or file associated with `name`. On Returns `String` - A path to a special directory or file associated with `name`. On
failure, an `Error` is thrown. failure, an `Error` is thrown.
@@ -659,8 +666,6 @@ to the npm modules spec. You should usually also specify a `productName`
field, which is your application's full capitalized name, and which will be field, which is your application's full capitalized name, and which will be
preferred over `name` by Electron. preferred over `name` by Electron.
**[Deprecated](modernization/property-updates.md)**
### `app.setName(name)` ### `app.setName(name)`
* `name` String * `name` String
@@ -669,8 +674,6 @@ Overrides the current application's name.
**Note:** This function overrides the name used internally by Electron; it does not affect the name that the OS uses. **Note:** This function overrides the name used internally by Electron; it does not affect the name that the OS uses.
**[Deprecated](modernization/property-updates.md)**
### `app.getLocale()` ### `app.getLocale()`
Returns `String` - The current application locale. Possible return values are documented [here](locales.md). Returns `String` - The current application locale. Possible return values are documented [here](locales.md).
@@ -703,34 +706,34 @@ Clears the recent documents list.
### `app.setAsDefaultProtocolClient(protocol[, path, args])` ### `app.setAsDefaultProtocolClient(protocol[, path, args])`
* `protocol` String - The name of your protocol, without `://`. If you want your * `protocol` String - The name of your protocol, without `://`. For example,
app to handle `electron://` links, call this method with `electron` as the if you want your app to handle `electron://` links, call this method with
parameter. `electron` as the parameter.
* `path` String (optional) _Windows_ - Defaults to `process.execPath` * `path` String (optional) _Windows_ - The path to the Electron executable.
* `args` String[] (optional) _Windows_ - Defaults to an empty array Defaults to `process.execPath`
* `args` String[] (optional) _Windows_ - Arguments passed to the executable.
Defaults to an empty array
Returns `Boolean` - Whether the call succeeded. Returns `Boolean` - Whether the call succeeded.
This method sets the current executable as the default handler for a protocol Sets the current executable as the default handler for a protocol (aka URI
(aka URI scheme). It allows you to integrate your app deeper into the operating scheme). It allows you to integrate your app deeper into the operating system.
system. Once registered, all links with `your-protocol://` will be opened with Once registered, all links with `your-protocol://` will be opened with the
the current executable. The whole link, including protocol, will be passed to current executable. The whole link, including protocol, will be passed to your
your application as a parameter. application as a parameter.
On Windows, you can provide optional parameters path, the path to your executable,
and args, an array of arguments to be passed to your executable when it launches.
**Note:** On macOS, you can only register protocols that have been added to **Note:** On macOS, you can only register protocols that have been added to
your app's `info.plist`, which can not be modified at runtime. You can however your app's `info.plist`, which cannot be modified at runtime. However, you can
change the file with a simple text editor or script during build time. change the file during build time via [Electron Forge][electron-forge],
Please refer to [Apple's documentation][CFBundleURLTypes] for details. [Electron Packager][electron-packager], or by editing `info.plist` with a text
editor. Please refer to [Apple's documentation][CFBundleURLTypes] for details.
**Note:** In a Windows Store environment (when packaged as an `appx`) this API **Note:** In a Windows Store environment (when packaged as an `appx`) this API
will return `true` for all calls but the registry key it sets won't be accessible will return `true` for all calls but the registry key it sets won't be accessible
by other applications. In order to register your Windows Store application by other applications. In order to register your Windows Store application
as a default protocol handler you must [declare the protocol in your manifest](https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-protocol). as a default protocol handler you must [declare the protocol in your manifest](https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-protocol).
The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally. The API uses the Windows Registry and `LSSetDefaultHandlerForURLScheme` internally.
### `app.removeAsDefaultProtocolClient(protocol[, path, args])` _macOS_ _Windows_ ### `app.removeAsDefaultProtocolClient(protocol[, path, args])` _macOS_ _Windows_
@@ -749,10 +752,8 @@ protocol (aka URI scheme). If so, it will remove the app as the default handler.
* `path` String (optional) _Windows_ - Defaults to `process.execPath` * `path` String (optional) _Windows_ - Defaults to `process.execPath`
* `args` String[] (optional) _Windows_ - Defaults to an empty array * `args` String[] (optional) _Windows_ - Defaults to an empty array
Returns `Boolean` Returns `Boolean` - Whether the current executable is the default handler for a
protocol (aka URI scheme).
This method checks if the current executable is the default handler for a protocol
(aka URI scheme). If so, it will return true. Otherwise, it will return false.
**Note:** On macOS, you can use this method to check if the app has been **Note:** On macOS, you can use this method to check if the app has been
registered as the default protocol handler for a protocol. You can also verify registered as the default protocol handler for a protocol. You can also verify
@@ -760,7 +761,7 @@ this by checking `~/Library/Preferences/com.apple.LaunchServices.plist` on the
macOS machine. Please refer to macOS machine. Please refer to
[Apple's documentation][LSCopyDefaultHandlerForURLScheme] for details. [Apple's documentation][LSCopyDefaultHandlerForURLScheme] for details.
The API uses the Windows Registry and LSCopyDefaultHandlerForURLScheme internally. The API uses the Windows Registry and `LSCopyDefaultHandlerForURLScheme` internally.
### `app.getApplicationNameForProtocol(url)` ### `app.getApplicationNameForProtocol(url)`
@@ -1027,7 +1028,7 @@ This method can only be called before app is ready.
By default, Chromium disables 3D APIs (e.g. WebGL) until restart on a per By default, Chromium disables 3D APIs (e.g. WebGL) until restart on a per
domain basis if the GPU processes crashes too frequently. This function domain basis if the GPU processes crashes too frequently. This function
disables that behaviour. disables that behavior.
This method can only be called before app is ready. This method can only be called before app is ready.
@@ -1091,14 +1092,10 @@ On macOS, it shows on the dock icon. On Linux, it only works for Unity launcher.
**Note:** Unity launcher requires the existence of a `.desktop` file to work, **Note:** Unity launcher requires the existence of a `.desktop` file to work,
for more information please read [Desktop Environment Integration][unity-requirement]. for more information please read [Desktop Environment Integration][unity-requirement].
**[Deprecated](modernization/property-updates.md)**
### `app.getBadgeCount()` _Linux_ _macOS_ ### `app.getBadgeCount()` _Linux_ _macOS_
Returns `Integer` - The current value displayed in the counter badge. Returns `Integer` - The current value displayed in the counter badge.
**[Deprecated](modernization/property-updates.md)**
### `app.isUnityRunning()` _Linux_ ### `app.isUnityRunning()` _Linux_
Returns `Boolean` - Whether the current desktop environment is Unity launcher. Returns `Boolean` - Whether the current desktop environment is Unity launcher.
@@ -1173,8 +1170,6 @@ technologies, such as screen readers, has been detected. See
https://www.chromium.org/developers/design-documents/accessibility for more https://www.chromium.org/developers/design-documents/accessibility for more
details. details.
**[Deprecated](modernization/property-updates.md)**
### `app.setAccessibilitySupportEnabled(enabled)` _macOS_ _Windows_ ### `app.setAccessibilitySupportEnabled(enabled)` _macOS_ _Windows_
* `enabled` Boolean - Enable or disable [accessibility tree](https://developers.google.com/web/fundamentals/accessibility/semantics-builtin/the-accessibility-tree) rendering * `enabled` Boolean - Enable or disable [accessibility tree](https://developers.google.com/web/fundamentals/accessibility/semantics-builtin/the-accessibility-tree) rendering
@@ -1186,8 +1181,6 @@ This API must be called after the `ready` event is emitted.
**Note:** Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default. **Note:** Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
**[Deprecated](modernization/property-updates.md)**
### `app.showAboutPanel()` ### `app.showAboutPanel()`
Show the app's about panel options. These options can be overridden with `app.setAboutPanelOptions(options)`. Show the app's about panel options. These options can be overridden with `app.setAboutPanelOptions(options)`.
@@ -1204,7 +1197,7 @@ Show the app's about panel options. These options can be overridden with `app.se
* `website` String (optional) _Linux_ - The app's website. * `website` String (optional) _Linux_ - The app's website.
* `iconPath` String (optional) _Linux_ _Windows_ - Path to the app's icon. On Linux, will be shown as 64x64 pixels while retaining aspect ratio. * `iconPath` String (optional) _Linux_ _Windows_ - Path to the app's icon. On Linux, will be shown as 64x64 pixels while retaining aspect ratio.
Set the about panel options. This will override the values defined in the app's `.plist` file on MacOS. See the [Apple docs][about-panel-options] for more details. On Linux, values must be set in order to be shown; there are no defaults. Set the about panel options. This will override the values defined in the app's `.plist` file on macOS. See the [Apple docs][about-panel-options] for more details. On Linux, values must be set in order to be shown; there are no defaults.
If you do not set `credits` but still wish to surface them in your app, AppKit will look for a file named "Credits.html", "Credits.rtf", and "Credits.rtfd", in that order, in the bundle returned by the NSBundle class method main. The first file found is used, and if none is found, the info area is left blank. See Apple [documentation](https://developer.apple.com/documentation/appkit/nsaboutpaneloptioncredits?language=objc) for more information. If you do not set `credits` but still wish to surface them in your app, AppKit will look for a file named "Credits.html", "Credits.rtf", and "Credits.rtfd", in that order, in the bundle returned by the NSBundle class method main. The first file found is used, and if none is found, the info area is left blank. See Apple [documentation](https://developer.apple.com/documentation/appkit/nsaboutpaneloptioncredits?language=objc) for more information.
@@ -1327,6 +1320,8 @@ A `Boolean` property that returns `true` if the app is packaged, `false` otherw
[dock-menu]:https://developer.apple.com/macos/human-interface-guidelines/menus/dock-menus/ [dock-menu]:https://developer.apple.com/macos/human-interface-guidelines/menus/dock-menus/
[tasks]:https://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks [tasks]:https://msdn.microsoft.com/en-us/library/windows/desktop/dd378460(v=vs.85).aspx#tasks
[app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx [app-user-model-id]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx
[electron-forge]: https://www.electronforge.io/
[electron-packager]: https://github.com/electron/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/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme [LSCopyDefaultHandlerForURLScheme]: https://developer.apple.com/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme
[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
@@ -1359,7 +1354,7 @@ in your app's initialization to ensure that your overridden value is used.
A `Boolean` which when `true` disables the overrides that Electron has in place A `Boolean` which when `true` disables the overrides that Electron has in place
to ensure renderer processes are restarted on every navigation. The current to ensure renderer processes are restarted on every navigation. The current
default value for this property is `false`. default value for this property is `true`.
The intention is for these overrides to become disabled by default and then at The intention is for these overrides to become disabled by default and then at
some point in the future this property will be removed. This property impacts some point in the future this property will be removed. This property impacts

View File

@@ -177,7 +177,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `simpleFullscreen` Boolean (optional) - Use pre-Lion fullscreen on macOS. Default is `false`. * `simpleFullscreen` Boolean (optional) - Use pre-Lion fullscreen on macOS. Default is `false`.
* `skipTaskbar` Boolean (optional) - Whether to show the window in taskbar. Default is * `skipTaskbar` Boolean (optional) - Whether to show the window in taskbar. Default is
`false`. `false`.
* `kiosk` Boolean (optional) - The kiosk mode. Default is `false`. * `kiosk` Boolean (optional) - Whether the window is in kiosk mode. Default is `false`.
* `title` String (optional) - Default window title. Default is `"Electron"`. If the HTML tag `<title>` is defined in the HTML file loaded by `loadURL()`, this property will be ignored. * `title` String (optional) - Default window title. Default is `"Electron"`. If the HTML tag `<title>` is defined in the HTML file loaded by `loadURL()`, this property will be ignored.
* `icon` ([NativeImage](native-image.md) | String) (optional) - The window icon. On Windows it is * `icon` ([NativeImage](native-image.md) | String) (optional) - The window icon. On Windows it is
recommended to use `ICO` icons to get best visual effects, you can also recommended to use `ICO` icons to get best visual effects, you can also
@@ -207,7 +207,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
* `opacity` Number (optional) - Set the initial opacity of the window, between 0.0 (fully * `opacity` Number (optional) - Set the initial opacity of the window, between 0.0 (fully
transparent) and 1.0 (fully opaque). This is only implemented on Windows and macOS. transparent) and 1.0 (fully opaque). This is only implemented on Windows and macOS.
* `darkTheme` Boolean (optional) - Forces using dark theme for the window, only works on * `darkTheme` Boolean (optional) - Forces using dark theme for the window, only works on
some GTK+3 desktop environments. Default is `false`. some GTK desktop environments. Default is `false`.
* `transparent` Boolean (optional) - Makes the window [transparent](frameless-window.md#transparent-window). * `transparent` Boolean (optional) - Makes the window [transparent](frameless-window.md#transparent-window).
Default is `false`. On Windows, does not work unless the window is frameless. Default is `false`. On Windows, does not work unless the window is frameless.
* `type` String (optional) - The type of window, default is normal window. See more about * `type` String (optional) - The type of window, default is normal window. See more about
@@ -289,7 +289,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
between the web pages even when you specified different values for them, between the web pages even when you specified different values for them,
including but not limited to `preload`, `sandbox` and `nodeIntegration`. including but not limited to `preload`, `sandbox` and `nodeIntegration`.
So it is suggested to use exact same `webPreferences` for web pages with So it is suggested to use exact same `webPreferences` for web pages with
the same `affinity`. _This property is experimental_ the same `affinity`. _Deprecated_
* `zoomFactor` Number (optional) - The default zoom factor of the page, `3.0` represents * `zoomFactor` Number (optional) - The default zoom factor of the page, `3.0` represents
`300%`. Default is `1.0`. `300%`. Default is `1.0`.
* `javascript` Boolean (optional) - Enables JavaScript support. Default is `true`. * `javascript` Boolean (optional) - Enables JavaScript support. Default is `true`.
@@ -369,6 +369,8 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
consecutive dialog protection is triggered. If not defined the default consecutive dialog protection is triggered. If not defined the default
message would be used, note that currently the default message is in message would be used, note that currently the default message is in
English and not localized. English and not localized.
* `disableDialogs` Boolean (optional) - Whether to disable dialogs
completely. Overrides `safeDialogs`. Default is `false`.
* `navigateOnDragDrop` Boolean (optional) - Whether dragging and dropping a * `navigateOnDragDrop` Boolean (optional) - Whether dragging and dropping a
file or link onto the page causes a navigation. Default is `false`. file or link onto the page causes a navigation. Default is `false`.
* `autoplayPolicy` String (optional) - Autoplay policy to apply to * `autoplayPolicy` String (optional) - Autoplay policy to apply to
@@ -383,6 +385,15 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
visible to users. visible to users.
* `spellcheck` Boolean (optional) - Whether to enable the builtin spellchecker. * `spellcheck` Boolean (optional) - Whether to enable the builtin spellchecker.
Default is `true`. Default is `true`.
* `enableWebSQL` Boolean (optional) - Whether to enable the [WebSQL api](https://www.w3.org/TR/webdatabase/).
Default is `true`.
* `v8CacheOptions` String (optional) - Enforces the v8 code caching policy
used by blink. Accepted values are
* `none` - Disables code caching
* `code` - Heuristic based code caching
* `bypassHeatCheck` - Bypass code caching heuristics but with lazy compilation
* `bypassHeatCheckAndEagerCompile` - Same as above except compilation is eager.
Default policy is `code`.
When setting minimum or maximum window size with `minWidth`/`maxWidth`/ When setting minimum or maximum window size with `minWidth`/`maxWidth`/
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from `minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
@@ -621,6 +632,12 @@ Returns:
Emitted on 3-finger swipe. Possible directions are `up`, `right`, `down`, `left`. Emitted on 3-finger swipe. Possible directions are `up`, `right`, `down`, `left`.
The method underlying this event is built to handle older macOS-style trackpad swiping,
where the content on the screen doesn't move with the swipe. Most macOS trackpads are not
configured to allow this kind of swiping anymore, so in order for it to emit properly the
'Swipe between pages' preference in `System Preferences > Trackpad > More Gestures` must be
set to 'Swipe with two or three fingers'.
#### Event: 'rotate-gesture' _macOS_ #### Event: 'rotate-gesture' _macOS_
Returns: Returns:
@@ -795,6 +812,51 @@ A `Boolean` property that determines whether the window menu bar should hide its
If the menu bar is already visible, setting this property to `true` won't If the menu bar is already visible, setting this property to `true` won't
hide it immediately. hide it immediately.
#### `win.simpleFullScreen`
A `Boolean` property that determines whether the window is in simple (pre-Lion) fullscreen mode.
#### `win.fullScreen`
A `Boolean` property that determines whether the window is in fullscreen mode.
#### `win.visibleOnAllWorkspaces`
A `Boolean` property that determines whether the window is visible on all workspaces.
**Note:** Always returns false on Windows.
#### `win.shadow`
A `Boolean` property that determines whether the window has a shadow.
#### `win.menuBarVisible` _Windows_ _Linux_
A `Boolean` property that determines whether the menu bar should be visible.
**Note:** If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
#### `win.kiosk`
A `Boolean` property that determines whether the window is in kiosk mode.
#### `win.documentEdited` _macOS_
A `Boolean` property that specifies whether the windows document has been edited.
The icon in title bar will become gray when set to `true`.
#### `win.representedFilename` _macOS_
A `String` property that determines the pathname of the file the window represents,
and the icon of the file will show in window's title bar.
#### `win.title`
A `String` property that determines the title of the native window.
**Note:** The title of the web page can be different from the title of the native window.
#### `win.minimizable` #### `win.minimizable`
A `Boolean` property that determines whether the window can be manually minimized by user. A `Boolean` property that determines whether the window can be manually minimized by user.
@@ -950,7 +1012,7 @@ Returns `Boolean` - Whether the window is in fullscreen mode.
Enters or leaves simple fullscreen mode. Enters or leaves simple fullscreen mode.
Simple fullscreen mode emulates the native fullscreen behavior found in versions of Mac OS X prior to Lion (10.7). Simple fullscreen mode emulates the native fullscreen behavior found in versions of macOS prior to Lion (10.7).
#### `win.isSimpleFullScreen()` _macOS_ #### `win.isSimpleFullScreen()` _macOS_
@@ -1113,15 +1175,11 @@ Returns `Integer[]` - Contains the window's maximum width and height.
* `resizable` Boolean * `resizable` Boolean
Sets whether the window can be manually resized by user. Sets whether the window can be manually resized by the user.
**[Deprecated](modernization/property-updates.md)**
#### `win.isResizable()` #### `win.isResizable()`
Returns `Boolean` - Whether the window can be manually resized by user. Returns `Boolean` - Whether the window can be manually resized by the user.
**[Deprecated](modernization/property-updates.md)**
#### `win.setMovable(movable)` _macOS_ _Windows_ #### `win.setMovable(movable)` _macOS_ _Windows_
@@ -1129,41 +1187,29 @@ Returns `Boolean` - Whether the window can be manually resized by user.
Sets whether the window can be moved by user. On Linux does nothing. Sets whether the window can be moved by user. On Linux does nothing.
**[Deprecated](modernization/property-updates.md)**
#### `win.isMovable()` _macOS_ _Windows_ #### `win.isMovable()` _macOS_ _Windows_
Returns `Boolean` - Whether the window can be moved by user. Returns `Boolean` - Whether the window can be moved by user.
On Linux always returns `true`. On Linux always returns `true`.
**[Deprecated](modernization/property-updates.md)**
#### `win.setMinimizable(minimizable)` _macOS_ _Windows_ #### `win.setMinimizable(minimizable)` _macOS_ _Windows_
* `minimizable` Boolean * `minimizable` Boolean
Sets whether the window can be manually minimized by user. On Linux does Sets whether the window can be manually minimized by user. On Linux does nothing.
nothing.
**[Deprecated](modernization/property-updates.md)**
#### `win.isMinimizable()` _macOS_ _Windows_ #### `win.isMinimizable()` _macOS_ _Windows_
Returns `Boolean` - Whether the window can be manually minimized by user Returns `Boolean` - Whether the window can be manually minimized by the user.
On Linux always returns `true`. On Linux always returns `true`.
**[Deprecated](modernization/property-updates.md)**
#### `win.setMaximizable(maximizable)` _macOS_ _Windows_ #### `win.setMaximizable(maximizable)` _macOS_ _Windows_
* `maximizable` Boolean * `maximizable` Boolean
Sets whether the window can be manually maximized by user. On Linux does Sets whether the window can be manually maximized by user. On Linux does nothing.
nothing.
**[Deprecated](modernization/property-updates.md)**
#### `win.isMaximizable()` _macOS_ _Windows_ #### `win.isMaximizable()` _macOS_ _Windows_
@@ -1171,23 +1217,15 @@ Returns `Boolean` - Whether the window can be manually maximized by user.
On Linux always returns `true`. On Linux always returns `true`.
**[Deprecated](modernization/property-updates.md)**
#### `win.setFullScreenable(fullscreenable)` #### `win.setFullScreenable(fullscreenable)`
* `fullscreenable` Boolean * `fullscreenable` Boolean
Sets whether the maximize/zoom window button toggles fullscreen mode or Sets whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
maximizes the window.
**[Deprecated](modernization/property-updates.md)**
#### `win.isFullScreenable()` #### `win.isFullScreenable()`
Returns `Boolean` - Whether the maximize/zoom window button toggles fullscreen mode or Returns `Boolean` - Whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
maximizes the window.
**[Deprecated](modernization/property-updates.md)**
#### `win.setClosable(closable)` _macOS_ _Windows_ #### `win.setClosable(closable)` _macOS_ _Windows_
@@ -1195,16 +1233,12 @@ maximizes the window.
Sets whether the window can be manually closed by user. On Linux does nothing. Sets whether the window can be manually closed by user. On Linux does nothing.
**[Deprecated](modernization/property-updates.md)**
#### `win.isClosable()` _macOS_ _Windows_ #### `win.isClosable()` _macOS_ _Windows_
Returns `Boolean` - Whether the window can be manually closed by user. Returns `Boolean` - Whether the window can be manually closed by user.
On Linux always returns `true`. On Linux always returns `true`.
**[Deprecated](modernization/property-updates.md)**
#### `win.setAlwaysOnTop(flag[, level][, relativeLevel])` #### `win.setAlwaysOnTop(flag[, level][, relativeLevel])`
* `flag` Boolean * `flag` Boolean
@@ -1302,7 +1336,7 @@ Makes the window not show in the taskbar.
* `flag` Boolean * `flag` Boolean
Enters or leaves the kiosk mode. Enters or leaves kiosk mode.
#### `win.isKiosk()` #### `win.isKiosk()`
@@ -1616,23 +1650,17 @@ This cannot be called when `titleBarStyle` is set to `customButtonsOnHover`.
Sets whether the window menu bar should hide itself automatically. Once set the Sets whether the window menu bar should hide itself automatically. Once set the
menu bar will only show when users press the single `Alt` key. menu bar will only show when users press the single `Alt` key.
If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't hide it immediately.
hide it immediately.
**[Deprecated](modernization/property-updates.md)**
#### `win.isMenuBarAutoHide()` #### `win.isMenuBarAutoHide()`
Returns `Boolean` - Whether menu bar automatically hides itself. Returns `Boolean` - Whether menu bar automatically hides itself.
**[Deprecated](modernization/property-updates.md)**
#### `win.setMenuBarVisibility(visible)` _Windows_ _Linux_ #### `win.setMenuBarVisibility(visible)` _Windows_ _Linux_
* `visible` Boolean * `visible` Boolean
Sets whether the menu bar should be visible. If the menu bar is auto-hide, users Sets whether the menu bar should be visible. If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
can still bring up the menu bar by pressing the single `Alt` key.
#### `win.isMenuBarVisible()` #### `win.isMenuBarVisible()`
@@ -1748,6 +1776,17 @@ will remove the vibrancy effect on the window.
Note that `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` have been Note that `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` have been
deprecated and will be removed in an upcoming version of macOS. deprecated and will be removed in an upcoming version of macOS.
#### `win.setTrafficLightPosition(position)` _macOS_
* `position` [Point](structures/point.md)
Set a custom position for the traffic light buttons. Can only be used with `titleBarStyle` set to `hidden`.
#### `win.getTrafficLightPosition()` _macOS_
Returns `Point` - The current position for the traffic light buttons. Can only be used with `titleBarStyle`
set to `hidden`.
#### `win.setTouchBar(touchBar)` _macOS_ _Experimental_ #### `win.setTouchBar(touchBar)` _macOS_ _Experimental_
* `touchBar` TouchBar | null * `touchBar` TouchBar | null

View File

@@ -22,6 +22,9 @@ which the request is associated.
with which the request is associated. Defaults to the empty string. The with which the request is associated. Defaults to the empty string. The
`session` option prevails on `partition`. Thus if a `session` is explicitly `session` option prevails on `partition`. Thus if a `session` is explicitly
specified, `partition` is ignored. specified, `partition` is ignored.
* `useSessionCookies` Boolean (optional) - Whether to send cookies with this
request from the provided session. This will make the `net` request's
cookie behavior match a `fetch` request. Default is `false`.
* `protocol` String (optional) - The protocol scheme in the form 'scheme:'. * `protocol` String (optional) - The protocol scheme in the form 'scheme:'.
Currently supported values are 'http:' or 'https:'. Defaults to 'http:'. Currently supported values are 'http:' or 'https:'. Defaults to 'http:'.
* `host` String (optional) - The server host provided as a concatenation of * `host` String (optional) - The server host provided as a concatenation of

View File

@@ -4,18 +4,13 @@
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)
The following is an example of automatically submitting a crash report to a The following is an example of setting up Electron to automatically submit
remote server: crash reports to a remote server:
```javascript ```javascript
const { crashReporter } = require('electron') const { crashReporter } = require('electron')
crashReporter.start({ crashReporter.start({ submitURL: 'https://your-domain.com/url-to-submit' })
productName: 'YourName',
companyName: 'YourCompany',
submitURL: 'https://your-domain.com/url-to-submit',
uploadToServer: true
})
``` ```
For setting up a server to accept and process crash reports, you can use For setting up a server to accept and process crash reports, you can use
@@ -30,11 +25,19 @@ Or use a 3rd party hosted solution:
* [Sentry](https://docs.sentry.io/clients/electron) * [Sentry](https://docs.sentry.io/clients/electron)
* [BugSplat](https://www.bugsplat.com/docs/platforms/electron) * [BugSplat](https://www.bugsplat.com/docs/platforms/electron)
Crash reports are saved locally in an application-specific temp directory folder. Crash reports are stored temporarily before being uploaded in a directory
For a `productName` of `YourName`, crash reports will be stored in a folder underneath the app's user data directory (called 'Crashpad' on Windows and Mac,
named `YourName Crashes` inside the temp directory. You can customize this temp or 'Crash Reports' on Linux). You can override this directory by calling
directory location for your app by calling the `app.setPath('temp', '/my/custom/temp')` `app.setPath('crashDumps', '/path/to/crashes')` before starting the crash
API before starting the crash reporter. reporter.
On Windows and macOS, Electron uses
[crashpad](https://chromium.googlesource.com/crashpad/crashpad/+/master/README.md)
to monitor and report crashes. On Linux, Electron uses
[breakpad](https://chromium.googlesource.com/breakpad/breakpad/+/master/). This
is an implementation detail driven by Chromium, and it may change in future. In
particular, crashpad is newer and will likely eventually replace breakpad on
all platforms.
## Methods ## Methods
@@ -43,40 +46,68 @@ The `crashReporter` module has the following methods:
### `crashReporter.start(options)` ### `crashReporter.start(options)`
* `options` Object * `options` Object
* `companyName` String
* `submitURL` String - URL that crash reports will be sent to as POST. * `submitURL` String - URL that crash reports will be sent to as POST.
* `productName` String (optional) - Defaults to `app.name`. * `productName` String (optional) - Defaults to `app.name`.
* `uploadToServer` Boolean (optional) - Whether crash reports should be sent to the server. Default is `true`. * `companyName` String (optional) _Deprecated_ - Deprecated alias for
* `ignoreSystemCrashHandler` Boolean (optional) - Default is `false`. `{ globalExtra: { _companyName: ... } }`.
* `extra` Record<String, String> (optional) - An object you can define that will be sent along with the * `uploadToServer` Boolean (optional) - Whether crash reports should be sent
report. Only string properties are sent correctly. Nested objects are not to the server. If false, crash reports will be collected and stored in the
supported. When using Windows, the property names and values must be fewer than 64 characters. crashes directory, but not uploaded. Default is `true`.
* `crashesDirectory` String (optional) - Directory to store the crash reports temporarily (only used when the crash reporter is started via `process.crashReporter.start`). * `ignoreSystemCrashHandler` Boolean (optional) - If true, crashes generated
in the main process will not be forwarded to the system crash handler.
Default is `false`.
* `rateLimit` Boolean (optional) _macOS_ _Windows_ - If true, limit the
number of crashes uploaded to 1/hour. Default is `false`.
* `compress` Boolean (optional) _macOS_ _Windows_ - If true, crash reports
will be compressed and uploaded with `Content-Encoding: gzip`. Not all
collection servers support compressed payloads. Default is `false`.
* `extra` Record<String, String> (optional) - Extra string key/value
annotations that will be sent along with crash reports that are generated
in the main process. Only string values are supported. Crashes generated in
child processes will not contain these extra
parameters to crash reports generated from child processes, call
[`addExtraParameter`](#crashreporteraddextraparameterkey-value) from the
child process.
* `globalExtra` Record<String, String> (optional) - Extra string key/value
annotations that will be sent along with any crash reports generated in any
process. These annotations cannot be changed once the crash reporter has
been started. If a key is present in both the global extra parameters and
the process-specific extra parameters, then the global one will take
precedence. By default, `productName` and the app version are included, as
well as the Electron version.
You are required to call this method before using any other `crashReporter` APIs This method must be called before using any other `crashReporter` APIs. Once
and in each process (main/renderer) from which you want to collect crash reports. initialized this way, the crashpad handler collects crashes from all
You can pass different options to `crashReporter.start` when calling from different processes. subsequently created processes. The crash reporter cannot be disabled once
started.
**Note** Child processes created via the `child_process` module will not have access to the Electron modules. This method should be called as early as possible in app startup, preferably
Therefore, to collect crash reports from them, use `process.crashReporter.start` instead. Pass the same options as above before `app.on('ready')`. If the crash reporter is not initialized at the time
along with an additional one called `crashesDirectory` that should point to a directory to store the crash a renderer process is created, then that renderer process will not be monitored
reports temporarily. You can test this out by calling `process.crash()` to crash the child process. by the crash reporter.
**Note:** If you need send additional/updated `extra` parameters after your **Note:** You can test out the crash reporter by generating a crash using
first call `start` you can call `addExtraParameter` on macOS or call `start` `process.crash()`.
again with the new/updated `extra` parameters on Linux and Windows.
**Note:** On macOS and windows, Electron uses a new `crashpad` client for crash collection and reporting. **Note:** If you need to send additional/updated `extra` parameters after your
If you want to enable crash reporting, initializing `crashpad` from the main process using `crashReporter.start` is required first call `start` you can call `addExtraParameter`.
regardless of which process you want to collect crashes from. Once initialized this way, the crashpad handler collects
crashes from all processes. You still have to call `crashReporter.start` from the renderer or child process, otherwise crashes from **Note:** Parameters passed in `extra`, `globalExtra` or set with
them will get reported without `companyName`, `productName` or any of the `extra` information. `addExtraParameter` have limits on the length of the keys and values. Key names
must be at most 39 bytes long, and values must be no longer than 127 bytes.
Keys with names longer than the maximum will be silently ignored. Key values
longer than the maximum length will be truncated.
**Note:** Calling this method from the renderer process is deprecated.
### `crashReporter.getLastCrashReport()` ### `crashReporter.getLastCrashReport()`
Returns [`CrashReport`](structures/crash-report.md): Returns [`CrashReport`](structures/crash-report.md) - The date and ID of the
last crash report. Only crash reports that have been uploaded will be returned;
even if a crash report is present on disk it will not be returned until it is
uploaded. In the case that there are no uploaded reports, `null` is returned.
Returns the date and ID of the last crash report. Only crash reports that have been uploaded will be returned; even if a crash report is present on disk it will not be returned until it is uploaded. In the case that there are no uploaded reports, `null` is returned. **Note:** Calling this method from the renderer process is deprecated.
### `crashReporter.getUploadedReports()` ### `crashReporter.getUploadedReports()`
@@ -85,43 +116,61 @@ Returns [`CrashReport[]`](structures/crash-report.md):
Returns all uploaded crash reports. Each report contains the date and uploaded Returns all uploaded crash reports. Each report contains the date and uploaded
ID. ID.
**Note:** Calling this method from the renderer process is deprecated.
### `crashReporter.getUploadToServer()` ### `crashReporter.getUploadToServer()`
Returns `Boolean` - Whether reports should be submitted to the server. Set through Returns `Boolean` - Whether reports should be submitted to the server. Set through
the `start` method or `setUploadToServer`. the `start` method or `setUploadToServer`.
**Note:** This API can only be called from the main process. **Note:** Calling this method from the renderer process is deprecated.
### `crashReporter.setUploadToServer(uploadToServer)` ### `crashReporter.setUploadToServer(uploadToServer)`
* `uploadToServer` Boolean _macOS_ - Whether reports should be submitted to the server. * `uploadToServer` Boolean - Whether reports should be submitted to the server.
This would normally be controlled by user preferences. This has no effect if This would normally be controlled by user preferences. This has no effect if
called before `start` is called. called before `start` is called.
**Note:** This API can only be called from the main process. **Note:** Calling this method from the renderer process is deprecated.
### `crashReporter.addExtraParameter(key, value)` _macOS_ _Windows_ ### `crashReporter.getCrashesDirectory()` _Deprecated_
* `key` String - Parameter key, must be less than 64 characters long. Returns `String` - The directory where crashes are temporarily stored before being uploaded.
* `value` String - Parameter value, must be less than 64 characters long.
Set an extra parameter to be sent with the crash report. The values **Note:** This method is deprecated, use `app.getPath('crashDumps')` instead.
specified here will be sent in addition to any values set via the `extra` option when `start` was called. This API is only available on macOS and windows, if you need to add/update extra parameters on Linux after your first call to `start` you can call `start` again with the updated `extra` options.
### `crashReporter.removeExtraParameter(key)` _macOS_ _Windows_ ### `crashReporter.addExtraParameter(key, value)`
* `key` String - Parameter key, must be less than 64 characters long. * `key` String - Parameter key, must be no longer than 39 bytes.
* `value` String - Parameter value, must be no longer than 127 bytes.
Remove a extra parameter from the current set of parameters so that it will not be sent with the crash report. Set an extra parameter to be sent with the crash report. The values specified
here will be sent in addition to any values set via the `extra` option when
`start` was called.
Parameters added in this fashion (or via the `extra` parameter to
`crashReporter.start`) are specific to the calling process. Adding extra
parameters in the main process will not cause those parameters to be sent along
with crashes from renderer or other child processes. Similarly, adding extra
parameters in a renderer process will not result in those parameters being sent
with crashes that occur in other renderer processes or in the main process.
**Note:** Parameters have limits on the length of the keys and values. Key
names must be no longer than 39 bytes, and values must be no longer than 127
bytes. Keys with names longer than the maximum will be silently ignored. Key
values longer than the maximum length will be truncated.
### `crashReporter.removeExtraParameter(key)`
* `key` String - Parameter key, must be no longer than 39 bytes.
Remove a extra parameter from the current set of parameters. Future crashes
will not include this parameter.
### `crashReporter.getParameters()` ### `crashReporter.getParameters()`
See all of the current parameters being passed to the crash reporter. Returns `Record<String, String>` - The current 'extra' parameters of the crash reporter.
### `crashReporter.getCrashesDirectory()`
Returns `String` - The directory where crashes are temporarily stored before being uploaded.
## Crash Report Payload ## Crash Report Payload

View File

@@ -269,6 +269,7 @@ Shows a message box, it will block the process until the message box is closed.
It returns the index of the clicked button. It returns the index of the clicked button.
The `browserWindow` argument allows the dialog to attach itself to a parent window, making it modal. The `browserWindow` argument allows the dialog to attach itself to a parent window, making it modal.
If `browserWindow` is not shown dialog will not be attached to it. In such case It will be displayed as independed window.
### `dialog.showMessageBox([browserWindow, ]options)` ### `dialog.showMessageBox([browserWindow, ]options)`

View File

@@ -82,16 +82,12 @@ The API is only available in session's `will-download` callback function.
If user doesn't set the save path via the API, Electron will use the original If user doesn't set the save path via the API, Electron will use the original
routine to determine the save path; this usually prompts a save dialog. routine to determine the save path; this usually prompts a save dialog.
**[Deprecated](modernization/property-updates.md): use the `savePath` property instead.**
#### `downloadItem.getSavePath()` #### `downloadItem.getSavePath()`
Returns `String` - The save path of the download item. This will be either the path Returns `String` - The save path of the download item. This will be either the path
set via `downloadItem.setSavePath(path)` or the path selected from the shown set via `downloadItem.setSavePath(path)` or the path selected from the shown
save dialog. save dialog.
**[Deprecated](modernization/property-updates.md): use the `savePath` property instead.**
#### `downloadItem.setSaveDialogOptions(options)` #### `downloadItem.setSaveDialogOptions(options)`
* `options` SaveDialogOptions - Set the save file dialog options. This object has the same * `options` SaveDialogOptions - Set the save file dialog options. This object has the same

View File

@@ -53,16 +53,23 @@ Unsupported options are:
### `GOOGLE_API_KEY` ### `GOOGLE_API_KEY`
You can provide an API key for making requests to Google's geocoding webservice. To do this, place the following code in your main process Geolocation support in Electron requires the use of Google Cloud Platform's
file, before opening any browser windows that will make geocoding requests: geolocation webservice. To enable this feature, acquire a
[Google API key](https://developers.google.com/maps/documentation/geolocation/get-api-key)
and place the following code in your main process file, before opening any
browser windows that will make geolocation requests:
```javascript ```javascript
process.env.GOOGLE_API_KEY = 'YOUR_KEY_HERE' process.env.GOOGLE_API_KEY = 'YOUR_KEY_HERE'
``` ```
For instructions on how to acquire a Google API key, visit [this page](https://developers.google.com/maps/documentation/javascript/get-api-key). By default, a newly generated Google API key may not be allowed to make geolocation requests.
By default, a newly generated Google API key may not be allowed to make To enable the geolocation webservice for your project, enable it through the
geocoding requests. To enable geocoding requests, visit [this page](https://developers.google.com/maps/documentation/geocoding/get-api-key). [API library](https://console.cloud.google.com/apis/library).
N.B. You will need to add a
[Billing Account](https://cloud.google.com/billing/docs/how-to/payment-methods#add_a_payment_method)
to the project associated to the API key for the geolocation webservice to work.
### `ELECTRON_NO_ASAR` ### `ELECTRON_NO_ASAR`
@@ -128,3 +135,14 @@ the one downloaded by `npm install`. Usage:
```sh ```sh
export ELECTRON_OVERRIDE_DIST_PATH=/Users/username/projects/electron/out/Testing export ELECTRON_OVERRIDE_DIST_PATH=/Users/username/projects/electron/out/Testing
``` ```
## Set By Electron
Electron sets some variables in your environment at runtime.
### `ORIGINAL_XDG_CURRENT_DESKTOP`
This variable is set to the value of `XDG_CURRENT_DESKTOP` that your application
originally launched with. Electron sometimes modifies the value of `XDG_CURRENT_DESKTOP`
to affect other logic within Chromium so if you want access to the _original_ value
you should look up this environment variable instead.

101
docs/api/extensions.md Normal file
View File

@@ -0,0 +1,101 @@
# Chrome Extension Support
Electron supports a subset of the [Chrome Extensions
API][chrome-extensions-api-index], primarily to support DevTools extensions and
Chromium-internal extensions, but it also happens to support some other
extension capabilities.
[chrome-extensions-api-index]: https://developer.chrome.com/extensions/api_index
> **Note:** Electron does not support arbitrary Chrome extensions from the
> store, and it is a **non-goal** of the Electron project to be perfectly
> compatible with Chrome's implementation of Extensions.
## Loading extensions
Electron only supports loading unpacked extensions (i.e., `.crx` files do not
work). Extensions are installed per-`session`. To load an extension, call
[`ses.loadExtension`](session.md#sesloadextensionpath):
```js
const { session } = require('electron')
session.loadExtension('path/to/unpacked/extension').then(({ id }) => {
// ...
})
```
Loaded extensions will not be automatically remembered across exits; if you do
not call `loadExtension` when the app runs, the extension will not be loaded.
See the [`session`](session.md) documentation for more information about
loading, unloading, and querying active extensions.
## Supported Extensions APIs
We support the following extensions APIs, with some caveats. Other APIs may
additionally be supported, but support for any APIs not listed here is
provisional and may be removed.
### `chrome.devtools.inspectedWindow`
All features of this API are supported.
### `chrome.devtools.network`
All features of this API are supported.
### `chrome.devtools.panels`
All features of this API are supported.
### `chrome.extension`
The following properties of `chrome.extension` are supported:
- `chrome.extension.lastError`
The following methods of `chrome.extension` are supported:
- `chrome.extension.getURL`
- `chrome.extension.getBackgroundPage`
### `chrome.runtime`
The following properties of `chrome.runtime` are supported:
- `chrome.runtime.lastError`
- `chrome.runtime.id`
The following methods of `chrome.runtime` are supported:
- `chrome.runtime.getBackgroundPage`
- `chrome.runtime.getManifest`
- `chrome.runtime.getURL`
- `chrome.runtime.connect`
- `chrome.runtime.sendMessage`
The following events of `chrome.runtime` are supported:
- `chrome.runtime.onStartup`
- `chrome.runtime.onInstalled`
- `chrome.runtime.onSuspend`
- `chrome.runtime.onSuspendCanceled`
- `chrome.runtime.onConnect`
- `chrome.runtime.onMessage`
### `chrome.storage`
Only `chrome.storage.local` is supported; `chrome.storage.sync` and
`chrome.storage.managed` are not.
### `chrome.tabs`
The following methods of `chrome.tabs` are supported:
- `chrome.tabs.sendMessage`
- `chrome.tabs.executeScript`
> **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active
> tab". Since Electron has no such concept, passing `-1` as a tab ID is not
> supported and will raise an error.

View File

@@ -52,7 +52,7 @@ win.show()
Uses custom drawn close, and miniaturize buttons that display Uses custom drawn close, and miniaturize buttons that display
when hovering in the top left of the window. The fullscreen button when hovering in the top left of the window. The fullscreen button
is not available due to restrictions of frameless windows as they is not available due to restrictions of frameless windows as they
interface with Apple's MacOS window masks. These custom buttons prevent interface with Apple's macOS window masks. These custom buttons prevent
issues with mouse events that occur with the standard window toolbar buttons. issues with mouse events that occur with the standard window toolbar buttons.
This option is only applicable for frameless windows. This option is only applicable for frameless windows.
@@ -158,7 +158,7 @@ buttons in titlebar non-draggable.
## Text selection ## Text selection
In a frameless window the dragging behaviour may conflict with selecting text. In a frameless window the dragging behavior may conflict with selecting text.
For example, when you drag the titlebar you may accidentally select the text on For example, when you drag the titlebar you may accidentally select the text on
the titlebar. To prevent this, you need to disable text selection within a the titlebar. To prevent this, you need to disable text selection within a
draggable area like this: draggable area like this:

View File

@@ -14,7 +14,7 @@ See [`Menu`](menu.md) for examples.
* `menuItem` MenuItem * `menuItem` MenuItem
* `browserWindow` [BrowserWindow](browser-window.md) * `browserWindow` [BrowserWindow](browser-window.md)
* `event` [KeyboardEvent](structures/keyboard-event.md) * `event` [KeyboardEvent](structures/keyboard-event.md)
* `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `minimize`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the * `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
`click` property will be ignored. See [roles](#roles). `click` property will be ignored. See [roles](#roles).
* `type` String (optional) - Can be `normal`, `separator`, `submenu`, `checkbox` or * `type` String (optional) - Can be `normal`, `separator`, `submenu`, `checkbox` or
`radio`. `radio`.
@@ -69,6 +69,7 @@ a `type`.
The `role` property can have following values: The `role` property can have following values:
* `undo` * `undo`
* `about` - Trigger a native about panel (custom message box on Window, which does not provide its own).
* `redo` * `redo`
* `cut` * `cut`
* `copy` * `copy`
@@ -94,7 +95,6 @@ The `role` property can have following values:
The following additional roles are available on _macOS_: The following additional roles are available on _macOS_:
* `appMenu` - Whole default "App" menu (About, Services, etc.) * `appMenu` - Whole default "App" menu (About, Services, etc.)
* `about` - Map to the `orderFrontStandardAboutPanel` action.
* `hide` - Map to the `hide` action. * `hide` - Map to the `hide` action.
* `hideOthers` - Map to the `hideOtherApplications` action. * `hideOthers` - Map to the `hideOtherApplications` action.
* `unhide` - Map to the `unhideAllApplications` action. * `unhide` - Map to the `unhideAllApplications` action.
@@ -117,7 +117,7 @@ When specifying a `role` on macOS, `label` and `accelerator` are the only
options that will affect the menu item. All other options will be ignored. options that will affect the menu item. All other options will be ignored.
Lowercase `role`, e.g. `toggledevtools`, is still supported. Lowercase `role`, e.g. `toggledevtools`, is still supported.
**Nota Bene:** The `enabled` and `visibility` properties are not available for top-level menu items in the tray on MacOS. **Nota Bene:** The `enabled` and `visibility` properties are not available for top-level menu items in the tray on macOS.
### Instance Properties ### Instance Properties
@@ -151,7 +151,7 @@ A `String` indicating the type of the item. Can be `normal`, `separator`, `subme
#### `menuItem.role` #### `menuItem.role`
A `String` (optional) indicating the item's role, if set. Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `close`, `minimize`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` A `String` (optional) indicating the item's role, if set. Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu`
#### `menuItem.accelerator` #### `menuItem.accelerator`

View File

@@ -5,14 +5,7 @@ The Electron team is currently undergoing an initiative to convert separate gett
## Candidates ## Candidates
* `BrowserWindow` * `BrowserWindow`
* `fullscreen`
* `simpleFullscreen`
* `alwaysOnTop`
* `title`
* `documentEdited`
* `hasShadow`
* `menubarVisible` * `menubarVisible`
* `visibleOnAllWorkspaces`
* `crashReporter` module * `crashReporter` module
* `uploadToServer` * `uploadToServer`
* `webFrame` modules * `webFrame` modules
@@ -45,9 +38,3 @@ The Electron team is currently undergoing an initiative to convert separate gett
* `isMacTemplateImage` * `isMacTemplateImage`
* `SystemPreferences` module * `SystemPreferences` module
* `appLevelAppearance` * `appLevelAppearance`
* `webContents` module
* `audioMuted`
* `frameRate`
* `userAgent`
* `zoomFactor`
* `zoomLevel`

View File

@@ -276,14 +276,10 @@ Returns [`Size`](structures/size.md)
Marks the image as a template image. Marks the image as a template image.
**[Deprecated](modernization/property-updates.md)**
#### `image.isTemplateImage()` #### `image.isTemplateImage()`
Returns `Boolean` - Whether the image is a template image. Returns `Boolean` - Whether the image is a template image.
**[Deprecated](modernization/property-updates.md)**
#### `image.crop(rect)` #### `image.crop(rect)`
* `rect` [Rectangle](structures/rectangle.md) - The area of the image to crop. * `rect` [Rectangle](structures/rectangle.md) - The area of the image to crop.

View File

@@ -51,7 +51,7 @@ app.whenReady().then(() => {
In the above code the [`BrowserWindow`](browser-window.md) that was created has Node.js disabled and can communicate In the above code the [`BrowserWindow`](browser-window.md) that was created has Node.js disabled and can communicate
only via IPC. The use of this option stops Electron from creating a Node.js runtime in the renderer. Also, only via IPC. The use of this option stops Electron from creating a Node.js runtime in the renderer. Also,
within this new window `window.open` follows the native behaviour (by default Electron creates a [`BrowserWindow`](browser-window.md) within this new window `window.open` follows the native behavior (by default Electron creates a [`BrowserWindow`](browser-window.md)
and returns a proxy to this via `window.open`). and returns a proxy to this via `window.open`).
[`app.enableSandbox`](app.md#appenablesandbox-experimental) can be used to force `sandbox: true` for all `BrowserWindow` instances. [`app.enableSandbox`](app.md#appenablesandbox-experimental) can be used to force `sandbox: true` for all `BrowserWindow` instances.

View File

@@ -0,0 +1,62 @@
## Class: ServiceWorkers
> Query and receive events from a sessions active service workers.
Process: [Main](../glossary.md#main-process)
Instances of the `ServiceWorkers` class are accessed by using `serviceWorkers` property of
a `Session`.
For example:
```javascript
const { session } = require('electron')
// Get all service workers.
console.log(session.defaultSession.serviceWorkers.getAllRunning())
// Handle logs and get service worker info
session.defaultSession.serviceWorkers.on('console-message', (event, messageDetails) => {
console.log(
'Got service worker message',
messageDetails,
'from',
session.defaultSession.serviceWorkers.getFromVersionID(messageDetails.versionId)
)
})
```
### Instance Events
The following events are available on instances of `ServiceWorkers`:
#### Event: 'console-message'
Returns:
* `event` Event
* `messageDetails` Object - Information about the console message
* `message` String - The actual console message
* `versionId` Number - The version ID of the service worker that sent the log message
* `source` String - The type of source for this message. Can be `javascript`, `xml`, `network`, `console-api`, `storage`, `app-cache`, `rendering`, `security`, `deprecation`, `worker`, `violation`, `intervention`, `recommendation` or `other`.
* `level` Number - The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and `error`.
* `sourceUrl` String - The URL the message came from
* `lineNumber` Number - The line number of the source that triggered this console message
Emitted when a service worker logs something to the console.
### Instance Methods
The following methods are available on instances of `ServiceWorkers`:
#### `serviceWorkers.getAllRunning()`
Returns `Record<Number, ServiceWorkerInfo>` - A [ServiceWorkerInfo](structures/service-worker-info.md) object where the keys are the service worker version ID and the values are the information about that service worker.
#### `serviceWorkers.getFromVersionID(versionId)`
* `versionId` Number
Returns [`ServiceWorkerInfo`](structures/service-worker-info.md) - Information about this service worker
If the service worker does not exist or is not running this method will throw an exception.

View File

@@ -105,6 +105,45 @@ Returns:
Emitted when a render process requests preconnection to a URL, generally due to Emitted when a render process requests preconnection to a URL, generally due to
a [resource hint](https://w3c.github.io/resource-hints/). a [resource hint](https://w3c.github.io/resource-hints/).
#### Event: 'spellcheck-dictionary-initialized'
Returns:
* `event` Event
* `languageCode` String - The language code of the dictionary file
Emitted when a hunspell dictionary file has been successfully initialized. This
occurs after the file has been downloaded.
#### Event: 'spellcheck-dictionary-download-begin'
Returns:
* `event` Event
* `languageCode` String - The language code of the dictionary file
Emitted when a hunspell dictionary file starts downloading
#### Event: 'spellcheck-dictionary-download-success'
Returns:
* `event` Event
* `languageCode` String - The language code of the dictionary file
Emitted when a hunspell dictionary file has been successfully downloaded
#### Event: 'spellcheck-dictionary-download-failure'
Returns:
* `event` Event
* `languageCode` String - The language code of the dictionary file
Emitted when a hunspell dictionary file download fails. For details
on the failure you should collect a netlog and inspect the download
request.
### Instance Methods ### Instance Methods
The following methods are available on instances of `Session`: The following methods are available on instances of `Session`:
@@ -483,18 +522,38 @@ setting with the current OS locale. This setting is persisted across restarts.
By default Electron will download hunspell dictionaries from the Chromium CDN. If you want to override this By default Electron will download hunspell dictionaries from the Chromium CDN. If you want to override this
behavior you can use this API to point the dictionary downloader at your own hosted version of the hunspell behavior you can use this API to point the dictionary downloader at your own hosted version of the hunspell
dictionaries. We publish a `hunspell_dictionaries.zip` file with each release which contains the files you need dictionaries. We publish a `hunspell_dictionaries.zip` file with each release which contains the files you need
to host here. to host here, the file server must be **case insensitive** you must upload each file twice, once with the case it
has in the ZIP file and once with the filename as all lower case.
If the files present in `hunspell_dictionaries.zip` are available at `https://example.com/dictionaries/language-code.bdic`
then you should call this api with `ses.setSpellCheckerDictionaryDownloadURL('https://example.com/dictionaries/')`. Please
note the trailing slash. The URL to the dictionaries is formed as `${url}${filename}`.
**Note:** On macOS the OS spellchecker is used and therefore we do not download any dictionary files. This API is a no-op on macOS. **Note:** On macOS the OS spellchecker is used and therefore we do not download any dictionary files. This API is a no-op on macOS.
#### `ses.listWordsInSpellCheckerDictionary()`
Returns `Promise<String[]>` - An array of all words in app's custom dictionary.
Resolves when the full dictionary is loaded from disk.
#### `ses.addWordToSpellCheckerDictionary(word)` #### `ses.addWordToSpellCheckerDictionary(word)`
* `word` String - The word you want to add to the dictionary * `word` String - The word you want to add to the dictionary
Returns `Boolean` - Whether the word was successfully written to the custom dictionary. Returns `Boolean` - Whether the word was successfully written to the custom dictionary. This API
will not work on non-persistent (in-memory) sessions.
**Note:** On macOS and Windows 10 this word will be written to the OS custom dictionary as well **Note:** On macOS and Windows 10 this word will be written to the OS custom dictionary as well
#### `ses.removeWordFromSpellCheckerDictionary(word)`
* `word` String - The word you want to remove from the dictionary
Returns `Boolean` - Whether the word was successfully removed from the custom dictionary. This API
will not work on non-persistent (in-memory) sessions.
**Note:** On macOS and Windows 10 this word will be removed from the OS custom dictionary as well
#### `ses.loadExtension(path)` #### `ses.loadExtension(path)`
* `path` String - Path to a directory containing an unpacked Chrome extension * `path` String - Path to a directory containing an unpacked Chrome extension
@@ -567,6 +626,10 @@ code to the `setSpellCheckerLanaguages` API that isn't in this array will result
A [`Cookies`](cookies.md) object for this session. A [`Cookies`](cookies.md) object for this session.
#### `ses.serviceWorkers` _Readonly_
A [`ServiceWorkers`](service-workers.md) object for this session.
#### `ses.webRequest` _Readonly_ #### `ses.webRequest` _Readonly_
A [`WebRequest`](web-request.md) object for this session. A [`WebRequest`](web-request.md) object for this session.

View File

@@ -1,5 +1,8 @@
# Extension Object # Extension Object
* `id` String * `id` String
* `manifest` any - Copy of the [extension's manifest data](https://developer.chrome.com/extensions/manifest).
* `name` String * `name` String
* `path` String - The extension's file path.
* `version` String * `version` String
* `url` String - The extension's `chrome-extension://` URL.

View File

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

View File

@@ -0,0 +1,5 @@
# ServiceWorkerInfo Object
* `scriptUrl` String - The full URL to the script that this service worker runs
* `scope` String - The base URL that this service worker is active for.
* `renderProcessId` Number - The virtual ID of the process that this service worker is running in. This is not an OS level PID. This aligns with the ID set used for `webContents.getProcessId()`.

View File

@@ -326,7 +326,7 @@ This API is only available on macOS 10.14 Mojave or newer.
* `window-frame-text` - The text in the window's titlebar area. * `window-frame-text` - The text in the window's titlebar area.
Returns `String` - The system color setting in RGB hexadecimal form (`#ABCDEF`). Returns `String` - The system color setting in RGB hexadecimal form (`#ABCDEF`).
See the [Windows docs][windows-colors] and the [MacOS docs][macos-colors] for more details. See the [Windows docs][windows-colors] and the [macOS docs][macos-colors] for more details.
The following colors are only available on macOS 10.14: `find-highlight`, `selected-content-background`, `separator`, `unemphasized-selected-content-background`, `unemphasized-selected-text-background`, and `unemphasized-selected-text`. The following colors are only available on macOS 10.14: `find-highlight`, `selected-content-background`, `separator`, `unemphasized-selected-content-background`, `unemphasized-selected-text-background`, and `unemphasized-selected-text`.
@@ -360,7 +360,7 @@ Returns `Boolean` - `true` if an inverted color scheme (a high contrast color sc
Returns `Boolean` - `true` if a high contrast theme is active, `false` otherwise. Returns `Boolean` - `true` if a high contrast theme is active, `false` otherwise.
**Depreacted:** Should use the new [`nativeTheme.shouldUseHighContrastColors`](native-theme.md#nativethemeshouldusehighcontrastcolors-macos-windows-readonly) API. **Deprecated:** Should use the new [`nativeTheme.shouldUseHighContrastColors`](native-theme.md#nativethemeshouldusehighcontrastcolors-macos-windows-readonly) API.
### `systemPreferences.getEffectiveAppearance()` _macOS_ ### `systemPreferences.getEffectiveAppearance()` _macOS_
@@ -369,16 +369,6 @@ Returns `String` - Can be `dark`, `light` or `unknown`.
Gets the macOS appearance setting that is currently applied to your application, Gets the macOS appearance setting that is currently applied to your application,
maps to [NSApplication.effectiveAppearance](https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc) maps to [NSApplication.effectiveAppearance](https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc)
Please note that until Electron is built targeting the 10.14 SDK, your application's
`effectiveAppearance` will default to 'light' and won't inherit the OS preference. In
the interim in order for your application to inherit the OS preference you must set the
`NSRequiresAquaSystemAppearance` key in your apps `Info.plist` to `false`. If you are
using `electron-packager` or `electron-forge` just set the `enableDarwinDarkMode`
packager option to `true`. See the [Electron Packager API](https://github.com/electron/electron-packager/blob/master/docs/api.md#darwindarkmodesupport)
for more details.
**[Deprecated](modernization/property-updates.md)**
### `systemPreferences.getAppLevelAppearance()` _macOS_ _Deprecated_ ### `systemPreferences.getAppLevelAppearance()` _macOS_ _Deprecated_
Returns `String` | `null` - Can be `dark`, `light` or `unknown`. Returns `String` | `null` - Can be `dark`, `light` or `unknown`.
@@ -387,8 +377,6 @@ Gets the macOS appearance setting that you have declared you want for
your application, maps to [NSApplication.appearance](https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc). your application, maps to [NSApplication.appearance](https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc).
You can use the `setAppLevelAppearance` API to set this value. You can use the `setAppLevelAppearance` API to set this value.
**[Deprecated](modernization/property-updates.md)**
### `systemPreferences.setAppLevelAppearance(appearance)` _macOS_ _Deprecated_ ### `systemPreferences.setAppLevelAppearance(appearance)` _macOS_ _Deprecated_
* `appearance` String | null - Can be `dark` or `light` * `appearance` String | null - Can be `dark` or `light`
@@ -396,16 +384,12 @@ You can use the `setAppLevelAppearance` API to set this value.
Sets the appearance setting for your application, this should override the Sets the appearance setting for your application, this should override the
system default and override the value of `getEffectiveAppearance`. system default and override the value of `getEffectiveAppearance`.
**[Deprecated](modernization/property-updates.md)**
### `systemPreferences.canPromptTouchID()` _macOS_ ### `systemPreferences.canPromptTouchID()` _macOS_
Returns `Boolean` - whether or not this device has the ability to use Touch ID. Returns `Boolean` - whether or not this device has the ability to use Touch ID.
**NOTE:** This API will return `false` on macOS systems older than Sierra 10.12.2. **NOTE:** This API will return `false` on macOS systems older than Sierra 10.12.2.
**[Deprecated](modernization/property-updates.md)**
### `systemPreferences.promptTouchID(reason)` _macOS_ ### `systemPreferences.promptTouchID(reason)` _macOS_
* `reason` String - The reason you are asking for Touch ID authentication * `reason` String - The reason you are asking for Touch ID authentication
@@ -480,11 +464,3 @@ A `String` property that can be `dark`, `light` or `unknown`.
Returns the macOS appearance setting that is currently applied to your application, Returns the macOS appearance setting that is currently applied to your application,
maps to [NSApplication.effectiveAppearance](https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc) maps to [NSApplication.effectiveAppearance](https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc)
Please note that until Electron is built targeting the 10.14 SDK, your application's
`effectiveAppearance` will default to 'light' and won't inherit the OS preference. In
the interim in order for your application to inherit the OS preference you must set the
`NSRequiresAquaSystemAppearance` key in your apps `Info.plist` to `false`. If you are
using `electron-packager` or `electron-forge` just set the `enableDarwinDarkMode`
packager option to `true`. See the [Electron Packager API](https://github.com/electron/electron-packager/blob/master/docs/api.md#darwindarkmodesupport)
for more details.

View File

@@ -138,7 +138,7 @@ Emitted when page receives favicon urls.
Returns: Returns:
* `event` Event * `event` NewWindowEvent
* `url` String * `url` String
* `frameName` String * `frameName` String
* `disposition` String - Can be `default`, `foreground-tab`, `background-tab`, * `disposition` String - Can be `default`, `foreground-tab`, `background-tab`,
@@ -871,10 +871,10 @@ Returns `String` - The URL of the current web page.
```javascript ```javascript
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
let win = new BrowserWindow({ width: 800, height: 600 }) let win = new BrowserWindow({ width: 800, height: 600 })
win.loadURL('http://github.com') win.loadURL('http://github.com').then(() => {
const currentURL = win.webContents.getURL()
let currentURL = win.webContents.getURL() console.log(currentURL)
console.log(currentURL) })
``` ```
#### `contents.getTitle()` #### `contents.getTitle()`
@@ -967,14 +967,10 @@ Returns `Boolean` - Whether the renderer process has crashed.
Overrides the user agent for this web page. Overrides the user agent for this web page.
**[Deprecated](modernization/property-updates.md)**
#### `contents.getUserAgent()` #### `contents.getUserAgent()`
Returns `String` - The user agent for this web page. Returns `String` - The user agent for this web page.
**[Deprecated](modernization/property-updates.md)**
#### `contents.insertCSS(css[, options])` #### `contents.insertCSS(css[, options])`
* `css` String * `css` String
@@ -1054,33 +1050,27 @@ Ignore application menu shortcuts while this web contents is focused.
Mute the audio on the current web page. Mute the audio on the current web page.
**[Deprecated](modernization/property-updates.md)**
#### `contents.isAudioMuted()` #### `contents.isAudioMuted()`
Returns `Boolean` - Whether this page has been muted. Returns `Boolean` - Whether this page has been muted.
**[Deprecated](modernization/property-updates.md)**
#### `contents.isCurrentlyAudible()` #### `contents.isCurrentlyAudible()`
Returns `Boolean` - Whether audio is currently playing. Returns `Boolean` - Whether audio is currently playing.
#### `contents.setZoomFactor(factor)` #### `contents.setZoomFactor(factor)`
* `factor` Number - Zoom factor. * `factor` Double - Zoom factor; default is 1.0.
Changes the zoom factor to the specified factor. Zoom factor is Changes the zoom factor to the specified factor. Zoom factor is
zoom percent divided by 100, so 300% = 3.0. zoom percent divided by 100, so 300% = 3.0.
**[Deprecated](modernization/property-updates.md)** The factor must be greater than 0.0.
#### `contents.getZoomFactor()` #### `contents.getZoomFactor()`
Returns `Number` - the current zoom factor. Returns `Number` - the current zoom factor.
**[Deprecated](modernization/property-updates.md)**
#### `contents.setZoomLevel(level)` #### `contents.setZoomLevel(level)`
* `level` Number - Zoom level. * `level` Number - Zoom level.
@@ -1090,14 +1080,10 @@ increment above or below represents zooming 20% larger or smaller to default
limits of 300% and 50% of original size, respectively. The formula for this is limits of 300% and 50% of original size, respectively. The formula for this is
`scale := 1.2 ^ level`. `scale := 1.2 ^ level`.
**[Deprecated](modernization/property-updates.md)**
#### `contents.getZoomLevel()` #### `contents.getZoomLevel()`
Returns `Number` - the current zoom level. Returns `Number` - the current zoom level.
**[Deprecated](modernization/property-updates.md)**
#### `contents.setVisualZoomLevelLimits(minimumLevel, maximumLevel)` #### `contents.setVisualZoomLevelLimits(minimumLevel, maximumLevel)`
* `minimumLevel` Number * `minimumLevel` Number
@@ -1286,7 +1272,7 @@ Returns [`PrinterInfo[]`](structures/printer-info.md)
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`. `A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`.
* `callback` Function (optional) * `callback` Function (optional)
* `success` Boolean - Indicates success of the print call. * `success` Boolean - Indicates success of the print call.
* `failureReason` String - Called back if the print fails; can be `cancelled` or `failed`. * `failureReason` String - Error description called back if the print fails.
Prints window's web page. When `silent` is set to `true`, Electron will pick Prints window's web page. When `silent` is set to `true`, Electron will pick
the system's default printer if `deviceName` is empty and the default settings for printing. the system's default printer if `deviceName` is empty and the default settings for printing.
@@ -1709,14 +1695,10 @@ Returns `Boolean` - If *offscreen rendering* is enabled returns whether it is cu
If *offscreen rendering* is enabled sets the frame rate to the specified number. If *offscreen rendering* is enabled sets the frame rate to the specified number.
Only values between 1 and 60 are accepted. Only values between 1 and 60 are accepted.
**[Deprecated](modernization/property-updates.md)**
#### `contents.getFrameRate()` #### `contents.getFrameRate()`
Returns `Integer` - If *offscreen rendering* is enabled returns the current frame rate. Returns `Integer` - If *offscreen rendering* is enabled returns the current frame rate.
**[Deprecated](modernization/property-updates.md)**
#### `contents.invalidate()` #### `contents.invalidate()`
Schedules a full repaint of the window this web contents is in. Schedules a full repaint of the window this web contents is in.
@@ -1822,7 +1804,7 @@ A [`WebContents`](web-contents.md) instance that might own this `WebContents`.
#### `contents.devToolsWebContents` _Readonly_ #### `contents.devToolsWebContents` _Readonly_
A `WebContents` of DevTools for this `WebContents`. A `WebContents | null` property that represents the of DevTools `WebContents` associated with a given `WebContents`.
**Note:** Users should never store this object because it may become `null` **Note:** Users should never store this object because it may become `null`
when the DevTools has been closed. when the DevTools has been closed.

View File

@@ -22,11 +22,13 @@ The `WebFrame` class has the following instance methods:
### `webFrame.setZoomFactor(factor)` ### `webFrame.setZoomFactor(factor)`
* `factor` Number - Zoom factor. * `factor` Double - Zoom factor; default is 1.0.
Changes the zoom factor to the specified factor. Zoom factor is Changes the zoom factor to the specified factor. Zoom factor is
zoom percent divided by 100, so 300% = 3.0. zoom percent divided by 100, so 300% = 3.0.
The factor must be greater than 0.0.
### `webFrame.getZoomFactor()` ### `webFrame.getZoomFactor()`
Returns `Number` - The current zoom factor. Returns `Number` - The current zoom factor.
@@ -122,13 +124,20 @@ by its key, which is returned from `webFrame.insertCSS(css)`.
Inserts `text` to the focused element. Inserts `text` to the focused element.
### `webFrame.executeJavaScript(code[, userGesture])` ### `webFrame.executeJavaScript(code[, userGesture, callback])`
* `code` String * `code` String
* `userGesture` Boolean (optional) - Default is `false`. * `userGesture` Boolean (optional) - Default is `false`.
* `callback` Function (optional) - Called after script has been executed. Unless
the frame is suspended (e.g. showing a modal alert), execution will be
synchronous and the callback will be invoked before the method returns. For
compatibility with an older version of this method, the error parameter is
second.
* `result` Any
* `error` Error
Returns `Promise<any>` - A promise that resolves with the result of the executed code Returns `Promise<any>` - A promise that resolves with the result of the executed
or is rejected if the result of the code is a rejected promise. code or is rejected if execution throws or results in a rejected promise.
Evaluates `code` in page. Evaluates `code` in page.
@@ -136,17 +145,31 @@ In the browser window some HTML APIs like `requestFullScreen` can only be
invoked by a gesture from the user. Setting `userGesture` to `true` will remove invoked by a gesture from the user. Setting `userGesture` to `true` will remove
this limitation. this limitation.
### `webFrame.executeJavaScriptInIsolatedWorld(worldId, scripts[, userGesture])` ### `webFrame.executeJavaScriptInIsolatedWorld(worldId, scripts[, userGesture, callback])`
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electrons `contextIsolation` feature. You can provide any integer here. * `worldId` Integer - The ID of the world to run the javascript
in, `0` is the default main world (where content runs), `999` is the
world used by Electron's `contextIsolation` feature. Accepts values
in the range 1..536870911.
* `scripts` [WebSource[]](structures/web-source.md) * `scripts` [WebSource[]](structures/web-source.md)
* `userGesture` Boolean (optional) - Default is `false`. * `userGesture` Boolean (optional) - Default is `false`.
* `callback` Function (optional) - Called after script has been executed. Unless
the frame is suspended (e.g. showing a modal alert), execution will be
synchronous and the callback will be invoked before the method returns. For
compatibility with an older version of this method, the error parameter is
second.
* `result` Any
* `error` Error
Returns `Promise<any>` - A promise that resolves with the result of the executed code Returns `Promise<any>` - A promise that resolves with the result of the executed
or is rejected if the result of the code is a rejected promise. code or is rejected if execution could not start.
Works like `executeJavaScript` but evaluates `scripts` in an isolated context. Works like `executeJavaScript` but evaluates `scripts` in an isolated context.
Note that when the execution of script fails, the returned promise will not
reject and the `result` would be `undefined`. This is because Chromium does not
dispatch errors of isolated worlds to foreign worlds.
### `webFrame.setIsolatedWorldInfo(worldId, info)` ### `webFrame.setIsolatedWorldInfo(worldId, info)`
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electrons `contextIsolation` feature. Chrome extensions reserve the range of IDs in `[1 << 20, 1 << 29)`. You can provide any integer here. * `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electrons `contextIsolation` feature. Chrome extensions reserve the range of IDs in `[1 << 20, 1 << 29)`. You can provide any integer here.
* `info` Object * `info` Object

View File

@@ -146,6 +146,7 @@ response are visible by the time this listener is fired.
* `timestamp` Double * `timestamp` Double
* `statusLine` String * `statusLine` String
* `statusCode` Integer * `statusCode` Integer
* `requestHeaders` Record<string, string>
* `responseHeaders` Record<string, string[]> (optional) * `responseHeaders` Record<string, string[]> (optional)
* `callback` Function * `callback` Function
* `headersReceivedResponse` Object * `headersReceivedResponse` Object
@@ -228,6 +229,7 @@ redirect is about to occur.
* `fromCache` Boolean * `fromCache` Boolean
* `statusCode` Integer * `statusCode` Integer
* `statusLine` String * `statusLine` String
* `error` String
The `listener` will be called with `listener(details)` when a request is The `listener` will be called with `listener(details)` when a request is
completed. completed.

View File

@@ -2,13 +2,124 @@
Breaking changes will be documented here, and deprecation warnings added to JS code where possible, at least [one major version](tutorial/electron-versioning.md#semver) before the change is made. Breaking changes will be documented here, and deprecation warnings added to JS code where possible, at least [one major version](tutorial/electron-versioning.md#semver) before the change is made.
## `FIXME` comments ### Types of Breaking Changes
The `FIXME` string is used in code comments to denote things that should be fixed for future releases. See https://github.com/electron/electron/search?q=fixme This document uses the following convention to categorize breaking changes:
- **API Changed:** An API was changed in such a way that code that has not been updated is guaranteed to throw an exception.
- **Behavior Changed:** The behavior of Electron has changed, but not in such a way that an exception will necessarily be thrown.
- **Default Changed:** Code depending on the old default may break, not necessarily throwing an exception. The old behavior can be restored by explicitly specifying the value.
- **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
- **Removed:** An API or feature was removed, and is no longer supported by Electron.
## Planned Breaking API Changes (12.0)
### Removed: `crashReporter` methods in the renderer process
The following `crashReporter` methods are no longer available in the renderer
process:
- `crashReporter.start`
- `crashReporter.getLastCrashReport`
- `crashReporter.getUploadedReports`
- `crashReporter.getUploadToServer`
- `crashReporter.setUploadToServer`
- `crashReporter.getCrashesDirectory`
They should be called only from the main process.
See [#23265](https://github.com/electron/electron/pull/23265) for more details.
## Planned Breaking API Changes (11.0)
## Planned Breaking API Changes (10.0)
### Deprecated: `companyName` argument to `crashReporter.start()`
The `companyName` argument to `crashReporter.start()`, which was previously
required, is now optional, and further, is deprecated. To get the same
behavior in a non-deprecated way, you can pass a `companyName` value in
`globalExtra`.
```js
// Deprecated in Electron 10
crashReporter.start({ companyName: 'Umbrella Corporation' })
// Replace with
crashReporter.start({ globalExtra: { _companyName: 'Umbrella Corporation' } })
```
### Deprecated: `crashReporter.getCrashesDirectory()`
The `crashReporter.getCrashesDirectory` method has been deprecated. Usage
should be replaced by `app.getPath('crashDumps')`.
```js
// Deprecated in Electron 10
crashReporter.getCrashesDirectory()
// Replace with
app.getPath('crashDumps')
```
### Deprecated: `crashReporter` methods in the renderer process
Calling the following `crashReporter` methods from the renderer process is
deprecated:
- `crashReporter.start`
- `crashReporter.getLastCrashReport`
- `crashReporter.getUploadedReports`
- `crashReporter.getUploadToServer`
- `crashReporter.setUploadToServer`
- `crashReporter.getCrashesDirectory`
The only non-deprecated methods remaining in the `crashReporter` module in the
renderer are `addExtraParameter`, `removeExtraParameter` and `getParameters`.
All above methods remain non-deprecated when called from the main process.
See [#23265](https://github.com/electron/electron/pull/23265) for more details.
### Removed: Browser Window Affinity
The `affinity` option when constructing a new `BrowserWindow` will be removed
as part of our plan to more closely align with Chromium's process model for security,
performance and maintainability.
For more detailed information see [#18397](https://github.com/electron/electron/issues/18397).
### Default Changed: `enableRemoteModule` defaults to `false`
In Electron 9, using the remote module without explicitly enabling it via the
`enableRemoteModule` WebPreferences option began emitting a warning. In
Electron 10, the remote module is now disabled by default. To use the remote
module, `enableRemoteModule: true` must be specified in WebPreferences:
```js
const w = new BrowserWindow({
webPreferences: {
enableRemoteModule: true
}
})
```
We [recommend moving away from the remote
module](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31).
## Planned Breaking API Changes (9.0) ## Planned Breaking API Changes (9.0)
### `<webview>.getWebContents()` ### Default Changed: Loading non-context-aware native modules in the renderer process is disabled by default
As of Electron 9 we do not allow loading of non-context-aware native modules in
the renderer process. This is to improve security, performance and maintainability
of Electron as a project.
If this impacts you, you can temporarily set `app.allowRendererProcessReuse` to `false`
to revert to the old behavior. This flag will only be an option until Electron 11 so
you should plan to update your native modules to be context aware.
For more detailed information see [#18397](https://github.com/electron/electron/issues/18397).
### Removed: `<webview>.getWebContents()`
This API, which was deprecated in Electron 8.0, is now removed. This API, which was deprecated in Electron 8.0, is now removed.
@@ -20,7 +131,7 @@ const { remote } = require('electron')
remote.webContents.fromId(webview.getWebContentsId()) remote.webContents.fromId(webview.getWebContentsId())
``` ```
### `webFrame.setLayoutZoomLevelLimits()` ### Removed: `webFrame.setLayoutZoomLevelLimits()`
Chromium has removed support for changing the layout zoom level limits, and it Chromium has removed support for changing the layout zoom level limits, and it
is beyond Electron's capacity to maintain it. The function was deprecated in is beyond Electron's capacity to maintain it. The function was deprecated in
@@ -28,7 +139,7 @@ Electron 8.x, and has been removed in Electron 9.x. The layout zoom level limits
are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11). [here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
### Sending non-JS objects over IPC now throws an exception ### Behavior Changed: Sending non-JS objects over IPC now throws an exception
In Electron 8.0, IPC was changed to use the Structured Clone Algorithm, In Electron 8.0, IPC was changed to use the Structured Clone Algorithm,
bringing significant performance improvements. To help ease the transition, the bringing significant performance improvements. To help ease the transition, the
@@ -44,9 +155,14 @@ In Electron 9.0, the old serialization algorithm has been removed, and sending
such non-serializable objects will now throw an "object could not be cloned" such non-serializable objects will now throw an "object could not be cloned"
error. error.
### API Changed: `shell.openItem` is now `shell.openPath`
The `shell.openItem` API has been replaced with an asynchronous `shell.openPath` API.
You can see the original API proposal and reasoning [here](https://github.com/electron/governance/blob/master/wg-api/spec-documents/shell-openitem.md).
## Planned Breaking API Changes (8.0) ## Planned Breaking API Changes (8.0)
### Values sent over IPC are now serialized with Structured Clone Algorithm ### Behavior Changed: Values sent over IPC are now serialized with Structured Clone Algorithm
The algorithm used to serialize objects sent over IPC (through The algorithm used to serialize objects sent over IPC (through
`ipcRenderer.send`, `ipcRenderer.sendSync`, `WebContents.send` and related `ipcRenderer.send`, `ipcRenderer.sendSync`, `WebContents.send` and related
@@ -97,7 +213,7 @@ these kinds of objects will throw a 'could not be cloned' error.
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm [SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
### `<webview>.getWebContents()` ### Deprecated: `<webview>.getWebContents()`
This API is implemented using the `remote` module, which has both performance This API is implemented using the `remote` module, which has both performance
and security implications. Therefore its usage should be explicit. and security implications. Therefore its usage should be explicit.
@@ -138,7 +254,7 @@ const { ipcRenderer } = require('electron')
ipcRenderer.invoke('openDevTools', webview.getWebContentsId()) ipcRenderer.invoke('openDevTools', webview.getWebContentsId())
``` ```
### `webFrame.setLayoutZoomLevelLimits()` ### Deprecated: `webFrame.setLayoutZoomLevelLimits()`
Chromium has removed support for changing the layout zoom level limits, and it Chromium has removed support for changing the layout zoom level limits, and it
is beyond Electron's capacity to maintain it. The function will emit a warning is beyond Electron's capacity to maintain it. The function will emit a warning
@@ -148,7 +264,7 @@ limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
## Planned Breaking API Changes (7.0) ## Planned Breaking API Changes (7.0)
### Node Headers URL ### Deprecated: Atom.io Node Headers URL
This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url` This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url`
command line flag when building native Node modules. Both will be supported for command line flag when building native Node modules. Both will be supported for
@@ -158,7 +274,7 @@ Deprecated: https://atom.io/download/electron
Replace with: https://electronjs.org/headers Replace with: https://electronjs.org/headers
### `session.clearAuthCache(options)` ### API Changed: `session.clearAuthCache()` no longer accepts options
The `session.clearAuthCache` API no longer accepts options for what to clear, and instead unconditionally clears the whole cache. The `session.clearAuthCache` API no longer accepts options for what to clear, and instead unconditionally clears the whole cache.
@@ -169,25 +285,25 @@ session.clearAuthCache({ type: 'password' })
session.clearAuthCache() session.clearAuthCache()
``` ```
### `powerMonitor.querySystemIdleState` ### API Changed: `powerMonitor.querySystemIdleState` is now `powerMonitor.getSystemIdleState`
```js ```js
// Removed in Electron 7.0 // Removed in Electron 7.0
powerMonitor.querySystemIdleState(threshold, callback) powerMonitor.querySystemIdleState(threshold, callback)
// Replace with synchronous API // Replace with synchronous API
const idleState = getSystemIdleState(threshold) const idleState = powerMonitor.getSystemIdleState(threshold)
``` ```
### `powerMonitor.querySystemIdleTime` ### API Changed: `powerMonitor.querySystemIdleTime` is now `powerMonitor.getSystemIdleState`
```js ```js
// Removed in Electron 7.0 // Removed in Electron 7.0
powerMonitor.querySystemIdleTime(callback) powerMonitor.querySystemIdleTime(callback)
// Replace with synchronous API // Replace with synchronous API
const idleTime = getSystemIdleTime() const idleTime = powerMonitor.getSystemIdleTime()
``` ```
### webFrame Isolated World APIs ### API Changed: `webFrame.setIsolatedWorldInfo` replaces separate methods
```js ```js
// Removed in Electron 7.0 // Removed in Electron 7.0
@@ -204,11 +320,11 @@ webFrame.setIsolatedWorldInfo(
}) })
``` ```
### Removal of deprecated `marked` property on getBlinkMemoryInfo ### Removed: `marked` property on `getBlinkMemoryInfo`
This property was removed in Chromium 77, and as such is no longer available. This property was removed in Chromium 77, and as such is no longer available.
### `webkitdirectory` attribute for `<input type="file"/>` ### Behavior Changed: `webkitdirectory` attribute for `<input type="file"/>` now lists directory contents
The `webkitdirectory` property on HTML file inputs allows them to select folders. The `webkitdirectory` property on HTML file inputs allows them to select folders.
Previous versions of Electron had an incorrect implementation where the `event.target.files` Previous versions of Electron had an incorrect implementation where the `event.target.files`
@@ -241,9 +357,10 @@ In Electron 7, this now returns a `FileList` with a `File` object for:
Note that `webkitdirectory` no longer exposes the path to the selected folder. Note that `webkitdirectory` no longer exposes the path to the selected folder.
If you require the path to the selected folder rather than the folder contents, If you require the path to the selected folder rather than the folder contents,
see the `dialog.showOpenDialog` API ([link](https://github.com/electron/electron/blob/master/docs/api/dialog.md#dialogshowopendialogbrowserwindow-options)). see the `dialog.showOpenDialog` API ([link](https://github.com/electron/electron/blob/master/docs/api/dialog.md#dialogshowopendialogbrowserwindow-options)).
## Planned Breaking API Changes (6.0) ## Planned Breaking API Changes (6.0)
### `win.setMenu(null)` ### API Changed: `win.setMenu(null)` is now `win.removeMenu()`
```js ```js
// Deprecated // Deprecated
@@ -252,7 +369,7 @@ win.setMenu(null)
win.removeMenu() win.removeMenu()
``` ```
### `contentTracing.getTraceBufferUsage()` ### API Changed: `contentTracing.getTraceBufferUsage()` is now a promise
```js ```js
// Deprecated // Deprecated
@@ -265,7 +382,7 @@ contentTracing.getTraceBufferUsage().then(infoObject => {
}) })
``` ```
### `electron.screen` in renderer process ### API Changed: `electron.screen` in the renderer process should be accessed via `remote`
```js ```js
// Deprecated // Deprecated
@@ -274,7 +391,7 @@ require('electron').screen
require('electron').remote.screen require('electron').remote.screen
``` ```
### `require` in sandboxed renderers ### API Changed: `require()`ing node builtins in sandboxed renderers no longer implicitly loads the `remote` version
```js ```js
// Deprecated // Deprecated
@@ -298,25 +415,25 @@ require('path')
require('electron').remote.require('path') require('electron').remote.require('path')
``` ```
### `powerMonitor.querySystemIdleState` ### Deprecated: `powerMonitor.querySystemIdleState` replaced with `powerMonitor.getSystemIdleState`
```js ```js
// Deprecated // Deprecated
powerMonitor.querySystemIdleState(threshold, callback) powerMonitor.querySystemIdleState(threshold, callback)
// Replace with synchronous API // Replace with synchronous API
const idleState = getSystemIdleState(threshold) const idleState = powerMonitor.getSystemIdleState(threshold)
``` ```
### `powerMonitor.querySystemIdleTime` ### Deprecated: `powerMonitor.querySystemIdleTime` replaced with `powerMonitor.getSystemIdleTime`
```js ```js
// Deprecated // Deprecated
powerMonitor.querySystemIdleTime(callback) powerMonitor.querySystemIdleTime(callback)
// Replace with synchronous API // Replace with synchronous API
const idleTime = getSystemIdleTime() const idleTime = powerMonitor.getSystemIdleTime()
``` ```
### `app.enableMixedSandbox` ### Deprecated: `app.enableMixedSandbox()` is no longer needed
```js ```js
// Deprecated // Deprecated
@@ -325,7 +442,7 @@ app.enableMixedSandbox()
Mixed-sandbox mode is now enabled by default. Mixed-sandbox mode is now enabled by default.
### `Tray` ### Deprecated: `Tray.setHighlightMode`
Under macOS Catalina our former Tray implementation breaks. Under macOS Catalina our former Tray implementation breaks.
Apple's native substitute doesn't support changing the highlighting behavior. Apple's native substitute doesn't support changing the highlighting behavior.
@@ -338,7 +455,7 @@ tray.setHighlightMode(mode)
## Planned Breaking API Changes (5.0) ## Planned Breaking API Changes (5.0)
### `new BrowserWindow({ webPreferences })` ### Default Changed: `nodeIntegration` and `webviewTag` default to false, `contextIsolation` defaults to true
The following `webPreferences` option default values are deprecated in favor of the new defaults listed below. The following `webPreferences` option default values are deprecated in favor of the new defaults listed below.
@@ -358,16 +475,16 @@ const w = new BrowserWindow({
}) })
``` ```
### `nativeWindowOpen` ### Behavior Changed: `nodeIntegration` in child windows opened via `nativeWindowOpen`
Child windows opened with the `nativeWindowOpen` option will always have Node.js integration disabled, unless `nodeIntegrationInSubFrames` is `true. Child windows opened with the `nativeWindowOpen` option will always have Node.js integration disabled, unless `nodeIntegrationInSubFrames` is `true`.
### Privileged Schemes Registration ### API Changed: Registering privileged schemes must now be done before app ready
Renderer process APIs `webFrame.setRegisterURLSchemeAsPrivileged` and `webFrame.registerURLSchemeAsBypassingCSP` as well as browser process API `protocol.registerStandardSchemes` have been removed. Renderer process APIs `webFrame.registerURLSchemeAsPrivileged` and `webFrame.registerURLSchemeAsBypassingCSP` as well as browser process API `protocol.registerStandardSchemes` have been removed.
A new API, `protocol.registerSchemesAsPrivileged` has been added and should be used for registering custom schemes with the required privileges. Custom schemes are required to be registered before app ready. A new API, `protocol.registerSchemesAsPrivileged` has been added and should be used for registering custom schemes with the required privileges. Custom schemes are required to be registered before app ready.
### webFrame Isolated World APIs ### Deprecated: `webFrame.setIsolatedWorld*` replaced with `webFrame.setIsolatedWorldInfo`
```js ```js
// Deprecated // Deprecated
@@ -384,7 +501,7 @@ webFrame.setIsolatedWorldInfo(
}) })
``` ```
## `webFrame.setSpellCheckProvider` ### API Changed: `webFrame.setSpellCheckProvider` now takes an asynchronous callback
The `spellCheck` callback is now asynchronous, and `autoCorrectWord` parameter has been removed. The `spellCheck` callback is now asynchronous, and `autoCorrectWord` parameter has been removed.
```js ```js
// Deprecated // Deprecated

View File

@@ -25,7 +25,7 @@ Follow the guidelines below for building Electron on Linux.
Doing so permits installing Node on your own home directory as a standard user. Doing so permits installing Node on your own home directory as a standard user.
Or try repositories such as [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories). Or try repositories such as [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories).
* [clang](https://clang.llvm.org/get_started.html) 3.4 or later. * [clang](https://clang.llvm.org/get_started.html) 3.4 or later.
* Development headers of GTK+ and libnotify. * Development headers of GTK 3 and libnotify.
On Ubuntu, install the following libraries: On Ubuntu, install the following libraries:

View File

@@ -42,7 +42,7 @@ $ pip install pyobjc
If you're developing Electron and don't plan to redistribute your If you're developing Electron and don't plan to redistribute your
custom Electron build, you may skip this section. custom Electron build, you may skip this section.
Official Electron builds are built with [Xcode 9.4.1](http://adcdownload.apple.com/Developer_Tools/Xcode_9.4.1/Xcode_9.4.1.xip), and the MacOS 10.13 SDK. Building with a newer SDK works too, but the releases currently use the 10.13 SDK. Official Electron builds are built with [Xcode 9.4.1](http://adcdownload.apple.com/Developer_Tools/Xcode_9.4.1/Xcode_9.4.1.xip), and the macOS 10.13 SDK. Building with a newer SDK works too, but the releases currently use the 10.13 SDK.
## Building Electron ## Building Electron

View File

@@ -20,7 +20,7 @@ you prefer a graphical interface.
tail calls, and other compiler optimizations. tail calls, and other compiler optimizations.
* **Xcode**: In addition to Xcode, also install the Xcode command line tools. * **Xcode**: In addition to Xcode, also install the Xcode command line tools.
They include LLDB, the default debugger in Xcode on Mac OS X. It supports They include LLDB, the default debugger in Xcode on macOS. It supports
debugging C, Objective-C and C++ on the desktop and iOS devices and simulator. debugging C, Objective-C and C++ on the desktop and iOS devices and simulator.
* **.lldbinit**: Create or edit `~/.lldbinit` to allow Chromium code to be properly source-mapped. * **.lldbinit**: Create or edit `~/.lldbinit` to allow Chromium code to be properly source-mapped.

View File

@@ -35,7 +35,7 @@ $ git fetch upstream
Build steps and dependencies differ slightly depending on your operating system. Build steps and dependencies differ slightly depending on your operating system.
See these detailed guides on building Electron locally: See these detailed guides on building Electron locally:
* [Building on MacOS](https://electronjs.org/docs/development/build-instructions-macos) * [Building on macOS](https://electronjs.org/docs/development/build-instructions-macos)
* [Building on Linux](https://electronjs.org/docs/development/build-instructions-linux) * [Building on Linux](https://electronjs.org/docs/development/build-instructions-linux)
* [Building on Windows](https://electronjs.org/docs/development/build-instructions-windows) * [Building on Windows](https://electronjs.org/docs/development/build-instructions-windows)

View File

@@ -324,7 +324,7 @@ app.whenReady().then(() => {
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
const reopenMenuItem = findReopenMenuItem() const reopenMenuItem = findReopenMenuItem()
if (reopenMenuItem) reopenMenuItem.enabled = true if (reopenMenuItem) reopenMenuItem.enabled = true
@@ -335,7 +335,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -46,7 +46,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -54,7 +54,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -36,7 +36,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -44,7 +44,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -38,7 +38,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -46,7 +46,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -38,7 +38,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -46,7 +46,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -5,7 +5,7 @@
</head> </head>
<body> <body>
<h2>Create a new window</h2> <h2>Create a new window</h2>
<h3>Supports: Win, MacOS, Linux <span>|</span> Process: Main</h3> <h3>Supports: Win, macOS, Linux <span>|</span> Process: Main</h3>
<button id="new-window">View Demo</button> <button id="new-window">View Demo</button>
<p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app. This main process module can be used from the renderer process with the <code>remote</code> module, as is shown in this demo.</p> <p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app. This main process module can be used from the renderer process with the <code>remote</code> module, as is shown in this demo.</p>
<p>There are a lot of options when creating a new window. A few are in this demo, but visit the <a id="browser-window-link" href="">documentation<span>(opens in new window)</span></a> <p>There are a lot of options when creating a new window. A few are in this demo, but visit the <a id="browser-window-link" href="">documentation<span>(opens in new window)</span></a>

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -37,7 +37,7 @@ app.whenReady().then(createWindow)
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function () { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
app.quit() app.quit()
@@ -45,7 +45,7 @@ app.on('window-all-closed', function () {
}) })
app.on('activate', function () { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
createWindow() createWindow()

View File

@@ -76,7 +76,7 @@ that cache folder to provide custom builds of Electron or to avoid making contac
with the network at all. with the network at all.
* Linux: `$XDG_CACHE_HOME` or `~/.cache/electron/` * Linux: `$XDG_CACHE_HOME` or `~/.cache/electron/`
* MacOS: `~/Library/Caches/electron/` * macOS: `~/Library/Caches/electron/`
* Windows: `$LOCALAPPDATA/electron/Cache` or `~/AppData/Local/electron/Cache/` * Windows: `$LOCALAPPDATA/electron/Cache` or `~/AppData/Local/electron/Cache/`
On environments that have been using older versions of Electron, you might find the On environments that have been using older versions of Electron, you might find the

View File

@@ -1,4 +1,4 @@
# MacOS Dock # macOS Dock
Electron has APIs to configure the app's icon in the macOS Dock. A macOS-only Electron has APIs to configure the app's icon in the macOS Dock. A macOS-only
API exists to create a custom dock menu, but API exists to create a custom dock menu, but

View File

@@ -1,29 +1,40 @@
# Mojave Dark Mode # Supporting macOS Dark Mode
In macOS 10.14 Mojave, Apple introduced a new [system-wide dark mode](https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/dark-mode/) In macOS 10.14 Mojave, Apple introduced a new [system-wide dark mode](https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/dark-mode/)
for all macOS computers. If your app does have a dark mode, you can make your Electron app for all macOS computers. If your Electron app has a dark mode, you can make it follow the
follow the system-wide dark mode setting using [the nativeTheme api](../api/native-theme.md). system-wide dark mode setting using [the `nativeTheme` api](../api/native-theme.md).
In macOS 10.15 Catalina, Apple introduced a new "automatic" dark mode option for all macOS computers. In order In macOS 10.15 Catalina, Apple introduced a new "automatic" dark mode option for all macOS computers.
for the `nativeTheme.shouldUseDarkColors` and `Tray` APIs to work correctly in this mode on Catalina you need to either have `NSRequiresAquaSystemAppearance` set to `false` in your `Info.plist` file or be on Electron `>=7.0.0`. In order for the `nativeTheme.shouldUseDarkColors` and `Tray` APIs to work correctly in this mode on
Catalina, you need to either have `NSRequiresAquaSystemAppearance` set to `false` in your
`Info.plist` file, or be on Electron `>=7.0.0`. Both [Electron Packager][electron-packager] and
[Electron Forge][electron-forge] have a [`darwinDarkModeSupport` option][packager-darwindarkmode-api]
to automate the `Info.plist` changes during app build time.
## Automatically updating the native interfaces ## Automatically updating the native interfaces
"Native Interfaces" include the file picker, window border, dialogs, context menus and more; basically anything where "Native Interfaces" include the file picker, window border, dialogs, context menus and more; basically,
the UI comes from macOS and not your app. The default behavior as of Electron 7.0.0 is to opt in to this automatic anything where the UI comes from macOS and not your app. As of Electron 7.0.0, the default behavior
theming from the OS. If you wish to opt out you must set the `NSRequiresAquaSystemAppearance` key in the `Info.plist` file is to opt in to this automatic theming from the OS. If you wish to opt out and are using Electron
to `true`. Please note that once Electron starts building against the 10.14 SDK it will not be possible for you to opt &gt; 8.0.0, you must set the `NSRequiresAquaSystemAppearance` key in the `Info.plist` file to `true`.
out of this theming. Please note that Electron 8.0.0 and above will not let your opt out of this theming, due to the use
of the macOS 10.14 SDK.
## Automatically updating your own interfaces ## Automatically updating your own interfaces
If your app has its own dark mode you should toggle it on and off in sync with the system's dark mode setting. You can do If your app has its own dark mode, you should toggle it on and off in sync with the system's dark
this by listening for the theme updated event on Electron's `nativeTheme` module. E.g. mode setting. You can do this by listening for the theme updated event on Electron's `nativeTheme` module.
```js For example:
```javascript
const { nativeTheme } = require('electron') const { nativeTheme } = require('electron')
nativeTheme.on('updated', function theThemeHasChanged () { nativeTheme.on('updated', function theThemeHasChanged () {
updateMyAppTheme(nativeTheme.shouldUseDarkColors) updateMyAppTheme(nativeTheme.shouldUseDarkColors)
}) })
``` ```
[electron-forge]: https://www.electronforge.io/
[electron-packager]: https://github.com/electron/electron-packager
[packager-darwindarkmode-api]: https://electron.github.io/electron-packager/master/interfaces/electronpackager.options.html#darwindarkmodesupport

View File

@@ -49,7 +49,7 @@ The library file `widevinecdm.dll` will be under
`Program Files(x86)/Google/Chrome/Application/CHROME_VERSION/WidevineCdm/_platform_specific/win_(x86|x64)/` `Program Files(x86)/Google/Chrome/Application/CHROME_VERSION/WidevineCdm/_platform_specific/win_(x86|x64)/`
directory. directory.
### On MacOS ### On macOS
The library file `libwidevinecdm.dylib` will be under The library file `libwidevinecdm.dylib` will be under
`/Applications/Google Chrome.app/Contents/Versions/CHROME_VERSION/Google Chrome Framework.framework/Versions/A/Libraries/WidevineCdm/_platform_specific/mac_(x86|x64)/` `/Applications/Google Chrome.app/Contents/Versions/CHROME_VERSION/Google Chrome Framework.framework/Versions/A/Libraries/WidevineCdm/_platform_specific/mac_(x86|x64)/`

View File

@@ -92,10 +92,14 @@ template("electron_extra_paks") {
} }
if (enable_electron_extensions) { if (enable_electron_extensions) {
sources += [ sources += [
"$root_gen_dir/chrome/component_extension_resources.pak",
"$root_gen_dir/extensions/extensions_renderer_resources.pak", "$root_gen_dir/extensions/extensions_renderer_resources.pak",
"$root_gen_dir/extensions/extensions_resources.pak", "$root_gen_dir/extensions/extensions_resources.pak",
] ]
deps += [ "//extensions:extensions_resources" ] deps += [
"//chrome/browser/resources:component_extension_resources",
"//extensions:extensions_resources",
]
} }
} }
} }

View File

@@ -17,7 +17,8 @@
<part file="electron_strings.grdp" /> <part file="electron_strings.grdp" />
</messages> </messages>
<includes> <includes>
<include name="IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE" file="${target_gen_dir}\shell_devtools_discovery_page.html" use_base_dir="false" type="BINDATA" /> <include name="IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE" file="${target_gen_dir}/shell_devtools_discovery_page.html" use_base_dir="false" type="BINDATA" />
<include name="IDR_PDF_MANIFEST" file="../chrome/browser/resources/pdf/manifest.json" type="BINDATA" />
</includes> </includes>
</release> </release>
</grit> </grit>

View File

@@ -21,6 +21,7 @@ auto_filenames = {
"docs/api/dock.md", "docs/api/dock.md",
"docs/api/download-item.md", "docs/api/download-item.md",
"docs/api/environment-variables.md", "docs/api/environment-variables.md",
"docs/api/extensions.md",
"docs/api/file-object.md", "docs/api/file-object.md",
"docs/api/frameless-window.md", "docs/api/frameless-window.md",
"docs/api/global-shortcut.md", "docs/api/global-shortcut.md",
@@ -45,6 +46,7 @@ auto_filenames = {
"docs/api/remote.md", "docs/api/remote.md",
"docs/api/sandbox-option.md", "docs/api/sandbox-option.md",
"docs/api/screen.md", "docs/api/screen.md",
"docs/api/service-workers.md",
"docs/api/session.md", "docs/api/session.md",
"docs/api/shell.md", "docs/api/shell.md",
"docs/api/structures", "docs/api/structures",
@@ -95,6 +97,7 @@ auto_filenames = {
"docs/api/structures/mime-typed-buffer.md", "docs/api/structures/mime-typed-buffer.md",
"docs/api/structures/mouse-input-event.md", "docs/api/structures/mouse-input-event.md",
"docs/api/structures/mouse-wheel-input-event.md", "docs/api/structures/mouse-wheel-input-event.md",
"docs/api/structures/new-window-event.md",
"docs/api/structures/notification-action.md", "docs/api/structures/notification-action.md",
"docs/api/structures/point.md", "docs/api/structures/point.md",
"docs/api/structures/printer-info.md", "docs/api/structures/printer-info.md",
@@ -110,6 +113,7 @@ auto_filenames = {
"docs/api/structures/remove-password.md", "docs/api/structures/remove-password.md",
"docs/api/structures/scrubber-item.md", "docs/api/structures/scrubber-item.md",
"docs/api/structures/segmented-control-segment.md", "docs/api/structures/segmented-control-segment.md",
"docs/api/structures/service-worker-info.md",
"docs/api/structures/shared-worker-info.md", "docs/api/structures/shared-worker-info.md",
"docs/api/structures/shortcut-details.md", "docs/api/structures/shortcut-details.md",
"docs/api/structures/size.md", "docs/api/structures/size.md",
@@ -128,20 +132,19 @@ auto_filenames = {
] ]
sandbox_bundle_deps = [ sandbox_bundle_deps = [
"lib/browser/api/module-keys.js", "lib/browser/api/module-names.ts",
"lib/common/api/clipboard.js", "lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts", "lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts", "lib/common/api/module-list.ts",
"lib/common/api/native-image.js", "lib/common/api/native-image.js",
"lib/common/api/shell.js", "lib/common/api/shell.js",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts", "lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts", "lib/common/electron-binding-setup.ts",
"lib/common/type-utils.ts", "lib/common/type-utils.ts",
"lib/common/web-view-methods.ts", "lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts", "lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts", "lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.js", "lib/renderer/api/crash-reporter.ts",
"lib/renderer/api/desktop-capturer.ts", "lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/ipc-renderer.ts", "lib/renderer/api/ipc-renderer.ts",
"lib/renderer/api/remote.js", "lib/renderer/api/remote.js",
@@ -176,11 +179,8 @@ auto_filenames = {
isolated_bundle_deps = [ isolated_bundle_deps = [
"lib/common/electron-binding-setup.ts", "lib/common/electron-binding-setup.ts",
"lib/isolated_renderer/init.js", "lib/isolated_renderer/init.js",
"lib/renderer/ipc-renderer-internal-utils.ts",
"lib/renderer/ipc-renderer-internal.ts",
"lib/renderer/web-view/web-view-constants.ts", "lib/renderer/web-view/web-view-constants.ts",
"lib/renderer/web-view/web-view-element.ts", "lib/renderer/web-view/web-view-element.ts",
"lib/renderer/window-setup.ts",
"package.json", "package.json",
"tsconfig.electron.json", "tsconfig.electron.json",
"tsconfig.json", "tsconfig.json",
@@ -190,6 +190,7 @@ auto_filenames = {
"lib/common/electron-binding-setup.ts", "lib/common/electron-binding-setup.ts",
"lib/common/webpack-globals-provider.ts", "lib/common/webpack-globals-provider.ts",
"lib/content_script/init.js", "lib/content_script/init.js",
"lib/renderer/api/context-bridge.ts",
"lib/renderer/chrome-api.ts", "lib/renderer/chrome-api.ts",
"lib/renderer/extensions/event.ts", "lib/renderer/extensions/event.ts",
"lib/renderer/extensions/i18n.ts", "lib/renderer/extensions/i18n.ts",
@@ -212,7 +213,7 @@ auto_filenames = {
"lib/browser/api/browser-view.js", "lib/browser/api/browser-view.js",
"lib/browser/api/browser-window.js", "lib/browser/api/browser-window.js",
"lib/browser/api/content-tracing.js", "lib/browser/api/content-tracing.js",
"lib/browser/api/crash-reporter.js", "lib/browser/api/crash-reporter.ts",
"lib/browser/api/dialog.js", "lib/browser/api/dialog.js",
"lib/browser/api/exports/electron.ts", "lib/browser/api/exports/electron.ts",
"lib/browser/api/global-shortcut.js", "lib/browser/api/global-shortcut.js",
@@ -248,7 +249,6 @@ auto_filenames = {
"lib/browser/api/web-contents.js", "lib/browser/api/web-contents.js",
"lib/browser/chrome-extension-shim.js", "lib/browser/chrome-extension-shim.js",
"lib/browser/chrome-extension.js", "lib/browser/chrome-extension.js",
"lib/browser/crash-reporter-init.js",
"lib/browser/default-menu.ts", "lib/browser/default-menu.ts",
"lib/browser/desktop-capturer.ts", "lib/browser/desktop-capturer.ts",
"lib/browser/devtools.ts", "lib/browser/devtools.ts",
@@ -268,7 +268,6 @@ auto_filenames = {
"lib/common/api/module-list.ts", "lib/common/api/module-list.ts",
"lib/common/api/native-image.js", "lib/common/api/native-image.js",
"lib/common/api/shell.js", "lib/common/api/shell.js",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts", "lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts", "lib/common/electron-binding-setup.ts",
"lib/common/init.ts", "lib/common/init.ts",
@@ -285,13 +284,12 @@ auto_filenames = {
] ]
renderer_bundle_deps = [ renderer_bundle_deps = [
"lib/browser/api/module-keys.js", "lib/browser/api/module-names.ts",
"lib/common/api/clipboard.js", "lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts", "lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts", "lib/common/api/module-list.ts",
"lib/common/api/native-image.js", "lib/common/api/native-image.js",
"lib/common/api/shell.js", "lib/common/api/shell.js",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts", "lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts", "lib/common/electron-binding-setup.ts",
"lib/common/init.ts", "lib/common/init.ts",
@@ -300,7 +298,7 @@ auto_filenames = {
"lib/common/web-view-methods.ts", "lib/common/web-view-methods.ts",
"lib/common/webpack-globals-provider.ts", "lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts", "lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.js", "lib/renderer/api/crash-reporter.ts",
"lib/renderer/api/desktop-capturer.ts", "lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/exports/electron.ts", "lib/renderer/api/exports/electron.ts",
"lib/renderer/api/ipc-renderer.ts", "lib/renderer/api/ipc-renderer.ts",
@@ -334,13 +332,12 @@ auto_filenames = {
] ]
worker_bundle_deps = [ worker_bundle_deps = [
"lib/browser/api/module-keys.js", "lib/browser/api/module-names.ts",
"lib/common/api/clipboard.js", "lib/common/api/clipboard.js",
"lib/common/api/deprecate.ts", "lib/common/api/deprecate.ts",
"lib/common/api/module-list.ts", "lib/common/api/module-list.ts",
"lib/common/api/native-image.js", "lib/common/api/native-image.js",
"lib/common/api/shell.js", "lib/common/api/shell.js",
"lib/common/crash-reporter.js",
"lib/common/define-properties.ts", "lib/common/define-properties.ts",
"lib/common/electron-binding-setup.ts", "lib/common/electron-binding-setup.ts",
"lib/common/init.ts", "lib/common/init.ts",
@@ -348,7 +345,7 @@ auto_filenames = {
"lib/common/type-utils.ts", "lib/common/type-utils.ts",
"lib/common/webpack-globals-provider.ts", "lib/common/webpack-globals-provider.ts",
"lib/renderer/api/context-bridge.ts", "lib/renderer/api/context-bridge.ts",
"lib/renderer/api/crash-reporter.js", "lib/renderer/api/crash-reporter.ts",
"lib/renderer/api/desktop-capturer.ts", "lib/renderer/api/desktop-capturer.ts",
"lib/renderer/api/exports/electron.ts", "lib/renderer/api/exports/electron.ts",
"lib/renderer/api/ipc-renderer.ts", "lib/renderer/api/ipc-renderer.ts",

View File

@@ -31,6 +31,8 @@ filenames = {
"shell/app/command_line_args.h", "shell/app/command_line_args.h",
"shell/app/electron_content_client.cc", "shell/app/electron_content_client.cc",
"shell/app/electron_content_client.h", "shell/app/electron_content_client.h",
"shell/app/electron_crash_reporter_client.cc",
"shell/app/electron_crash_reporter_client.h",
"shell/app/electron_main_delegate.cc", "shell/app/electron_main_delegate.cc",
"shell/app/electron_main_delegate.h", "shell/app/electron_main_delegate.h",
"shell/app/electron_main_delegate_mac.h", "shell/app/electron_main_delegate_mac.h",
@@ -51,6 +53,8 @@ filenames = {
"shell/browser/api/electron_api_content_tracing.cc", "shell/browser/api/electron_api_content_tracing.cc",
"shell/browser/api/electron_api_cookies.cc", "shell/browser/api/electron_api_cookies.cc",
"shell/browser/api/electron_api_cookies.h", "shell/browser/api/electron_api_cookies.h",
"shell/browser/api/electron_api_crash_reporter.cc",
"shell/browser/api/electron_api_crash_reporter.h",
"shell/browser/api/electron_api_data_pipe_holder.cc", "shell/browser/api/electron_api_data_pipe_holder.cc",
"shell/browser/api/electron_api_data_pipe_holder.h", "shell/browser/api/electron_api_data_pipe_holder.h",
"shell/browser/api/electron_api_debugger.cc", "shell/browser/api/electron_api_debugger.cc",
@@ -88,6 +92,8 @@ filenames = {
"shell/browser/api/electron_api_protocol.h", "shell/browser/api/electron_api_protocol.h",
"shell/browser/api/electron_api_screen.cc", "shell/browser/api/electron_api_screen.cc",
"shell/browser/api/electron_api_screen.h", "shell/browser/api/electron_api_screen.h",
"shell/browser/api/electron_api_service_worker_context.cc",
"shell/browser/api/electron_api_service_worker_context.h",
"shell/browser/api/electron_api_session.cc", "shell/browser/api/electron_api_session.cc",
"shell/browser/api/electron_api_session.h", "shell/browser/api/electron_api_session.h",
"shell/browser/api/electron_api_system_preferences.cc", "shell/browser/api/electron_api_system_preferences.cc",
@@ -162,7 +168,6 @@ filenames = {
"shell/browser/electron_javascript_dialog_manager.h", "shell/browser/electron_javascript_dialog_manager.h",
"shell/browser/electron_navigation_throttle.cc", "shell/browser/electron_navigation_throttle.cc",
"shell/browser/electron_navigation_throttle.h", "shell/browser/electron_navigation_throttle.h",
"shell/browser/electron_paths.h",
"shell/browser/electron_permission_manager.cc", "shell/browser/electron_permission_manager.cc",
"shell/browser/electron_permission_manager.h", "shell/browser/electron_permission_manager.h",
"shell/browser/electron_quota_permission_context.cc", "shell/browser/electron_quota_permission_context.cc",
@@ -234,12 +239,15 @@ filenames = {
"shell/browser/net/node_stream_loader.h", "shell/browser/net/node_stream_loader.h",
"shell/browser/net/proxying_url_loader_factory.cc", "shell/browser/net/proxying_url_loader_factory.cc",
"shell/browser/net/proxying_url_loader_factory.h", "shell/browser/net/proxying_url_loader_factory.h",
"shell/browser/net/proxying_websocket.cc",
"shell/browser/net/proxying_websocket.h",
"shell/browser/net/resolve_proxy_helper.cc", "shell/browser/net/resolve_proxy_helper.cc",
"shell/browser/net/resolve_proxy_helper.h", "shell/browser/net/resolve_proxy_helper.h",
"shell/browser/net/system_network_context_manager.cc", "shell/browser/net/system_network_context_manager.cc",
"shell/browser/net/system_network_context_manager.h", "shell/browser/net/system_network_context_manager.h",
"shell/browser/net/url_pipe_loader.cc", "shell/browser/net/url_pipe_loader.cc",
"shell/browser/net/url_pipe_loader.h", "shell/browser/net/url_pipe_loader.h",
"shell/browser/net/web_request_api_interface.h",
"shell/browser/network_hints_handler_impl.cc", "shell/browser/network_hints_handler_impl.cc",
"shell/browser/network_hints_handler_impl.h", "shell/browser/network_hints_handler_impl.h",
"shell/browser/node_debugger.cc", "shell/browser/node_debugger.cc",
@@ -276,6 +284,8 @@ filenames = {
"shell/browser/notifications/win/win32_notification.h", "shell/browser/notifications/win/win32_notification.h",
"shell/browser/notifications/win/windows_toast_notification.cc", "shell/browser/notifications/win/windows_toast_notification.cc",
"shell/browser/notifications/win/windows_toast_notification.h", "shell/browser/notifications/win/windows_toast_notification.h",
"shell/browser/plugins/plugin_utils.cc",
"shell/browser/plugins/plugin_utils.h",
"shell/browser/pref_store_delegate.cc", "shell/browser/pref_store_delegate.cc",
"shell/browser/pref_store_delegate.h", "shell/browser/pref_store_delegate.h",
"shell/browser/relauncher.cc", "shell/browser/relauncher.cc",
@@ -382,6 +392,8 @@ filenames = {
"shell/browser/ui/views/submenu_button.h", "shell/browser/ui/views/submenu_button.h",
"shell/browser/ui/views/win_frame_view.cc", "shell/browser/ui/views/win_frame_view.cc",
"shell/browser/ui/views/win_frame_view.h", "shell/browser/ui/views/win_frame_view.h",
"shell/browser/ui/win/dialog_thread.cc",
"shell/browser/ui/win/dialog_thread.h",
"shell/browser/ui/win/electron_desktop_native_widget_aura.cc", "shell/browser/ui/win/electron_desktop_native_widget_aura.cc",
"shell/browser/ui/win/electron_desktop_native_widget_aura.h", "shell/browser/ui/win/electron_desktop_native_widget_aura.h",
"shell/browser/ui/win/electron_desktop_window_tree_host_win.cc", "shell/browser/ui/win/electron_desktop_window_tree_host_win.cc",
@@ -426,7 +438,6 @@ filenames = {
"shell/common/api/electron_api_clipboard.h", "shell/common/api/electron_api_clipboard.h",
"shell/common/api/electron_api_clipboard_mac.mm", "shell/common/api/electron_api_clipboard_mac.mm",
"shell/common/api/electron_api_command_line.cc", "shell/common/api/electron_api_command_line.cc",
"shell/common/api/electron_api_crash_reporter.cc",
"shell/common/api/electron_api_key_weak_map.h", "shell/common/api/electron_api_key_weak_map.h",
"shell/common/api/electron_api_native_image.cc", "shell/common/api/electron_api_native_image.cc",
"shell/common/api/electron_api_native_image.h", "shell/common/api/electron_api_native_image.h",
@@ -436,6 +447,8 @@ filenames = {
"shell/common/api/electron_bindings.cc", "shell/common/api/electron_bindings.cc",
"shell/common/api/electron_bindings.h", "shell/common/api/electron_bindings.h",
"shell/common/api/features.cc", "shell/common/api/features.cc",
"shell/common/api/object_life_monitor.cc",
"shell/common/api/object_life_monitor.h",
"shell/common/application_info.cc", "shell/common/application_info.cc",
"shell/common/application_info.h", "shell/common/application_info.h",
"shell/common/application_info_linux.cc", "shell/common/application_info_linux.cc",
@@ -449,22 +462,13 @@ filenames = {
"shell/common/asar/scoped_temporary_file.h", "shell/common/asar/scoped_temporary_file.h",
"shell/common/color_util.cc", "shell/common/color_util.cc",
"shell/common/color_util.h", "shell/common/color_util.h",
"shell/common/crash_reporter/crash_reporter.cc", "shell/common/crash_keys.cc",
"shell/common/crash_reporter/crash_reporter.h", "shell/common/crash_keys.h",
"shell/common/crash_reporter/crash_reporter_linux.cc",
"shell/common/crash_reporter/crash_reporter_linux.h",
"shell/common/crash_reporter/crash_reporter_mac.h",
"shell/common/crash_reporter/crash_reporter_mac.mm",
"shell/common/crash_reporter/crash_reporter_win.cc",
"shell/common/crash_reporter/crash_reporter_win.h",
"shell/common/crash_reporter/linux/crash_dump_handler.cc",
"shell/common/crash_reporter/linux/crash_dump_handler.h",
"shell/common/crash_reporter/win/crash_service_main.cc",
"shell/common/crash_reporter/win/crash_service_main.h",
"shell/common/electron_command_line.cc", "shell/common/electron_command_line.cc",
"shell/common/electron_command_line.h", "shell/common/electron_command_line.h",
"shell/common/electron_constants.cc", "shell/common/electron_constants.cc",
"shell/common/electron_constants.h", "shell/common/electron_constants.h",
"shell/common/electron_paths.h",
"shell/common/gin_converters/accelerator_converter.cc", "shell/common/gin_converters/accelerator_converter.cc",
"shell/common/gin_converters/accelerator_converter.h", "shell/common/gin_converters/accelerator_converter.h",
"shell/common/gin_converters/blink_converter.cc", "shell/common/gin_converters/blink_converter.cc",
@@ -472,8 +476,6 @@ filenames = {
"shell/common/gin_converters/callback_converter.h", "shell/common/gin_converters/callback_converter.h",
"shell/common/gin_converters/content_converter.cc", "shell/common/gin_converters/content_converter.cc",
"shell/common/gin_converters/content_converter.h", "shell/common/gin_converters/content_converter.h",
"shell/common/gin_converters/extension_converter.cc",
"shell/common/gin_converters/extension_converter.h",
"shell/common/gin_converters/file_dialog_converter.cc", "shell/common/gin_converters/file_dialog_converter.cc",
"shell/common/gin_converters/file_dialog_converter.h", "shell/common/gin_converters/file_dialog_converter.h",
"shell/common/gin_converters/file_path_converter.h", "shell/common/gin_converters/file_path_converter.h",
@@ -488,6 +490,8 @@ filenames = {
"shell/common/gin_converters/net_converter.cc", "shell/common/gin_converters/net_converter.cc",
"shell/common/gin_converters/net_converter.h", "shell/common/gin_converters/net_converter.h",
"shell/common/gin_converters/std_converter.h", "shell/common/gin_converters/std_converter.h",
"shell/common/gin_converters/time_converter.cc",
"shell/common/gin_converters/time_converter.h",
"shell/common/gin_converters/value_converter.cc", "shell/common/gin_converters/value_converter.cc",
"shell/common/gin_converters/value_converter.h", "shell/common/gin_converters/value_converter.h",
"shell/common/gin_helper/arguments.cc", "shell/common/gin_helper/arguments.cc",
@@ -524,6 +528,10 @@ filenames = {
"shell/common/key_weak_map.h", "shell/common/key_weak_map.h",
"shell/common/keyboard_util.cc", "shell/common/keyboard_util.cc",
"shell/common/keyboard_util.h", "shell/common/keyboard_util.h",
"shell/common/language_util.h",
"shell/common/language_util_linux.cc",
"shell/common/language_util_mac.mm",
"shell/common/language_util_win.cc",
"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/mouse_util.cc", "shell/common/mouse_util.cc",
@@ -551,10 +559,12 @@ filenames = {
"shell/common/skia_util.h", "shell/common/skia_util.h",
"shell/common/v8_value_converter.cc", "shell/common/v8_value_converter.cc",
"shell/common/v8_value_converter.h", "shell/common/v8_value_converter.h",
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.cc", "shell/common/world_ids.h",
"shell/renderer/api/context_bridge/render_frame_context_bridge_store.h", "shell/renderer/api/context_bridge/object_cache.cc",
"shell/renderer/api/context_bridge/object_cache.h",
"shell/renderer/api/electron_api_context_bridge.cc", "shell/renderer/api/electron_api_context_bridge.cc",
"shell/renderer/api/electron_api_context_bridge.h", "shell/renderer/api/electron_api_context_bridge.h",
"shell/renderer/api/electron_api_crash_reporter_renderer.cc",
"shell/renderer/api/electron_api_renderer_ipc.cc", "shell/renderer/api/electron_api_renderer_ipc.cc",
"shell/renderer/api/electron_api_spell_check_client.cc", "shell/renderer/api/electron_api_spell_check_client.cc",
"shell/renderer/api/electron_api_spell_check_client.h", "shell/renderer/api/electron_api_spell_check_client.h",
@@ -591,44 +601,56 @@ filenames = {
] ]
lib_sources_extensions = [ lib_sources_extensions = [
"shell/browser/extensions/api/i18n/i18n_api.cc",
"shell/browser/extensions/api/i18n/i18n_api.h",
"shell/browser/extensions/api/resources_private/resources_private_api.cc",
"shell/browser/extensions/api/resources_private/resources_private_api.h",
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc", "shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc",
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h", "shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h",
"shell/browser/extensions/api/tabs/tabs_api.cc", "shell/browser/extensions/api/tabs/tabs_api.cc",
"shell/browser/extensions/api/tabs/tabs_api.h", "shell/browser/extensions/api/tabs/tabs_api.h",
"shell/browser/extensions/electron_extensions_browser_client.cc", "shell/browser/extensions/api/streams_private/streams_private_api.cc",
"shell/browser/extensions/electron_extensions_browser_client.h", "shell/browser/extensions/api/streams_private/streams_private_api.h",
"shell/browser/extensions/electron_browser_context_keyed_service_factories.cc", "shell/browser/extensions/electron_browser_context_keyed_service_factories.cc",
"shell/browser/extensions/electron_browser_context_keyed_service_factories.h", "shell/browser/extensions/electron_browser_context_keyed_service_factories.h",
"shell/browser/extensions/electron_component_extension_resource_manager.cc",
"shell/browser/extensions/electron_component_extension_resource_manager.h",
"shell/browser/extensions/electron_display_info_provider.cc", "shell/browser/extensions/electron_display_info_provider.cc",
"shell/browser/extensions/electron_display_info_provider.h", "shell/browser/extensions/electron_display_info_provider.h",
"shell/browser/extensions/electron_extension_host_delegate.cc", "shell/browser/extensions/electron_extension_host_delegate.cc",
"shell/browser/extensions/electron_extension_host_delegate.h", "shell/browser/extensions/electron_extension_host_delegate.h",
"shell/browser/extensions/electron_extension_loader.cc", "shell/browser/extensions/electron_extension_loader.cc",
"shell/browser/extensions/electron_extension_loader.h", "shell/browser/extensions/electron_extension_loader.h",
"shell/browser/extensions/electron_extension_message_filter.cc",
"shell/browser/extensions/electron_extension_message_filter.h",
"shell/browser/extensions/electron_extension_system.cc", "shell/browser/extensions/electron_extension_system.cc",
"shell/browser/extensions/electron_extension_system.h", "shell/browser/extensions/electron_extension_system.h",
"shell/browser/extensions/electron_extension_system_factory.cc", "shell/browser/extensions/electron_extension_system_factory.cc",
"shell/browser/extensions/electron_extension_system_factory.h", "shell/browser/extensions/electron_extension_system_factory.h",
"shell/browser/extensions/electron_extension_web_contents_observer.cc", "shell/browser/extensions/electron_extension_web_contents_observer.cc",
"shell/browser/extensions/electron_extension_web_contents_observer.h", "shell/browser/extensions/electron_extension_web_contents_observer.h",
"shell/browser/extensions/electron_navigation_ui_data.cc",
"shell/browser/extensions/electron_navigation_ui_data.h",
"shell/browser/extensions/electron_process_manager_delegate.cc",
"shell/browser/extensions/electron_process_manager_delegate.h",
"shell/browser/extensions/electron_extensions_api_client.cc", "shell/browser/extensions/electron_extensions_api_client.cc",
"shell/browser/extensions/electron_extensions_api_client.h", "shell/browser/extensions/electron_extensions_api_client.h",
"shell/browser/extensions/electron_extensions_browser_api_provider.cc", "shell/browser/extensions/electron_extensions_browser_api_provider.cc",
"shell/browser/extensions/electron_extensions_browser_api_provider.h", "shell/browser/extensions/electron_extensions_browser_api_provider.h",
"shell/browser/extensions/electron_extensions_browser_client.cc",
"shell/browser/extensions/electron_extensions_browser_client.h",
"shell/browser/extensions/electron_messaging_delegate.cc", "shell/browser/extensions/electron_messaging_delegate.cc",
"shell/browser/extensions/electron_messaging_delegate.h", "shell/browser/extensions/electron_messaging_delegate.h",
"shell/browser/extensions/electron_navigation_ui_data.cc",
"shell/browser/extensions/electron_navigation_ui_data.h",
"shell/browser/extensions/electron_process_manager_delegate.cc",
"shell/browser/extensions/electron_process_manager_delegate.h",
"shell/common/extensions/electron_extensions_api_provider.cc", "shell/common/extensions/electron_extensions_api_provider.cc",
"shell/common/extensions/electron_extensions_api_provider.h", "shell/common/extensions/electron_extensions_api_provider.h",
"shell/common/extensions/electron_extensions_client.cc", "shell/common/extensions/electron_extensions_client.cc",
"shell/common/extensions/electron_extensions_client.h", "shell/common/extensions/electron_extensions_client.h",
"shell/renderer/extensions/electron_extensions_renderer_client.cc", "shell/common/gin_converters/extension_converter.cc",
"shell/renderer/extensions/electron_extensions_renderer_client.h", "shell/common/gin_converters/extension_converter.h",
"shell/renderer/extensions/electron_extensions_dispatcher_delegate.cc", "shell/renderer/extensions/electron_extensions_dispatcher_delegate.cc",
"shell/renderer/extensions/electron_extensions_dispatcher_delegate.h", "shell/renderer/extensions/electron_extensions_dispatcher_delegate.h",
"shell/renderer/extensions/electron_extensions_renderer_client.cc",
"shell/renderer/extensions/electron_extensions_renderer_client.h",
] ]
app_sources = [ app_sources = [

View File

@@ -44,7 +44,7 @@ hunspell_dictionaries = [
"//third_party/hunspell_dictionaries/ta-IN-3-0.bdic", "//third_party/hunspell_dictionaries/ta-IN-3-0.bdic",
"//third_party/hunspell_dictionaries/tg-TG-5-0.bdic", "//third_party/hunspell_dictionaries/tg-TG-5-0.bdic",
"//third_party/hunspell_dictionaries/tr-TR-4-0.bdic", "//third_party/hunspell_dictionaries/tr-TR-4-0.bdic",
"//third_party/hunspell_dictionaries/uk-UA-3-0.bdic", "//third_party/hunspell_dictionaries/uk-UA-4-0.bdic",
"//third_party/hunspell_dictionaries/vi-VN-3-0.bdic", "//third_party/hunspell_dictionaries/vi-VN-3-0.bdic",
"//third_party/hunspell_dictionaries/xx-XX-3-0.bdic", "//third_party/hunspell_dictionaries/xx-XX-3-0.bdic",
] ]

View File

@@ -1,21 +1,44 @@
import * as fs from 'fs' import * as fs from 'fs';
import * as path from 'path' import * as path from 'path';
import { deprecate, Menu } from 'electron' import { Menu } from 'electron';
import { EventEmitter } from 'events' import { EventEmitter } from 'events';
const bindings = process.electronBinding('app') const bindings = process.electronBinding('app');
const commandLine = process.electronBinding('command_line') const commandLine = process.electronBinding('command_line');
const { app, App } = bindings const { app, App } = bindings;
// Only one app object permitted. // Only one app object permitted.
export default app export default app;
let dockMenu: Electron.Menu | null = null let dockMenu: Electron.Menu | null = null;
// App is an EventEmitter. // App is an EventEmitter.
Object.setPrototypeOf(App.prototype, EventEmitter.prototype) Object.setPrototypeOf(App.prototype, EventEmitter.prototype);
EventEmitter.call(app as any) EventEmitter.call(app as any);
// Properties.
const nativeASGetter = app.isAccessibilitySupportEnabled;
const nativeASSetter = app.setAccessibilitySupportEnabled;
Object.defineProperty(App.prototype, 'accessibilitySupportEnabled', {
get: () => nativeASGetter.call(app),
set: (enabled) => nativeASSetter.call(app, enabled)
});
const nativeBCGetter = app.getBadgeCount;
const nativeBCSetter = app.setBadgeCount;
Object.defineProperty(App.prototype, 'badgeCount', {
get: () => nativeBCGetter.call(app),
set: (count) => nativeBCSetter.call(app, count)
});
const nativeNGetter = app.getName;
const nativeNSetter = app.setName;
Object.defineProperty(App.prototype, 'name', {
get: () => nativeNGetter.call(app),
set: (name) => nativeNSetter.call(app, name)
});
Object.assign(app, { Object.assign(app, {
commandLine: { commandLine: {
@@ -24,99 +47,94 @@ Object.assign(app, {
appendSwitch: (theSwitch: string, value?: string) => commandLine.appendSwitch(String(theSwitch), typeof value === 'undefined' ? value : String(value)), appendSwitch: (theSwitch: string, value?: string) => commandLine.appendSwitch(String(theSwitch), typeof value === 'undefined' ? value : String(value)),
appendArgument: (arg: string) => commandLine.appendArgument(String(arg)) appendArgument: (arg: string) => commandLine.appendArgument(String(arg))
} as Electron.CommandLine } as Electron.CommandLine
}) });
// we define this here because it'd be overly complicated to // we define this here because it'd be overly complicated to
// do in native land // do in native land
Object.defineProperty(app, 'applicationMenu', { Object.defineProperty(app, 'applicationMenu', {
get () { get () {
return Menu.getApplicationMenu() return Menu.getApplicationMenu();
}, },
set (menu: Electron.Menu | null) { set (menu: Electron.Menu | null) {
return Menu.setApplicationMenu(menu) return Menu.setApplicationMenu(menu);
} }
}) });
App.prototype.isPackaged = (() => { App.prototype.isPackaged = (() => {
const execFile = path.basename(process.execPath).toLowerCase() const execFile = path.basename(process.execPath).toLowerCase();
if (process.platform === 'win32') { if (process.platform === 'win32') {
return execFile !== 'electron.exe' return execFile !== 'electron.exe';
} }
return execFile !== 'electron' return execFile !== 'electron';
})() })();
app._setDefaultAppPaths = (packagePath) => { app._setDefaultAppPaths = (packagePath) => {
// Set the user path according to application's name. // Set the user path according to application's name.
app.setPath('userData', path.join(app.getPath('appData'), app.name!)) app.setPath('userData', path.join(app.getPath('appData'), app.name!));
app.setPath('userCache', path.join(app.getPath('cache'), app.name!)) app.setPath('userCache', path.join(app.getPath('cache'), app.name!));
app.setAppPath(packagePath) app.setAppPath(packagePath);
// Add support for --user-data-dir= // Add support for --user-data-dir=
if (app.commandLine.hasSwitch('user-data-dir')) { if (app.commandLine.hasSwitch('user-data-dir')) {
const userDataDir = app.commandLine.getSwitchValue('user-data-dir') const userDataDir = app.commandLine.getSwitchValue('user-data-dir');
if (path.isAbsolute(userDataDir)) app.setPath('userData', userDataDir) if (path.isAbsolute(userDataDir)) app.setPath('userData', userDataDir);
} }
} };
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
const setDockMenu = app.dock!.setMenu const setDockMenu = app.dock!.setMenu;
app.dock!.setMenu = (menu) => { app.dock!.setMenu = (menu) => {
dockMenu = menu dockMenu = menu;
setDockMenu(menu) setDockMenu(menu);
} };
app.dock!.getMenu = () => dockMenu app.dock!.getMenu = () => dockMenu;
} }
if (process.platform === 'linux') { if (process.platform === 'linux') {
const patternVmRSS = /^VmRSS:\s*(\d+) kB$/m const patternVmRSS = /^VmRSS:\s*(\d+) kB$/m;
const patternVmHWM = /^VmHWM:\s*(\d+) kB$/m const patternVmHWM = /^VmHWM:\s*(\d+) kB$/m;
const getStatus = (pid: number) => { const getStatus = (pid: number) => {
try { try {
return fs.readFileSync(`/proc/${pid}/status`, 'utf8') return fs.readFileSync(`/proc/${pid}/status`, 'utf8');
} catch { } catch {
return '' return '';
} }
} };
const getEntry = (file: string, pattern: RegExp) => { const getEntry = (file: string, pattern: RegExp) => {
const match = file.match(pattern) const match = file.match(pattern);
return match ? parseInt(match[1], 10) : 0 return match ? parseInt(match[1], 10) : 0;
} };
const getProcessMemoryInfo = (pid: number) => { const getProcessMemoryInfo = (pid: number) => {
const file = getStatus(pid) const file = getStatus(pid);
return { return {
workingSetSize: getEntry(file, patternVmRSS), workingSetSize: getEntry(file, patternVmRSS),
peakWorkingSetSize: getEntry(file, patternVmHWM) peakWorkingSetSize: getEntry(file, patternVmHWM)
} };
} };
const nativeFn = app.getAppMetrics const nativeFn = app.getAppMetrics;
app.getAppMetrics = () => { app.getAppMetrics = () => {
const metrics = nativeFn.call(app) const metrics = nativeFn.call(app);
for (const metric of metrics) { for (const metric of metrics) {
metric.memory = getProcessMemoryInfo(metric.pid) metric.memory = getProcessMemoryInfo(metric.pid);
} }
return metrics return metrics;
} };
} }
// Routes the events to webContents. // Routes the events to webContents.
const events = ['certificate-error', 'select-client-certificate'] const events = ['certificate-error', 'select-client-certificate'];
for (const name of events) { for (const name of events) {
app.on(name as 'certificate-error', (event, webContents, ...args: any[]) => { app.on(name as 'certificate-error', (event, webContents, ...args: any[]) => {
webContents.emit(name, event, ...args) webContents.emit(name, event, ...args);
}) });
} }
// Property Deprecations
deprecate.fnToProperty(App.prototype, 'accessibilitySupportEnabled', '_isAccessibilitySupportEnabled', '_setAccessibilitySupportEnabled')
deprecate.fnToProperty(App.prototype, 'badgeCount', '_getBadgeCount', '_setBadgeCount')
deprecate.fnToProperty(App.prototype, 'name', '_getName', '_setName')
// Wrappers for native classes. // Wrappers for native classes.
const { DownloadItem } = process.electronBinding('download_item') const { DownloadItem } = process.electronBinding('download_item');
Object.setPrototypeOf(DownloadItem.prototype, EventEmitter.prototype) Object.setPrototypeOf(DownloadItem.prototype, EventEmitter.prototype);

View File

@@ -1,7 +1,7 @@
'use strict' 'use strict';
if (process.platform === 'win32') { if (process.platform === 'win32') {
module.exports = require('@electron/internal/browser/api/auto-updater/auto-updater-win') module.exports = require('@electron/internal/browser/api/auto-updater/auto-updater-win');
} else { } else {
module.exports = require('@electron/internal/browser/api/auto-updater/auto-updater-native') module.exports = require('@electron/internal/browser/api/auto-updater/auto-updater-native');
} }

View File

@@ -1,10 +1,10 @@
'use strict' 'use strict';
const EventEmitter = require('events').EventEmitter const EventEmitter = require('events').EventEmitter;
const { autoUpdater, AutoUpdater } = process.electronBinding('auto_updater') const { autoUpdater, AutoUpdater } = process.electronBinding('auto_updater');
// AutoUpdater is an EventEmitter. // AutoUpdater is an EventEmitter.
Object.setPrototypeOf(AutoUpdater.prototype, EventEmitter.prototype) Object.setPrototypeOf(AutoUpdater.prototype, EventEmitter.prototype);
EventEmitter.call(autoUpdater) EventEmitter.call(autoUpdater);
module.exports = autoUpdater module.exports = autoUpdater;

View File

@@ -1,74 +1,74 @@
'use strict' 'use strict';
const { app } = require('electron') const { app } = require('electron');
const { EventEmitter } = require('events') const { EventEmitter } = require('events');
const squirrelUpdate = require('@electron/internal/browser/api/auto-updater/squirrel-update-win') const squirrelUpdate = require('@electron/internal/browser/api/auto-updater/squirrel-update-win');
class AutoUpdater extends EventEmitter { class AutoUpdater extends EventEmitter {
quitAndInstall () { quitAndInstall () {
if (!this.updateAvailable) { if (!this.updateAvailable) {
return this.emitError('No update available, can\'t quit and install') return this.emitError('No update available, can\'t quit and install');
} }
squirrelUpdate.processStart() squirrelUpdate.processStart();
app.quit() app.quit();
} }
getFeedURL () { getFeedURL () {
return this.updateURL return this.updateURL;
} }
setFeedURL (options) { setFeedURL (options) {
let updateURL let updateURL;
if (typeof options === 'object') { if (typeof options === 'object') {
if (typeof options.url === 'string') { if (typeof options.url === 'string') {
updateURL = options.url updateURL = options.url;
} else { } else {
throw new Error('Expected options object to contain a \'url\' string property in setFeedUrl call') throw new Error('Expected options object to contain a \'url\' string property in setFeedUrl call');
} }
} else if (typeof options === 'string') { } else if (typeof options === 'string') {
updateURL = options updateURL = options;
} else { } else {
throw new Error('Expected an options object with a \'url\' property to be provided') throw new Error('Expected an options object with a \'url\' property to be provided');
} }
this.updateURL = updateURL this.updateURL = updateURL;
} }
checkForUpdates () { checkForUpdates () {
if (!this.updateURL) { if (!this.updateURL) {
return this.emitError('Update URL is not set') return this.emitError('Update URL is not set');
} }
if (!squirrelUpdate.supported()) { if (!squirrelUpdate.supported()) {
return this.emitError('Can not find Squirrel') return this.emitError('Can not find Squirrel');
} }
this.emit('checking-for-update') this.emit('checking-for-update');
squirrelUpdate.checkForUpdate(this.updateURL, (error, update) => { squirrelUpdate.checkForUpdate(this.updateURL, (error, update) => {
if (error != null) { if (error != null) {
return this.emitError(error) return this.emitError(error);
} }
if (update == null) { if (update == null) {
return this.emit('update-not-available') return this.emit('update-not-available');
} }
this.updateAvailable = true this.updateAvailable = true;
this.emit('update-available') this.emit('update-available');
squirrelUpdate.update(this.updateURL, (error) => { squirrelUpdate.update(this.updateURL, (error) => {
if (error != null) { if (error != null) {
return this.emitError(error) return this.emitError(error);
} }
const { releaseNotes, version } = update const { releaseNotes, version } = update;
// Date is not available on Windows, so fake it. // Date is not available on Windows, so fake it.
const date = new Date() const date = new Date();
this.emit('update-downloaded', {}, releaseNotes, version, date, this.updateURL, () => { this.emit('update-downloaded', {}, releaseNotes, version, date, this.updateURL, () => {
this.quitAndInstall() this.quitAndInstall();
}) });
}) });
}) });
} }
// Private: Emit both error object and message, this is to keep compatibility // Private: Emit both error object and message, this is to keep compatibility
// with Old APIs. // with Old APIs.
emitError (message) { emitError (message) {
this.emit('error', new Error(message), message) this.emit('error', new Error(message), message);
} }
} }
module.exports = new AutoUpdater() module.exports = new AutoUpdater();

View File

@@ -1,24 +1,24 @@
'use strict' 'use strict';
const fs = require('fs') const fs = require('fs');
const path = require('path') const path = require('path');
const spawn = require('child_process').spawn const spawn = require('child_process').spawn;
// i.e. my-app/app-0.1.13/ // i.e. my-app/app-0.1.13/
const appFolder = path.dirname(process.execPath) const appFolder = path.dirname(process.execPath);
// i.e. my-app/Update.exe // i.e. my-app/Update.exe
const updateExe = path.resolve(appFolder, '..', 'Update.exe') const updateExe = path.resolve(appFolder, '..', 'Update.exe');
const exeName = path.basename(process.execPath) const exeName = path.basename(process.execPath);
let spawnedArgs = [] let spawnedArgs = [];
let spawnedProcess let spawnedProcess;
const isSameArgs = (args) => args.length === spawnedArgs.length && args.every((e, i) => e === spawnedArgs[i]) const isSameArgs = (args) => args.length === spawnedArgs.length && args.every((e, i) => e === spawnedArgs[i]);
// Spawn a command and invoke the callback when it completes with an error // Spawn a command and invoke the callback when it completes with an error
// and the output from standard out. // and the output from standard out.
const spawnUpdate = function (args, detached, callback) { const spawnUpdate = function (args, detached, callback) {
let error, errorEmitted, stderr, stdout let error, errorEmitted, stderr, stdout;
try { try {
// Ensure we don't spawn multiple squirrel processes // Ensure we don't spawn multiple squirrel processes
@@ -28,92 +28,92 @@ const spawnUpdate = function (args, detached, callback) {
if (spawnedProcess && !isSameArgs(args)) { if (spawnedProcess && !isSameArgs(args)) {
// Disabled for backwards compatibility: // Disabled for backwards compatibility:
// eslint-disable-next-line standard/no-callback-literal // eslint-disable-next-line standard/no-callback-literal
return callback(`AutoUpdater process with arguments ${args} is already running`) return callback(`AutoUpdater process with arguments ${args} is already running`);
} else if (!spawnedProcess) { } else if (!spawnedProcess) {
spawnedProcess = spawn(updateExe, args, { spawnedProcess = spawn(updateExe, args, {
detached: detached, detached: detached,
windowsHide: true windowsHide: true
}) });
spawnedArgs = args || [] spawnedArgs = args || [];
} }
} catch (error1) { } catch (error1) {
error = error1 error = error1;
// Shouldn't happen, but still guard it. // Shouldn't happen, but still guard it.
process.nextTick(function () { process.nextTick(function () {
return callback(error) return callback(error);
}) });
return return;
} }
stdout = '' stdout = '';
stderr = '' stderr = '';
spawnedProcess.stdout.on('data', (data) => { stdout += data }) spawnedProcess.stdout.on('data', (data) => { stdout += data; });
spawnedProcess.stderr.on('data', (data) => { stderr += data }) spawnedProcess.stderr.on('data', (data) => { stderr += data; });
errorEmitted = false errorEmitted = false;
spawnedProcess.on('error', (error) => { spawnedProcess.on('error', (error) => {
errorEmitted = true errorEmitted = true;
callback(error) callback(error);
}) });
return spawnedProcess.on('exit', function (code, signal) { return spawnedProcess.on('exit', function (code, signal) {
spawnedProcess = undefined spawnedProcess = undefined;
spawnedArgs = [] spawnedArgs = [];
// We may have already emitted an error. // We may have already emitted an error.
if (errorEmitted) { if (errorEmitted) {
return return;
} }
// Process terminated with error. // Process terminated with error.
if (code !== 0) { if (code !== 0) {
// Disabled for backwards compatibility: // Disabled for backwards compatibility:
// eslint-disable-next-line standard/no-callback-literal // eslint-disable-next-line standard/no-callback-literal
return callback(`Command failed: ${signal != null ? signal : code}\n${stderr}`) return callback(`Command failed: ${signal != null ? signal : code}\n${stderr}`);
} }
// Success. // Success.
callback(null, stdout) callback(null, stdout);
}) });
} };
// Start an instance of the installed app. // Start an instance of the installed app.
exports.processStart = function () { exports.processStart = function () {
return spawnUpdate(['--processStartAndWait', exeName], true, function () {}) return spawnUpdate(['--processStartAndWait', exeName], true, function () {});
} };
// Download the releases specified by the URL and write new results to stdout. // Download the releases specified by the URL and write new results to stdout.
exports.checkForUpdate = function (updateURL, callback) { exports.checkForUpdate = function (updateURL, callback) {
return spawnUpdate(['--checkForUpdate', updateURL], false, function (error, stdout) { return spawnUpdate(['--checkForUpdate', updateURL], false, function (error, stdout) {
let ref, ref1, update let ref, ref1, update;
if (error != null) { if (error != null) {
return callback(error) return callback(error);
} }
try { try {
// Last line of output is the JSON details about the releases // Last line of output is the JSON details about the releases
const json = stdout.trim().split('\n').pop() const json = stdout.trim().split('\n').pop();
update = (ref = JSON.parse(json)) != null ? (ref1 = ref.releasesToApply) != null ? typeof ref1.pop === 'function' ? ref1.pop() : void 0 : void 0 : void 0 update = (ref = JSON.parse(json)) != null ? (ref1 = ref.releasesToApply) != null ? typeof ref1.pop === 'function' ? ref1.pop() : void 0 : void 0 : void 0;
} catch { } catch {
// Disabled for backwards compatibility: // Disabled for backwards compatibility:
// eslint-disable-next-line standard/no-callback-literal // eslint-disable-next-line standard/no-callback-literal
return callback(`Invalid result:\n${stdout}`) return callback(`Invalid result:\n${stdout}`);
} }
return callback(null, update) return callback(null, update);
}) });
} };
// Update the application to the latest remote version specified by URL. // Update the application to the latest remote version specified by URL.
exports.update = function (updateURL, callback) { exports.update = function (updateURL, callback) {
return spawnUpdate(['--update', updateURL], false, callback) return spawnUpdate(['--update', updateURL], false, callback);
} };
// Is the Update.exe installed with the current application? // Is the Update.exe installed with the current application?
exports.supported = function () { exports.supported = function () {
try { try {
fs.accessSync(updateExe, fs.R_OK) fs.accessSync(updateExe, fs.R_OK);
return true return true;
} catch { } catch {
return false return false;
} }
} };

View File

@@ -1,16 +1,16 @@
'use strict' 'use strict';
const { EventEmitter } = require('events') const { EventEmitter } = require('events');
const { BrowserView } = process.electronBinding('browser_view') const { BrowserView } = process.electronBinding('browser_view');
Object.setPrototypeOf(BrowserView.prototype, EventEmitter.prototype) Object.setPrototypeOf(BrowserView.prototype, EventEmitter.prototype);
BrowserView.fromWebContents = (webContents) => { BrowserView.fromWebContents = (webContents) => {
for (const view of BrowserView.getAllViews()) { for (const view of BrowserView.getAllViews()) {
if (view.webContents.equal(webContents)) return view if (view.webContents.equal(webContents)) return view;
} }
return null return null;
} };
module.exports = BrowserView module.exports = BrowserView;

View File

@@ -1,49 +1,49 @@
'use strict' 'use strict';
const electron = require('electron') const electron = require('electron');
const { WebContentsView, TopLevelWindow, deprecate } = electron const { WebContentsView, TopLevelWindow, deprecate } = electron;
const { BrowserWindow } = process.electronBinding('window') const { BrowserWindow } = process.electronBinding('window');
Object.setPrototypeOf(BrowserWindow.prototype, TopLevelWindow.prototype) Object.setPrototypeOf(BrowserWindow.prototype, TopLevelWindow.prototype);
BrowserWindow.prototype._init = function () { BrowserWindow.prototype._init = function () {
// Call parent class's _init. // Call parent class's _init.
TopLevelWindow.prototype._init.call(this) TopLevelWindow.prototype._init.call(this);
// Avoid recursive require. // Avoid recursive require.
const { app } = electron const { app } = electron;
// Create WebContentsView. // Create WebContentsView.
this.setContentView(new WebContentsView(this.webContents)) this.setContentView(new WebContentsView(this.webContents));
const nativeSetBounds = this.setBounds const nativeSetBounds = this.setBounds;
this.setBounds = (bounds, ...opts) => { this.setBounds = (bounds, ...opts) => {
bounds = { bounds = {
...this.getBounds(), ...this.getBounds(),
...bounds ...bounds
} };
nativeSetBounds.call(this, bounds, ...opts) nativeSetBounds.call(this, bounds, ...opts);
} };
// window.resizeTo(...) // window.resizeTo(...)
// window.moveTo(...) // window.moveTo(...)
this.webContents.on('move', (event, size) => { this.webContents.on('move', (event, size) => {
this.setBounds(size) this.setBounds(size);
}) });
// Hide the auto-hide menu when webContents is focused. // Hide the auto-hide menu when webContents is focused.
this.webContents.on('activate', () => { this.webContents.on('activate', () => {
if (process.platform !== 'darwin' && this.autoHideMenuBar && this.isMenuBarVisible()) { if (process.platform !== 'darwin' && this.autoHideMenuBar && this.isMenuBarVisible()) {
this.setMenuBarVisibility(false) this.setMenuBarVisibility(false);
} }
}) });
// Change window title to page title. // Change window title to page title.
this.webContents.on('page-title-updated', (event, title, ...args) => { this.webContents.on('page-title-updated', (event, title, ...args) => {
// Route the event to BrowserWindow. // Route the event to BrowserWindow.
this.emit('page-title-updated', event, title, ...args) this.emit('page-title-updated', event, title, ...args);
if (!this.isDestroyed() && !event.defaultPrevented) this.setTitle(title) if (!this.isDestroyed() && !event.defaultPrevented) this.setTitle(title);
}) });
// Sometimes the webContents doesn't get focus when window is shown, so we // Sometimes the webContents doesn't get focus when window is shown, so we
// have to force focusing on webContents in this case. The safest way is to // have to force focusing on webContents in this case. The safest way is to
@@ -54,144 +54,135 @@ BrowserWindow.prototype._init = function () {
// Finder, we still do it on all platforms in case of other bugs we don't // Finder, we still do it on all platforms in case of other bugs we don't
// know. // know.
this.webContents.once('load-url', function () { this.webContents.once('load-url', function () {
this.focus() this.focus();
}) });
// Redirect focus/blur event to app instance too. // Redirect focus/blur event to app instance too.
this.on('blur', (event) => { this.on('blur', (event) => {
app.emit('browser-window-blur', event, this) app.emit('browser-window-blur', event, this);
}) });
this.on('focus', (event) => { this.on('focus', (event) => {
app.emit('browser-window-focus', event, this) app.emit('browser-window-focus', event, this);
}) });
// Subscribe to visibilityState changes and pass to renderer process. // Subscribe to visibilityState changes and pass to renderer process.
let isVisible = this.isVisible() && !this.isMinimized() let isVisible = this.isVisible() && !this.isMinimized();
const visibilityChanged = () => { const visibilityChanged = () => {
const newState = this.isVisible() && !this.isMinimized() const newState = this.isVisible() && !this.isMinimized();
if (isVisible !== newState) { if (isVisible !== newState) {
isVisible = newState isVisible = newState;
const visibilityState = isVisible ? 'visible' : 'hidden' const visibilityState = isVisible ? 'visible' : 'hidden';
this.webContents.emit('-window-visibility-change', visibilityState) this.webContents.emit('-window-visibility-change', visibilityState);
} }
} };
const visibilityEvents = ['show', 'hide', 'minimize', 'maximize', 'restore'] const visibilityEvents = ['show', 'hide', 'minimize', 'maximize', 'restore'];
for (const event of visibilityEvents) { for (const event of visibilityEvents) {
this.on(event, visibilityChanged) this.on(event, visibilityChanged);
} }
// Notify the creation of the window. // Notify the creation of the window.
const event = process.electronBinding('event').createEmpty() const event = process.electronBinding('event').createEmpty();
app.emit('browser-window-created', event, this) app.emit('browser-window-created', event, this);
Object.defineProperty(this, 'devToolsWebContents', { Object.defineProperty(this, 'devToolsWebContents', {
enumerable: true, enumerable: true,
configurable: false, configurable: false,
get () { get () {
return this.webContents.devToolsWebContents return this.webContents.devToolsWebContents;
} }
}) });
} };
const isBrowserWindow = (win) => { const isBrowserWindow = (win) => {
return win && win.constructor.name === 'BrowserWindow' return win && win.constructor.name === 'BrowserWindow';
} };
BrowserWindow.fromId = (id) => { BrowserWindow.fromId = (id) => {
const win = TopLevelWindow.fromId(id) const win = TopLevelWindow.fromId(id);
return isBrowserWindow(win) ? win : null return isBrowserWindow(win) ? win : null;
} };
BrowserWindow.getAllWindows = () => { BrowserWindow.getAllWindows = () => {
return TopLevelWindow.getAllWindows().filter(isBrowserWindow) return TopLevelWindow.getAllWindows().filter(isBrowserWindow);
} };
BrowserWindow.getFocusedWindow = () => { BrowserWindow.getFocusedWindow = () => {
for (const window of BrowserWindow.getAllWindows()) { for (const window of BrowserWindow.getAllWindows()) {
if (window.isFocused() || window.isDevToolsFocused()) return window if (window.isFocused() || window.isDevToolsFocused()) return window;
} }
return null return null;
} };
BrowserWindow.fromWebContents = (webContents) => { BrowserWindow.fromWebContents = (webContents) => {
for (const window of BrowserWindow.getAllWindows()) { for (const window of BrowserWindow.getAllWindows()) {
if (window.webContents && window.webContents.equal(webContents)) return window if (window.webContents && window.webContents.equal(webContents)) return window;
} }
return null return null;
} };
BrowserWindow.fromBrowserView = (browserView) => { BrowserWindow.fromBrowserView = (browserView) => {
for (const window of BrowserWindow.getAllWindows()) { for (const window of BrowserWindow.getAllWindows()) {
if (window.getBrowserView() === browserView) return window if (window.getBrowserView() === browserView) return window;
} }
return null return null;
} };
// Helpers. // Helpers.
Object.assign(BrowserWindow.prototype, { Object.assign(BrowserWindow.prototype, {
loadURL (...args) { loadURL (...args) {
return this.webContents.loadURL(...args) return this.webContents.loadURL(...args);
}, },
getURL (...args) { getURL (...args) {
return this.webContents.getURL() return this.webContents.getURL();
}, },
loadFile (...args) { loadFile (...args) {
return this.webContents.loadFile(...args) return this.webContents.loadFile(...args);
}, },
reload (...args) { reload (...args) {
return this.webContents.reload(...args) return this.webContents.reload(...args);
}, },
send (...args) { send (...args) {
return this.webContents.send(...args) return this.webContents.send(...args);
}, },
openDevTools (...args) { openDevTools (...args) {
return this.webContents.openDevTools(...args) return this.webContents.openDevTools(...args);
}, },
closeDevTools () { closeDevTools () {
return this.webContents.closeDevTools() return this.webContents.closeDevTools();
}, },
isDevToolsOpened () { isDevToolsOpened () {
return this.webContents.isDevToolsOpened() return this.webContents.isDevToolsOpened();
}, },
isDevToolsFocused () { isDevToolsFocused () {
return this.webContents.isDevToolsFocused() return this.webContents.isDevToolsFocused();
}, },
toggleDevTools () { toggleDevTools () {
return this.webContents.toggleDevTools() return this.webContents.toggleDevTools();
}, },
inspectElement (...args) { inspectElement (...args) {
return this.webContents.inspectElement(...args) return this.webContents.inspectElement(...args);
}, },
inspectSharedWorker () { inspectSharedWorker () {
return this.webContents.inspectSharedWorker() return this.webContents.inspectSharedWorker();
}, },
inspectServiceWorker () { inspectServiceWorker () {
return this.webContents.inspectServiceWorker() return this.webContents.inspectServiceWorker();
}, },
showDefinitionForSelection () { showDefinitionForSelection () {
return this.webContents.showDefinitionForSelection() return this.webContents.showDefinitionForSelection();
}, },
capturePage (...args) { capturePage (...args) {
return this.webContents.capturePage(...args) return this.webContents.capturePage(...args);
}, },
setTouchBar (touchBar) { setTouchBar (touchBar) {
electron.TouchBar._setOnWindow(touchBar, this) electron.TouchBar._setOnWindow(touchBar, this);
}, },
setBackgroundThrottling (allowed) { setBackgroundThrottling (allowed) {
this.webContents.setBackgroundThrottling(allowed) this.webContents.setBackgroundThrottling(allowed);
} }
}) });
// Deprecations module.exports = BrowserWindow;
deprecate.fnToProperty(BrowserWindow.prototype, 'autoHideMenuBar', '_isMenuBarAutoHide', '_setAutoHideMenuBar')
deprecate.fnToProperty(BrowserWindow.prototype, 'minimizable', '_isMinimizable', '_setMinimizable')
deprecate.fnToProperty(BrowserWindow.prototype, 'maximizable', '_isMaximizable', '_setMaximizable')
deprecate.fnToProperty(BrowserWindow.prototype, 'resizable', '_isResizable', '_setResizable')
deprecate.fnToProperty(BrowserWindow.prototype, 'fullScreenable', '_isFullScreenable', '_setFullScreenable')
deprecate.fnToProperty(BrowserWindow.prototype, 'closable', '_isClosable', '_setClosable')
deprecate.fnToProperty(BrowserWindow.prototype, 'movable', '_isMovable', '_setMovable')
module.exports = BrowserWindow

View File

@@ -1,2 +1,2 @@
'use strict' 'use strict';
module.exports = process.electronBinding('content_tracing') module.exports = process.electronBinding('content_tracing');

View File

@@ -1,12 +0,0 @@
'use strict'
const CrashReporter = require('@electron/internal/common/crash-reporter')
const { crashReporterInit } = require('@electron/internal/browser/crash-reporter-init')
class CrashReporterMain extends CrashReporter {
init (options) {
return crashReporterInit(options)
}
}
module.exports = new CrashReporterMain()

View File

@@ -0,0 +1,83 @@
import { app } from 'electron';
const binding = process.electronBinding('crash_reporter');
class CrashReporter {
start (options: Electron.CrashReporterStartOptions) {
const {
productName = app.name,
companyName = undefined,
extra = {},
globalExtra = {},
ignoreSystemCrashHandler = false,
submitURL = undefined,
uploadToServer = true,
rateLimit = false,
compress = false
} = options || {};
if (submitURL == null) throw new Error('submitURL is a required option to crashReporter.start');
const appVersion = app.getVersion();
if (companyName && globalExtra._companyName == null) globalExtra._companyName = companyName;
const globalExtraAmended = {
_productName: productName,
_version: appVersion,
...globalExtra
};
binding.start(submitURL, uploadToServer,
ignoreSystemCrashHandler, rateLimit, compress, globalExtraAmended, extra, false);
}
getLastCrashReport () {
const reports = this.getUploadedReports()
.sort((a, b) => {
const ats = (a && a.date) ? new Date(a.date).getTime() : 0;
const bts = (b && b.date) ? new Date(b.date).getTime() : 0;
return bts - ats;
});
return (reports.length > 0) ? reports[0] : null;
}
getUploadedReports (): Electron.CrashReport[] {
return binding.getUploadedReports();
}
getCrashesDirectory () {
return app.getPath('crashDumps');
}
getUploadToServer () {
if (process.type === 'browser') {
return binding.getUploadToServer();
} else {
throw new Error('getUploadToServer can only be called from the main process');
}
}
setUploadToServer (uploadToServer: boolean) {
if (process.type === 'browser') {
return binding.setUploadToServer(uploadToServer);
} else {
throw new Error('setUploadToServer can only be called from the main process');
}
}
addExtraParameter (key: string, value: string) {
binding.addExtraParameter(key, value);
}
removeExtraParameter (key: string) {
binding.removeExtraParameter(key);
}
getParameters () {
return binding.getParameters();
}
}
export default new CrashReporter();

View File

@@ -1,13 +1,13 @@
'use strict' 'use strict';
const { app, BrowserWindow, deprecate } = require('electron') const { app, BrowserWindow, deprecate } = require('electron');
const binding = process.electronBinding('dialog') const binding = process.electronBinding('dialog');
const v8Util = process.electronBinding('v8_util') const v8Util = process.electronBinding('v8_util');
const DialogType = { const DialogType = {
OPEN: 'OPEN', OPEN: 'OPEN',
SAVE: 'SAVE' SAVE: 'SAVE'
} };
const saveFileDialogProperties = { const saveFileDialogProperties = {
createDirectory: 1 << 0, createDirectory: 1 << 0,
@@ -15,7 +15,7 @@ const saveFileDialogProperties = {
treatPackageAsDirectory: 1 << 2, treatPackageAsDirectory: 1 << 2,
showOverwriteConfirmation: 1 << 3, showOverwriteConfirmation: 1 << 3,
dontAddToRecent: 1 << 4 dontAddToRecent: 1 << 4
} };
const openFileDialogProperties = { const openFileDialogProperties = {
openFile: 1 << 0, openFile: 1 << 0,
@@ -27,15 +27,15 @@ const openFileDialogProperties = {
noResolveAliases: 1 << 6, // macOS noResolveAliases: 1 << 6, // macOS
treatPackageAsDirectory: 1 << 7, // macOS treatPackageAsDirectory: 1 << 7, // macOS
dontAddToRecent: 1 << 8 // Windows dontAddToRecent: 1 << 8 // Windows
} };
const normalizeAccessKey = (text) => { const normalizeAccessKey = (text) => {
if (typeof text !== 'string') return text if (typeof text !== 'string') return text;
// macOS does not have access keys so remove single ampersands // macOS does not have access keys so remove single ampersands
// and replace double ampersands with a single ampersand // and replace double ampersands with a single ampersand
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
return text.replace(/&(&?)/g, '$1') return text.replace(/&(&?)/g, '$1');
} }
// Linux uses a single underscore as an access key prefix so escape // Linux uses a single underscore as an access key prefix so escape
@@ -44,41 +44,41 @@ const normalizeAccessKey = (text) => {
// a single underscore // a single underscore
if (process.platform === 'linux') { if (process.platform === 'linux') {
return text.replace(/_/g, '__').replace(/&(.?)/g, (match, after) => { return text.replace(/_/g, '__').replace(/&(.?)/g, (match, after) => {
if (after === '&') return after if (after === '&') return after;
return `_${after}` return `_${after}`;
}) });
} }
return text return text;
} };
const checkAppInitialized = function () { const checkAppInitialized = function () {
if (!app.isReady()) { if (!app.isReady()) {
throw new Error('dialog module can only be used after app is ready') throw new Error('dialog module can only be used after app is ready');
} }
} };
const setupDialogProperties = (type, properties) => { const setupDialogProperties = (type, properties) => {
const dialogPropertiesTypes = (type === DialogType.OPEN) ? openFileDialogProperties : saveFileDialogProperties const dialogPropertiesTypes = (type === DialogType.OPEN) ? openFileDialogProperties : saveFileDialogProperties;
let dialogProperties = 0 let dialogProperties = 0;
for (const prop in dialogPropertiesTypes) { for (const prop in dialogPropertiesTypes) {
if (properties.includes(prop)) { if (properties.includes(prop)) {
dialogProperties |= dialogPropertiesTypes[prop] dialogProperties |= dialogPropertiesTypes[prop];
} }
} }
return dialogProperties return dialogProperties;
} };
const saveDialog = (sync, window, options) => { const saveDialog = (sync, window, options) => {
checkAppInitialized() checkAppInitialized();
if (window && window.constructor !== BrowserWindow) { if (window && window.constructor !== BrowserWindow) {
options = window options = window;
window = null window = null;
} }
if (options == null) options = { title: 'Save' } if (options == null) options = { title: 'Save' };
const { const {
buttonLabel = '', buttonLabel = '',
@@ -90,33 +90,33 @@ const saveDialog = (sync, window, options) => {
securityScopedBookmarks = false, securityScopedBookmarks = false,
nameFieldLabel = '', nameFieldLabel = '',
showsTagField = true showsTagField = true
} = options } = options;
if (typeof title !== 'string') throw new TypeError('Title must be a string') if (typeof title !== 'string') throw new TypeError('Title must be a string');
if (typeof buttonLabel !== 'string') throw new TypeError('Button label must be a string') if (typeof buttonLabel !== 'string') throw new TypeError('Button label must be a string');
if (typeof defaultPath !== 'string') throw new TypeError('Default path must be a string') if (typeof defaultPath !== 'string') throw new TypeError('Default path must be a string');
if (typeof message !== 'string') throw new TypeError('Message must be a string') if (typeof message !== 'string') throw new TypeError('Message must be a string');
if (typeof nameFieldLabel !== 'string') throw new TypeError('Name field label must be a string') if (typeof nameFieldLabel !== 'string') throw new TypeError('Name field label must be a string');
const settings = { buttonLabel, defaultPath, filters, title, message, securityScopedBookmarks, nameFieldLabel, showsTagField, window } const settings = { buttonLabel, defaultPath, filters, title, message, securityScopedBookmarks, nameFieldLabel, showsTagField, window };
settings.properties = setupDialogProperties(DialogType.SAVE, properties) settings.properties = setupDialogProperties(DialogType.SAVE, properties);
return (sync) ? binding.showSaveDialogSync(settings) : binding.showSaveDialog(settings) return (sync) ? binding.showSaveDialogSync(settings) : binding.showSaveDialog(settings);
} };
const openDialog = (sync, window, options) => { const openDialog = (sync, window, options) => {
checkAppInitialized() checkAppInitialized();
if (window && window.constructor !== BrowserWindow) { if (window && window.constructor !== BrowserWindow) {
options = window options = window;
window = null window = null;
} }
if (options == null) { if (options == null) {
options = { options = {
title: 'Open', title: 'Open',
properties: ['openFile'] properties: ['openFile']
} };
} }
const { const {
@@ -127,33 +127,33 @@ const openDialog = (sync, window, options) => {
title = '', title = '',
message = '', message = '',
securityScopedBookmarks = false securityScopedBookmarks = false
} = options } = options;
if (!Array.isArray(properties)) throw new TypeError('Properties must be an array') if (!Array.isArray(properties)) throw new TypeError('Properties must be an array');
if (typeof title !== 'string') throw new TypeError('Title must be a string') if (typeof title !== 'string') throw new TypeError('Title must be a string');
if (typeof buttonLabel !== 'string') throw new TypeError('Button label must be a string') if (typeof buttonLabel !== 'string') throw new TypeError('Button label must be a string');
if (typeof defaultPath !== 'string') throw new TypeError('Default path must be a string') if (typeof defaultPath !== 'string') throw new TypeError('Default path must be a string');
if (typeof message !== 'string') throw new TypeError('Message must be a string') if (typeof message !== 'string') throw new TypeError('Message must be a string');
const settings = { title, buttonLabel, defaultPath, filters, message, securityScopedBookmarks, window } const settings = { title, buttonLabel, defaultPath, filters, message, securityScopedBookmarks, window };
settings.properties = setupDialogProperties(DialogType.OPEN, properties) settings.properties = setupDialogProperties(DialogType.OPEN, properties);
return (sync) ? binding.showOpenDialogSync(settings) : binding.showOpenDialog(settings) return (sync) ? binding.showOpenDialogSync(settings) : binding.showOpenDialog(settings);
} };
const messageBox = (sync, window, options) => { const messageBox = (sync, window, options) => {
checkAppInitialized() checkAppInitialized();
if (window && window.constructor !== BrowserWindow) { if (window && window.constructor !== BrowserWindow) {
options = window options = window;
window = null window = null;
} }
if (options == null) options = { type: 'none' } if (options == null) options = { type: 'none' };
const messageBoxTypes = ['none', 'info', 'warning', 'error', 'question'] const messageBoxTypes = ['none', 'info', 'warning', 'error', 'question'];
const messageBoxOptions = { noLink: 1 << 0 } const messageBoxOptions = { noLink: 1 << 0 };
let { let {
buttons = [], buttons = [],
@@ -167,32 +167,32 @@ const messageBox = (sync, window, options) => {
message = '', message = '',
title = '', title = '',
type = 'none' type = 'none'
} = options } = options;
const messageBoxType = messageBoxTypes.indexOf(type) const messageBoxType = messageBoxTypes.indexOf(type);
if (messageBoxType === -1) throw new TypeError('Invalid message box type') if (messageBoxType === -1) throw new TypeError('Invalid message box type');
if (!Array.isArray(buttons)) throw new TypeError('Buttons must be an array') if (!Array.isArray(buttons)) throw new TypeError('Buttons must be an array');
if (options.normalizeAccessKeys) buttons = buttons.map(normalizeAccessKey) if (options.normalizeAccessKeys) buttons = buttons.map(normalizeAccessKey);
if (typeof title !== 'string') throw new TypeError('Title must be a string') if (typeof title !== 'string') throw new TypeError('Title must be a string');
if (typeof noLink !== 'boolean') throw new TypeError('noLink must be a boolean') if (typeof noLink !== 'boolean') throw new TypeError('noLink must be a boolean');
if (typeof message !== 'string') throw new TypeError('Message must be a string') if (typeof message !== 'string') throw new TypeError('Message must be a string');
if (typeof detail !== 'string') throw new TypeError('Detail must be a string') if (typeof detail !== 'string') throw new TypeError('Detail must be a string');
if (typeof checkboxLabel !== 'string') throw new TypeError('checkboxLabel must be a string') if (typeof checkboxLabel !== 'string') throw new TypeError('checkboxLabel must be a string');
checkboxChecked = !!checkboxChecked checkboxChecked = !!checkboxChecked;
if (checkboxChecked && !checkboxLabel) { if (checkboxChecked && !checkboxLabel) {
throw new Error('checkboxChecked requires that checkboxLabel also be passed') throw new Error('checkboxChecked requires that checkboxLabel also be passed');
} }
// Choose a default button to get selected when dialog is cancelled. // Choose a default button to get selected when dialog is cancelled.
if (cancelId == null) { if (cancelId == null) {
// If the defaultId is set to 0, ensure the cancel button is a different index (1) // If the defaultId is set to 0, ensure the cancel button is a different index (1)
cancelId = (defaultId === 0 && buttons.length > 1) ? 1 : 0 cancelId = (defaultId === 0 && buttons.length > 1) ? 1 : 0;
for (let i = 0; i < buttons.length; i++) { for (let i = 0; i < buttons.length; i++) {
const text = buttons[i].toLowerCase() const text = buttons[i].toLowerCase();
if (text === 'cancel' || text === 'no') { if (text === 'cancel' || text === 'no') {
cancelId = i cancelId = i;
break break;
} }
} }
} }
@@ -210,57 +210,57 @@ const messageBox = (sync, window, options) => {
checkboxLabel, checkboxLabel,
checkboxChecked, checkboxChecked,
icon icon
} };
if (sync) { if (sync) {
return binding.showMessageBoxSync(settings) return binding.showMessageBoxSync(settings);
} else { } else {
return binding.showMessageBox(settings) return binding.showMessageBox(settings);
} }
} };
module.exports = { module.exports = {
showOpenDialog: function (window, options) { showOpenDialog: function (window, options) {
return openDialog(false, window, options) return openDialog(false, window, options);
}, },
showOpenDialogSync: function (window, options) { showOpenDialogSync: function (window, options) {
return openDialog(true, window, options) return openDialog(true, window, options);
}, },
showSaveDialog: function (window, options) { showSaveDialog: function (window, options) {
return saveDialog(false, window, options) return saveDialog(false, window, options);
}, },
showSaveDialogSync: function (window, options) { showSaveDialogSync: function (window, options) {
return saveDialog(true, window, options) return saveDialog(true, window, options);
}, },
showMessageBox: function (window, options) { showMessageBox: function (window, options) {
return messageBox(false, window, options) return messageBox(false, window, options);
}, },
showMessageBoxSync: function (window, options) { showMessageBoxSync: function (window, options) {
return messageBox(true, window, options) return messageBox(true, window, options);
}, },
showErrorBox: function (...args) { showErrorBox: function (...args) {
return binding.showErrorBox(...args) return binding.showErrorBox(...args);
}, },
showCertificateTrustDialog: function (window, options) { showCertificateTrustDialog: function (window, options) {
if (window && window.constructor !== BrowserWindow) options = window if (window && window.constructor !== BrowserWindow) options = window;
if (options == null || typeof options !== 'object') { if (options == null || typeof options !== 'object') {
throw new TypeError('options must be an object') throw new TypeError('options must be an object');
} }
const { certificate, message = '' } = options const { certificate, message = '' } = options;
if (certificate == null || typeof certificate !== 'object') { if (certificate == null || typeof certificate !== 'object') {
throw new TypeError('certificate must be an object') throw new TypeError('certificate must be an object');
} }
if (typeof message !== 'string') throw new TypeError('message must be a string') if (typeof message !== 'string') throw new TypeError('message must be a string');
return binding.showCertificateTrustDialog(window, certificate, message) return binding.showCertificateTrustDialog(window, certificate, message);
} }
} };

View File

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

View File

@@ -1,3 +1,3 @@
'use strict' 'use strict';
module.exports = process.electronBinding('global_shortcut').globalShortcut module.exports = process.electronBinding('global_shortcut').globalShortcut;

View File

@@ -1,22 +1,22 @@
'use strict' 'use strict';
const { deprecate } = require('electron') const { deprecate } = require('electron');
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
const { EventEmitter } = require('events') const { EventEmitter } = require('events');
const { inAppPurchase, InAppPurchase } = process.electronBinding('in_app_purchase') const { inAppPurchase, InAppPurchase } = process.electronBinding('in_app_purchase');
// inAppPurchase is an EventEmitter. // inAppPurchase is an EventEmitter.
Object.setPrototypeOf(InAppPurchase.prototype, EventEmitter.prototype) Object.setPrototypeOf(InAppPurchase.prototype, EventEmitter.prototype);
EventEmitter.call(inAppPurchase) EventEmitter.call(inAppPurchase);
module.exports = inAppPurchase module.exports = inAppPurchase;
} else { } else {
module.exports = { module.exports = {
purchaseProduct: (productID, quantity, callback) => { purchaseProduct: (productID, quantity, callback) => {
throw new Error('The inAppPurchase module can only be used on macOS') throw new Error('The inAppPurchase module can only be used on macOS');
}, },
canMakePayments: () => false, canMakePayments: () => false,
getReceiptURL: () => '' getReceiptURL: () => ''
} };
} }

View File

@@ -1,8 +1,8 @@
import { IpcMainImpl } from '@electron/internal/browser/ipc-main-impl' import { IpcMainImpl } from '@electron/internal/browser/ipc-main-impl';
const ipcMain = new IpcMainImpl() const ipcMain = new IpcMainImpl();
// Do not throw exception when channel name is "error". // Do not throw exception when channel name is "error".
ipcMain.on('error', () => {}) ipcMain.on('error', () => {});
export default ipcMain export default ipcMain;

View File

@@ -1,16 +1,17 @@
'use strict' 'use strict';
const { app } = require('electron') const { app } = require('electron');
const isMac = process.platform === 'darwin' const isMac = process.platform === 'darwin';
const isWindows = process.platform === 'win32' const isWindows = process.platform === 'win32';
const isLinux = process.platform === 'linux' const isLinux = process.platform === 'linux';
const roles = { const roles = {
about: { about: {
get label () { get label () {
return isLinux ? 'About' : `About ${app.name}` return isLinux ? 'About' : `About ${app.name}`;
} },
...(isWindows && { appMethod: 'showAboutPanel' })
}, },
close: { close: {
label: isMac ? 'Close Window' : 'Close', label: isMac ? 'Close Window' : 'Close',
@@ -38,7 +39,7 @@ const roles = {
accelerator: 'Shift+CmdOrCtrl+R', accelerator: 'Shift+CmdOrCtrl+R',
nonNativeMacOSRole: true, nonNativeMacOSRole: true,
windowMethod: (window) => { windowMethod: (window) => {
window.webContents.reloadIgnoringCache() window.webContents.reloadIgnoringCache();
} }
}, },
front: { front: {
@@ -49,7 +50,7 @@ const roles = {
}, },
hide: { hide: {
get label () { get label () {
return `Hide ${app.name}` return `Hide ${app.name}`;
}, },
accelerator: 'Command+H' accelerator: 'Command+H'
}, },
@@ -77,9 +78,9 @@ const roles = {
quit: { quit: {
get label () { get label () {
switch (process.platform) { switch (process.platform) {
case 'darwin': return `Quit ${app.name}` case 'darwin': return `Quit ${app.name}`;
case 'win32': return 'Exit' case 'win32': return 'Exit';
default: return 'Quit' default: return 'Quit';
} }
}, },
accelerator: isWindows ? undefined : 'CommandOrControl+Q', accelerator: isWindows ? undefined : 'CommandOrControl+Q',
@@ -101,7 +102,7 @@ const roles = {
accelerator: 'CommandOrControl+0', accelerator: 'CommandOrControl+0',
nonNativeMacOSRole: true, nonNativeMacOSRole: true,
webContentsMethod: (webContents) => { webContentsMethod: (webContents) => {
webContents.zoomLevel = 0 webContents.zoomLevel = 0;
} }
}, },
selectall: { selectall: {
@@ -134,7 +135,7 @@ const roles = {
label: 'Toggle Full Screen', label: 'Toggle Full Screen',
accelerator: isMac ? 'Control+Command+F' : 'F11', accelerator: isMac ? 'Control+Command+F' : 'F11',
windowMethod: (window) => { windowMethod: (window) => {
window.setFullScreen(!window.isFullScreen()) window.setFullScreen(!window.isFullScreen());
} }
}, },
undo: { undo: {
@@ -156,7 +157,7 @@ const roles = {
accelerator: 'CommandOrControl+Plus', accelerator: 'CommandOrControl+Plus',
nonNativeMacOSRole: true, nonNativeMacOSRole: true,
webContentsMethod: (webContents) => { webContentsMethod: (webContents) => {
webContents.zoomLevel += 0.5 webContents.zoomLevel += 0.5;
} }
}, },
zoomout: { zoomout: {
@@ -164,13 +165,13 @@ const roles = {
accelerator: 'CommandOrControl+-', accelerator: 'CommandOrControl+-',
nonNativeMacOSRole: true, nonNativeMacOSRole: true,
webContentsMethod: (webContents) => { webContentsMethod: (webContents) => {
webContents.zoomLevel -= 0.5 webContents.zoomLevel -= 0.5;
} }
}, },
// App submenu should be used for Mac only // App submenu should be used for Mac only
appmenu: { appmenu: {
get label () { get label () {
return app.name return app.name;
}, },
submenu: [ submenu: [
{ role: 'about' }, { role: 'about' },
@@ -249,71 +250,71 @@ const roles = {
]) ])
] ]
} }
} };
exports.roleList = roles exports.roleList = roles;
const canExecuteRole = (role) => { const canExecuteRole = (role) => {
if (!roles.hasOwnProperty(role)) return false if (!roles.hasOwnProperty(role)) return false;
if (!isMac) return true if (!isMac) return true;
// macOS handles all roles natively except for a few // macOS handles all roles natively except for a few
return roles[role].nonNativeMacOSRole return roles[role].nonNativeMacOSRole;
} };
exports.getDefaultLabel = (role) => { exports.getDefaultLabel = (role) => {
return roles.hasOwnProperty(role) ? roles[role].label : '' return roles.hasOwnProperty(role) ? roles[role].label : '';
} };
exports.getDefaultAccelerator = (role) => { exports.getDefaultAccelerator = (role) => {
if (roles.hasOwnProperty(role)) return roles[role].accelerator if (roles.hasOwnProperty(role)) return roles[role].accelerator;
} };
exports.shouldRegisterAccelerator = (role) => { exports.shouldRegisterAccelerator = (role) => {
const hasRoleRegister = roles.hasOwnProperty(role) && roles[role].registerAccelerator !== undefined const hasRoleRegister = roles.hasOwnProperty(role) && roles[role].registerAccelerator !== undefined;
return hasRoleRegister ? roles[role].registerAccelerator : true return hasRoleRegister ? roles[role].registerAccelerator : true;
} };
exports.getDefaultSubmenu = (role) => { exports.getDefaultSubmenu = (role) => {
if (!roles.hasOwnProperty(role)) return if (!roles.hasOwnProperty(role)) return;
let { submenu } = roles[role] let { submenu } = roles[role];
// remove null items from within the submenu // remove null items from within the submenu
if (Array.isArray(submenu)) { if (Array.isArray(submenu)) {
submenu = submenu.filter((item) => item != null) submenu = submenu.filter((item) => item != null);
} }
return submenu return submenu;
} };
exports.execute = (role, focusedWindow, focusedWebContents) => { exports.execute = (role, focusedWindow, focusedWebContents) => {
if (!canExecuteRole(role)) return false if (!canExecuteRole(role)) return false;
const { appMethod, webContentsMethod, windowMethod } = roles[role] const { appMethod, webContentsMethod, windowMethod } = roles[role];
if (appMethod) { if (appMethod) {
app[appMethod]() app[appMethod]();
return true return true;
} }
if (windowMethod && focusedWindow != null) { if (windowMethod && focusedWindow != null) {
if (typeof windowMethod === 'function') { if (typeof windowMethod === 'function') {
windowMethod(focusedWindow) windowMethod(focusedWindow);
} else { } else {
focusedWindow[windowMethod]() focusedWindow[windowMethod]();
} }
return true return true;
} }
if (webContentsMethod && focusedWebContents != null) { if (webContentsMethod && focusedWebContents != null) {
if (typeof webContentsMethod === 'function') { if (typeof webContentsMethod === 'function') {
webContentsMethod(focusedWebContents) webContentsMethod(focusedWebContents);
} else { } else {
focusedWebContents[webContentsMethod]() focusedWebContents[webContentsMethod]();
} }
return true return true;
} }
return false return false;
} };

View File

@@ -1,87 +1,87 @@
'use strict' 'use strict';
const roles = require('@electron/internal/browser/api/menu-item-roles') const roles = require('@electron/internal/browser/api/menu-item-roles');
let nextCommandId = 0 let nextCommandId = 0;
const MenuItem = function (options) { const MenuItem = function (options) {
const { Menu } = require('electron') const { Menu } = require('electron');
// Preserve extra fields specified by user // Preserve extra fields specified by user
for (const key in options) { for (const key in options) {
if (!(key in this)) this[key] = options[key] if (!(key in this)) this[key] = options[key];
} }
if (typeof this.role === 'string' || this.role instanceof String) { if (typeof this.role === 'string' || this.role instanceof String) {
this.role = this.role.toLowerCase() this.role = this.role.toLowerCase();
} }
this.submenu = this.submenu || roles.getDefaultSubmenu(this.role) this.submenu = this.submenu || roles.getDefaultSubmenu(this.role);
if (this.submenu != null && this.submenu.constructor !== Menu) { if (this.submenu != null && this.submenu.constructor !== Menu) {
this.submenu = Menu.buildFromTemplate(this.submenu) this.submenu = Menu.buildFromTemplate(this.submenu);
} }
if (this.type == null && this.submenu != null) { if (this.type == null && this.submenu != null) {
this.type = 'submenu' this.type = 'submenu';
} }
if (this.type === 'submenu' && (this.submenu == null || this.submenu.constructor !== Menu)) { if (this.type === 'submenu' && (this.submenu == null || this.submenu.constructor !== Menu)) {
throw new Error('Invalid submenu') throw new Error('Invalid submenu');
} }
this.overrideReadOnlyProperty('type', 'normal') this.overrideReadOnlyProperty('type', 'normal');
this.overrideReadOnlyProperty('role') this.overrideReadOnlyProperty('role');
this.overrideReadOnlyProperty('accelerator') this.overrideReadOnlyProperty('accelerator');
this.overrideReadOnlyProperty('icon') this.overrideReadOnlyProperty('icon');
this.overrideReadOnlyProperty('submenu') this.overrideReadOnlyProperty('submenu');
this.overrideProperty('label', roles.getDefaultLabel(this.role)) this.overrideProperty('label', roles.getDefaultLabel(this.role));
this.overrideProperty('sublabel', '') this.overrideProperty('sublabel', '');
this.overrideProperty('toolTip', '') this.overrideProperty('toolTip', '');
this.overrideProperty('enabled', true) this.overrideProperty('enabled', true);
this.overrideProperty('visible', true) this.overrideProperty('visible', true);
this.overrideProperty('checked', false) this.overrideProperty('checked', false);
this.overrideProperty('acceleratorWorksWhenHidden', true) this.overrideProperty('acceleratorWorksWhenHidden', true);
this.overrideProperty('registerAccelerator', roles.shouldRegisterAccelerator(this.role)) this.overrideProperty('registerAccelerator', roles.shouldRegisterAccelerator(this.role));
if (!MenuItem.types.includes(this.type)) { if (!MenuItem.types.includes(this.type)) {
throw new Error(`Unknown menu item type: ${this.type}`) throw new Error(`Unknown menu item type: ${this.type}`);
} }
this.overrideReadOnlyProperty('commandId', ++nextCommandId) this.overrideReadOnlyProperty('commandId', ++nextCommandId);
const click = options.click const click = options.click;
this.click = (event, focusedWindow, focusedWebContents) => { this.click = (event, focusedWindow, focusedWebContents) => {
// Manually flip the checked flags when clicked. // Manually flip the checked flags when clicked.
if (this.type === 'checkbox' || this.type === 'radio') { if (this.type === 'checkbox' || this.type === 'radio') {
this.checked = !this.checked this.checked = !this.checked;
} }
if (!roles.execute(this.role, focusedWindow, focusedWebContents)) { if (!roles.execute(this.role, focusedWindow, focusedWebContents)) {
if (typeof click === 'function') { if (typeof click === 'function') {
click(this, focusedWindow, event) click(this, focusedWindow, event);
} else if (typeof this.selector === 'string' && process.platform === 'darwin') { } else if (typeof this.selector === 'string' && process.platform === 'darwin') {
Menu.sendActionToFirstResponder(this.selector) Menu.sendActionToFirstResponder(this.selector);
} }
} }
} };
} };
MenuItem.types = ['normal', 'separator', 'submenu', 'checkbox', 'radio'] MenuItem.types = ['normal', 'separator', 'submenu', 'checkbox', 'radio'];
MenuItem.prototype.getDefaultRoleAccelerator = function () { MenuItem.prototype.getDefaultRoleAccelerator = function () {
return roles.getDefaultAccelerator(this.role) return roles.getDefaultAccelerator(this.role);
} };
MenuItem.prototype.overrideProperty = function (name, defaultValue = null) { MenuItem.prototype.overrideProperty = function (name, defaultValue = null) {
if (this[name] == null) { if (this[name] == null) {
this[name] = defaultValue this[name] = defaultValue;
} }
} };
MenuItem.prototype.overrideReadOnlyProperty = function (name, defaultValue) { MenuItem.prototype.overrideReadOnlyProperty = function (name, defaultValue) {
this.overrideProperty(name, defaultValue) this.overrideProperty(name, defaultValue);
Object.defineProperty(this, name, { Object.defineProperty(this, name, {
enumerable: true, enumerable: true,
writable: false, writable: false,
value: this[name] value: this[name]
}) });
} };
module.exports = MenuItem module.exports = MenuItem;

View File

@@ -1,41 +1,41 @@
'use strict' 'use strict';
function splitArray (arr, predicate) { function splitArray (arr, predicate) {
const result = arr.reduce((multi, item) => { const result = arr.reduce((multi, item) => {
const current = multi[multi.length - 1] const current = multi[multi.length - 1];
if (predicate(item)) { if (predicate(item)) {
if (current.length > 0) multi.push([]) if (current.length > 0) multi.push([]);
} else { } else {
current.push(item) current.push(item);
} }
return multi return multi;
}, [[]]) }, [[]]);
if (result[result.length - 1].length === 0) { if (result[result.length - 1].length === 0) {
return result.slice(0, result.length - 1) return result.slice(0, result.length - 1);
} }
return result return result;
} }
function joinArrays (arrays, joinIDs) { function joinArrays (arrays, joinIDs) {
return arrays.reduce((joined, arr, i) => { return arrays.reduce((joined, arr, i) => {
if (i > 0 && arr.length) { if (i > 0 && arr.length) {
if (joinIDs.length > 0) { if (joinIDs.length > 0) {
joined.push(joinIDs[0]) joined.push(joinIDs[0]);
joinIDs.splice(0, 1) joinIDs.splice(0, 1);
} else { } else {
joined.push({ type: 'separator' }) joined.push({ type: 'separator' });
} }
} }
return joined.concat(arr) return joined.concat(arr);
}, []) }, []);
} }
function pushOntoMultiMap (map, key, value) { function pushOntoMultiMap (map, key, value) {
if (!map.has(key)) { if (!map.has(key)) {
map.set(key, []) map.set(key, []);
} }
map.get(key).push(value) map.get(key).push(value);
} }
function indexOfGroupContainingID (groups, id, ignoreGroup) { function indexOfGroupContainingID (groups, id, ignoreGroup) {
@@ -45,102 +45,102 @@ function indexOfGroupContainingID (groups, id, ignoreGroup) {
candidateGroup.some( candidateGroup.some(
candidateItem => candidateItem.id === id candidateItem => candidateItem.id === id
) )
) );
} }
// Sort nodes topologically using a depth-first approach. Encountered cycles // Sort nodes topologically using a depth-first approach. Encountered cycles
// are broken. // are broken.
function sortTopologically (originalOrder, edgesById) { function sortTopologically (originalOrder, edgesById) {
const sorted = [] const sorted = [];
const marked = new Set() const marked = new Set();
const visit = (mark) => { const visit = (mark) => {
if (marked.has(mark)) return if (marked.has(mark)) return;
marked.add(mark) marked.add(mark);
const edges = edgesById.get(mark) const edges = edgesById.get(mark);
if (edges != null) { if (edges != null) {
edges.forEach(visit) edges.forEach(visit);
} }
sorted.push(mark) sorted.push(mark);
} };
originalOrder.forEach(visit) originalOrder.forEach(visit);
return sorted return sorted;
} }
function attemptToMergeAGroup (groups) { function attemptToMergeAGroup (groups) {
for (let i = 0; i < groups.length; i++) { for (let i = 0; i < groups.length; i++) {
const group = groups[i] const group = groups[i];
for (const item of group) { for (const item of group) {
const toIDs = [...(item.before || []), ...(item.after || [])] const toIDs = [...(item.before || []), ...(item.after || [])];
for (const id of toIDs) { for (const id of toIDs) {
const index = indexOfGroupContainingID(groups, id, group) const index = indexOfGroupContainingID(groups, id, group);
if (index === -1) continue if (index === -1) continue;
const mergeTarget = groups[index] const mergeTarget = groups[index];
mergeTarget.push(...group) mergeTarget.push(...group);
groups.splice(i, 1) groups.splice(i, 1);
return true return true;
} }
} }
} }
return false return false;
} }
function mergeGroups (groups) { function mergeGroups (groups) {
let merged = true let merged = true;
while (merged) { while (merged) {
merged = attemptToMergeAGroup(groups) merged = attemptToMergeAGroup(groups);
} }
return groups return groups;
} }
function sortItemsInGroup (group) { function sortItemsInGroup (group) {
const originalOrder = group.map((node, i) => i) const originalOrder = group.map((node, i) => i);
const edges = new Map() const edges = new Map();
const idToIndex = new Map(group.map((item, i) => [item.id, i])) const idToIndex = new Map(group.map((item, i) => [item.id, i]));
group.forEach((item, i) => { group.forEach((item, i) => {
if (item.before) { if (item.before) {
item.before.forEach(toID => { item.before.forEach(toID => {
const to = idToIndex.get(toID) const to = idToIndex.get(toID);
if (to != null) { if (to != null) {
pushOntoMultiMap(edges, to, i) pushOntoMultiMap(edges, to, i);
} }
}) });
} }
if (item.after) { if (item.after) {
item.after.forEach(toID => { item.after.forEach(toID => {
const to = idToIndex.get(toID) const to = idToIndex.get(toID);
if (to != null) { if (to != null) {
pushOntoMultiMap(edges, i, to) pushOntoMultiMap(edges, i, to);
} }
}) });
} }
}) });
const sortedNodes = sortTopologically(originalOrder, edges) const sortedNodes = sortTopologically(originalOrder, edges);
return sortedNodes.map(i => group[i]) return sortedNodes.map(i => group[i]);
} }
function findEdgesInGroup (groups, i, edges) { function findEdgesInGroup (groups, i, edges) {
const group = groups[i] const group = groups[i];
for (const item of group) { for (const item of group) {
if (item.beforeGroupContaining) { if (item.beforeGroupContaining) {
for (const id of item.beforeGroupContaining) { for (const id of item.beforeGroupContaining) {
const to = indexOfGroupContainingID(groups, id, group) const to = indexOfGroupContainingID(groups, id, group);
if (to !== -1) { if (to !== -1) {
pushOntoMultiMap(edges, to, i) pushOntoMultiMap(edges, to, i);
return return;
} }
} }
} }
if (item.afterGroupContaining) { if (item.afterGroupContaining) {
for (const id of item.afterGroupContaining) { for (const id of item.afterGroupContaining) {
const to = indexOfGroupContainingID(groups, id, group) const to = indexOfGroupContainingID(groups, id, group);
if (to !== -1) { if (to !== -1) {
pushOntoMultiMap(edges, i, to) pushOntoMultiMap(edges, i, to);
return return;
} }
} }
} }
@@ -148,29 +148,29 @@ function findEdgesInGroup (groups, i, edges) {
} }
function sortGroups (groups) { function sortGroups (groups) {
const originalOrder = groups.map((item, i) => i) const originalOrder = groups.map((item, i) => i);
const edges = new Map() const edges = new Map();
for (let i = 0; i < groups.length; i++) { for (let i = 0; i < groups.length; i++) {
findEdgesInGroup(groups, i, edges) findEdgesInGroup(groups, i, edges);
} }
const sortedGroupIndexes = sortTopologically(originalOrder, edges) const sortedGroupIndexes = sortTopologically(originalOrder, edges);
return sortedGroupIndexes.map(i => groups[i]) return sortedGroupIndexes.map(i => groups[i]);
} }
function sortMenuItems (menuItems) { function sortMenuItems (menuItems) {
const isSeparator = (item) => item.type === 'separator' const isSeparator = (item) => item.type === 'separator';
const separators = menuItems.filter(i => i.type === 'separator') const separators = menuItems.filter(i => i.type === 'separator');
// Split the items into their implicit groups based upon separators. // Split the items into their implicit groups based upon separators.
const groups = splitArray(menuItems, isSeparator) const groups = splitArray(menuItems, isSeparator);
const mergedGroups = mergeGroups(groups) const mergedGroups = mergeGroups(groups);
const mergedGroupsWithSortedItems = mergedGroups.map(sortItemsInGroup) const mergedGroupsWithSortedItems = mergedGroups.map(sortItemsInGroup);
const sortedGroups = sortGroups(mergedGroupsWithSortedItems) const sortedGroups = sortGroups(mergedGroupsWithSortedItems);
const joined = joinArrays(sortedGroups, separators) const joined = joinArrays(sortedGroups, separators);
return joined return joined;
} }
module.exports = { sortMenuItems } module.exports = { sortMenuItems };

View File

@@ -1,16 +1,16 @@
'use strict' 'use strict';
const { TopLevelWindow, MenuItem, webContents } = require('electron') const { TopLevelWindow, MenuItem, webContents } = require('electron');
const { sortMenuItems } = require('@electron/internal/browser/api/menu-utils') const { sortMenuItems } = require('@electron/internal/browser/api/menu-utils');
const EventEmitter = require('events').EventEmitter const EventEmitter = require('events').EventEmitter;
const v8Util = process.electronBinding('v8_util') const v8Util = process.electronBinding('v8_util');
const bindings = process.electronBinding('menu') const bindings = process.electronBinding('menu');
const { Menu } = bindings const { Menu } = bindings;
let applicationMenu = null let applicationMenu = null;
let groupIdIndex = 0 let groupIdIndex = 0;
Object.setPrototypeOf(Menu.prototype, EventEmitter.prototype) Object.setPrototypeOf(Menu.prototype, EventEmitter.prototype);
// Menu Delegate. // Menu Delegate.
// This object should hold no reference to |Menu| to avoid cyclic reference. // This object should hold no reference to |Menu| to avoid cyclic reference.
@@ -20,172 +20,172 @@ const delegate = {
shouldCommandIdWorkWhenHidden: (menu, id) => menu.commandsMap[id] ? menu.commandsMap[id].acceleratorWorksWhenHidden : undefined, shouldCommandIdWorkWhenHidden: (menu, id) => menu.commandsMap[id] ? menu.commandsMap[id].acceleratorWorksWhenHidden : undefined,
isCommandIdVisible: (menu, id) => menu.commandsMap[id] ? menu.commandsMap[id].visible : undefined, isCommandIdVisible: (menu, id) => menu.commandsMap[id] ? menu.commandsMap[id].visible : undefined,
getAcceleratorForCommandId: (menu, id, useDefaultAccelerator) => { getAcceleratorForCommandId: (menu, id, useDefaultAccelerator) => {
const command = menu.commandsMap[id] const command = menu.commandsMap[id];
if (!command) return if (!command) return;
if (command.accelerator != null) return command.accelerator if (command.accelerator != null) return command.accelerator;
if (useDefaultAccelerator) return command.getDefaultRoleAccelerator() if (useDefaultAccelerator) return command.getDefaultRoleAccelerator();
}, },
shouldRegisterAcceleratorForCommandId: (menu, id) => menu.commandsMap[id] ? menu.commandsMap[id].registerAccelerator : undefined, shouldRegisterAcceleratorForCommandId: (menu, id) => menu.commandsMap[id] ? menu.commandsMap[id].registerAccelerator : undefined,
executeCommand: (menu, event, id) => { executeCommand: (menu, event, id) => {
const command = menu.commandsMap[id] const command = menu.commandsMap[id];
if (!command) return if (!command) return;
command.click(event, TopLevelWindow.getFocusedWindow(), webContents.getFocusedWebContents()) command.click(event, TopLevelWindow.getFocusedWindow(), webContents.getFocusedWebContents());
}, },
menuWillShow: (menu) => { menuWillShow: (menu) => {
// Ensure radio groups have at least one menu item selected // Ensure radio groups have at least one menu item selected
for (const id in menu.groupsMap) { for (const id of Object.keys(menu.groupsMap)) {
const found = menu.groupsMap[id].find(item => item.checked) || null const found = menu.groupsMap[id].find(item => item.checked) || null;
if (!found) v8Util.setHiddenValue(menu.groupsMap[id][0], 'checked', true) if (!found) v8Util.setHiddenValue(menu.groupsMap[id][0], 'checked', true);
} }
} }
} };
/* Instance Methods */ /* Instance Methods */
Menu.prototype._init = function () { Menu.prototype._init = function () {
this.commandsMap = {} this.commandsMap = {};
this.groupsMap = {} this.groupsMap = {};
this.items = [] this.items = [];
this.delegate = delegate this.delegate = delegate;
} };
Menu.prototype.popup = function (options = {}) { Menu.prototype.popup = function (options = {}) {
if (options == null || typeof options !== 'object') { if (options == null || typeof options !== 'object') {
throw new TypeError('Options must be an object') throw new TypeError('Options must be an object');
} }
let { window, x, y, positioningItem, callback } = options let { window, x, y, positioningItem, callback } = options;
// no callback passed // no callback passed
if (!callback || typeof callback !== 'function') callback = () => {} if (!callback || typeof callback !== 'function') callback = () => {};
// set defaults // set defaults
if (typeof x !== 'number') x = -1 if (typeof x !== 'number') x = -1;
if (typeof y !== 'number') y = -1 if (typeof y !== 'number') y = -1;
if (typeof positioningItem !== 'number') positioningItem = -1 if (typeof positioningItem !== 'number') positioningItem = -1;
// find which window to use // find which window to use
const wins = TopLevelWindow.getAllWindows() const wins = TopLevelWindow.getAllWindows();
if (!wins || wins.indexOf(window) === -1) { if (!wins || wins.indexOf(window) === -1) {
window = TopLevelWindow.getFocusedWindow() window = TopLevelWindow.getFocusedWindow();
if (!window && wins && wins.length > 0) { if (!window && wins && wins.length > 0) {
window = wins[0] window = wins[0];
} }
if (!window) { if (!window) {
throw new Error(`Cannot open Menu without a TopLevelWindow present`) throw new Error(`Cannot open Menu without a TopLevelWindow present`);
} }
} }
this.popupAt(window, x, y, positioningItem, callback) this.popupAt(window, x, y, positioningItem, callback);
return { browserWindow: window, x, y, position: positioningItem } return { browserWindow: window, x, y, position: positioningItem };
} };
Menu.prototype.closePopup = function (window) { Menu.prototype.closePopup = function (window) {
if (window instanceof TopLevelWindow) { if (window instanceof TopLevelWindow) {
this.closePopupAt(window.id) this.closePopupAt(window.id);
} else { } else {
// Passing -1 (invalid) would make closePopupAt close the all menu runners // Passing -1 (invalid) would make closePopupAt close the all menu runners
// belong to this menu. // belong to this menu.
this.closePopupAt(-1) this.closePopupAt(-1);
} }
} };
Menu.prototype.getMenuItemById = function (id) { Menu.prototype.getMenuItemById = function (id) {
const items = this.items const items = this.items;
let found = items.find(item => item.id === id) || null let found = items.find(item => item.id === id) || null;
for (let i = 0; !found && i < items.length; i++) { for (let i = 0; !found && i < items.length; i++) {
if (items[i].submenu) { if (items[i].submenu) {
found = items[i].submenu.getMenuItemById(id) found = items[i].submenu.getMenuItemById(id);
} }
} }
return found return found;
} };
Menu.prototype.append = function (item) { Menu.prototype.append = function (item) {
return this.insert(this.getItemCount(), item) return this.insert(this.getItemCount(), item);
} };
Menu.prototype.insert = function (pos, item) { Menu.prototype.insert = function (pos, item) {
if ((item ? item.constructor : void 0) !== MenuItem) { if ((item ? item.constructor : void 0) !== MenuItem) {
throw new TypeError('Invalid item') throw new TypeError('Invalid item');
} }
if (pos < 0) { if (pos < 0) {
throw new RangeError(`Position ${pos} cannot be less than 0`) throw new RangeError(`Position ${pos} cannot be less than 0`);
} else if (pos > this.getItemCount()) { } else if (pos > this.getItemCount()) {
throw new RangeError(`Position ${pos} cannot be greater than the total MenuItem count`) throw new RangeError(`Position ${pos} cannot be greater than the total MenuItem count`);
} }
// insert item depending on its type // insert item depending on its type
insertItemByType.call(this, item, pos) insertItemByType.call(this, item, pos);
// set item properties // set item properties
if (item.sublabel) this.setSublabel(pos, item.sublabel) if (item.sublabel) this.setSublabel(pos, item.sublabel);
if (item.toolTip) this.setToolTip(pos, item.toolTip) if (item.toolTip) this.setToolTip(pos, item.toolTip);
if (item.icon) this.setIcon(pos, item.icon) if (item.icon) this.setIcon(pos, item.icon);
if (item.role) this.setRole(pos, item.role) if (item.role) this.setRole(pos, item.role);
// Make menu accessable to items. // Make menu accessable to items.
item.overrideReadOnlyProperty('menu', this) item.overrideReadOnlyProperty('menu', this);
// Remember the items. // Remember the items.
this.items.splice(pos, 0, item) this.items.splice(pos, 0, item);
this.commandsMap[item.commandId] = item this.commandsMap[item.commandId] = item;
} };
Menu.prototype._callMenuWillShow = function () { Menu.prototype._callMenuWillShow = function () {
if (this.delegate) this.delegate.menuWillShow(this) if (this.delegate) this.delegate.menuWillShow(this);
this.items.forEach(item => { this.items.forEach(item => {
if (item.submenu) item.submenu._callMenuWillShow() if (item.submenu) item.submenu._callMenuWillShow();
}) });
} };
/* Static Methods */ /* Static Methods */
Menu.getApplicationMenu = () => applicationMenu Menu.getApplicationMenu = () => applicationMenu;
Menu.sendActionToFirstResponder = bindings.sendActionToFirstResponder Menu.sendActionToFirstResponder = bindings.sendActionToFirstResponder;
// set application menu with a preexisting menu // set application menu with a preexisting menu
Menu.setApplicationMenu = function (menu) { Menu.setApplicationMenu = function (menu) {
if (menu && menu.constructor !== Menu) { if (menu && menu.constructor !== Menu) {
throw new TypeError('Invalid menu') throw new TypeError('Invalid menu');
} }
applicationMenu = menu applicationMenu = menu;
v8Util.setHiddenValue(global, 'applicationMenuSet', true) v8Util.setHiddenValue(global, 'applicationMenuSet', true);
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
if (!menu) return if (!menu) return;
menu._callMenuWillShow() menu._callMenuWillShow();
bindings.setApplicationMenu(menu) bindings.setApplicationMenu(menu);
} else { } else {
const windows = TopLevelWindow.getAllWindows() const windows = TopLevelWindow.getAllWindows();
return windows.map(w => w.setMenu(menu)) return windows.map(w => w.setMenu(menu));
} }
} };
Menu.buildFromTemplate = function (template) { Menu.buildFromTemplate = function (template) {
if (!Array.isArray(template)) { if (!Array.isArray(template)) {
throw new TypeError('Invalid template for Menu: Menu template must be an array') throw new TypeError('Invalid template for Menu: Menu template must be an array');
} }
if (!areValidTemplateItems(template)) { if (!areValidTemplateItems(template)) {
throw new TypeError('Invalid template for MenuItem: must have at least one of label, role or type') throw new TypeError('Invalid template for MenuItem: must have at least one of label, role or type');
} }
const filtered = removeExtraSeparators(template) const filtered = removeExtraSeparators(template);
const sorted = sortTemplate(filtered) const sorted = sortTemplate(filtered);
const menu = new Menu() const menu = new Menu();
sorted.forEach(item => { sorted.forEach(item => {
if (item instanceof MenuItem) { if (item instanceof MenuItem) {
menu.append(item) menu.append(item);
} else { } else {
menu.append(new MenuItem(item)) menu.append(new MenuItem(item));
} }
}) });
return menu return menu;
} };
/* Helper Functions */ /* Helper Functions */
@@ -196,51 +196,50 @@ function areValidTemplateItems (template) {
typeof item === 'object' && typeof item === 'object' &&
(item.hasOwnProperty('label') || (item.hasOwnProperty('label') ||
item.hasOwnProperty('role') || item.hasOwnProperty('role') ||
item.type === 'separator')) item.type === 'separator'));
} }
function sortTemplate (template) { function sortTemplate (template) {
const sorted = sortMenuItems(template) const sorted = sortMenuItems(template);
for (const id in sorted) { for (const item of sorted) {
const item = sorted[id]
if (Array.isArray(item.submenu)) { if (Array.isArray(item.submenu)) {
item.submenu = sortTemplate(item.submenu) item.submenu = sortTemplate(item.submenu);
} }
} }
return sorted return sorted;
} }
// Search between separators to find a radio menu item and return its group id // Search between separators to find a radio menu item and return its group id
function generateGroupId (items, pos) { function generateGroupId (items, pos) {
if (pos > 0) { if (pos > 0) {
for (let idx = pos - 1; idx >= 0; idx--) { for (let idx = pos - 1; idx >= 0; idx--) {
if (items[idx].type === 'radio') return items[idx].groupId if (items[idx].type === 'radio') return items[idx].groupId;
if (items[idx].type === 'separator') break if (items[idx].type === 'separator') break;
} }
} else if (pos < items.length) { } else if (pos < items.length) {
for (let idx = pos; idx <= items.length - 1; idx++) { for (let idx = pos; idx <= items.length - 1; idx++) {
if (items[idx].type === 'radio') return items[idx].groupId if (items[idx].type === 'radio') return items[idx].groupId;
if (items[idx].type === 'separator') break if (items[idx].type === 'separator') break;
} }
} }
groupIdIndex += 1 groupIdIndex += 1;
return groupIdIndex return groupIdIndex;
} }
function removeExtraSeparators (items) { function removeExtraSeparators (items) {
// fold adjacent separators together // fold adjacent separators together
let ret = items.filter((e, idx, arr) => { let ret = items.filter((e, idx, arr) => {
if (e.visible === false) return true if (e.visible === false) return true;
return e.type !== 'separator' || idx === 0 || arr[idx - 1].type !== 'separator' return e.type !== 'separator' || idx === 0 || arr[idx - 1].type !== 'separator';
}) });
// remove edge separators // remove edge separators
ret = ret.filter((e, idx, arr) => { ret = ret.filter((e, idx, arr) => {
if (e.visible === false) return true if (e.visible === false) return true;
return e.type !== 'separator' || (idx !== 0 && idx !== arr.length - 1) return e.type !== 'separator' || (idx !== 0 && idx !== arr.length - 1);
}) });
return ret return ret;
} }
function insertItemByType (item, pos) { function insertItemByType (item, pos) {
@@ -251,28 +250,28 @@ function insertItemByType (item, pos) {
submenu: () => this.insertSubMenu(pos, item.commandId, item.label, item.submenu), submenu: () => this.insertSubMenu(pos, item.commandId, item.label, item.submenu),
radio: () => { radio: () => {
// Grouping radio menu items // Grouping radio menu items
item.overrideReadOnlyProperty('groupId', generateGroupId(this.items, pos)) item.overrideReadOnlyProperty('groupId', generateGroupId(this.items, pos));
if (this.groupsMap[item.groupId] == null) { if (this.groupsMap[item.groupId] == null) {
this.groupsMap[item.groupId] = [] this.groupsMap[item.groupId] = [];
} }
this.groupsMap[item.groupId].push(item) this.groupsMap[item.groupId].push(item);
// Setting a radio menu item should flip other items in the group. // Setting a radio menu item should flip other items in the group.
v8Util.setHiddenValue(item, 'checked', item.checked) v8Util.setHiddenValue(item, 'checked', item.checked);
Object.defineProperty(item, 'checked', { Object.defineProperty(item, 'checked', {
enumerable: true, enumerable: true,
get: () => v8Util.getHiddenValue(item, 'checked'), get: () => v8Util.getHiddenValue(item, 'checked'),
set: () => { set: () => {
this.groupsMap[item.groupId].forEach(other => { this.groupsMap[item.groupId].forEach(other => {
if (other !== item) v8Util.setHiddenValue(other, 'checked', false) if (other !== item) v8Util.setHiddenValue(other, 'checked', false);
}) });
v8Util.setHiddenValue(item, 'checked', true) v8Util.setHiddenValue(item, 'checked', true);
} }
}) });
this.insertRadioItem(pos, item.commandId, item.label, item.groupId) this.insertRadioItem(pos, item.commandId, item.label, item.groupId);
} }
} };
types[item.type]() types[item.type]();
} }
module.exports = Menu module.exports = Menu;

View File

@@ -1,52 +0,0 @@
'use strict'
// TODO: Figure out a way to not duplicate this information between here and module-list
// It is currently duplicated as module-list "require"s all the browser API file and the
// remote module in the renderer process depends on that file. As a result webpack
// includes all the browser API files in the renderer process as well and we want to avoid that
const features = process.electronBinding('features')
// Browser side modules, please sort alphabetically.
module.exports = [
{ name: 'app' },
{ name: 'autoUpdater' },
{ name: 'BrowserView' },
{ name: 'BrowserWindow' },
{ name: 'contentTracing' },
{ name: 'crashReporter' },
{ name: 'dialog' },
{ name: 'globalShortcut' },
{ name: 'ipcMain' },
{ name: 'inAppPurchase' },
{ name: 'Menu' },
{ name: 'MenuItem' },
{ name: 'nativeTheme' },
{ name: 'net' },
{ name: 'netLog' },
{ name: 'Notification' },
{ name: 'powerMonitor' },
{ name: 'powerSaveBlocker' },
{ name: 'protocol' },
{ name: 'screen' },
{ name: 'session' },
{ name: 'systemPreferences' },
{ name: 'TopLevelWindow' },
{ name: 'TouchBar' },
{ name: 'Tray' },
{ name: 'View' },
{ name: 'webContents' },
{ name: 'WebContentsView' }
]
if (features.isViewApiEnabled()) {
module.exports.push(
{ name: 'BoxLayout' },
{ name: 'Button' },
{ name: 'LabelButton' },
{ name: 'LayoutManager' },
{ name: 'MdTextButton' },
{ name: 'ResizeArea' },
{ name: 'TextField' }
)
}

View File

@@ -1,7 +1,5 @@
// TODO: Updating this file also required updating the module-keys file // TODO: Updating this file also required updating the module-keys file
const features = process.electronBinding('features')
// Browser side modules, please sort alphabetically. // Browser side modules, please sort alphabetically.
export const browserModuleList: ElectronInternal.ModuleEntry[] = [ export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'app', loader: () => require('./app') }, { name: 'app', loader: () => require('./app') },
@@ -32,16 +30,16 @@ export const browserModuleList: ElectronInternal.ModuleEntry[] = [
{ name: 'View', loader: () => require('./view') }, { name: 'View', loader: () => require('./view') },
{ name: 'webContents', loader: () => require('./web-contents') }, { name: 'webContents', loader: () => require('./web-contents') },
{ name: 'WebContentsView', loader: () => require('./web-contents-view') } { name: 'WebContentsView', loader: () => require('./web-contents-view') }
] ];
if (features.isViewApiEnabled()) { if (BUILDFLAG(ENABLE_VIEW_API)) {
browserModuleList.push( browserModuleList.push(
{ name: 'BoxLayout', loader: () => require('./views/box-layout') }, { name: 'BoxLayout', loader: () => require('@electron/internal/browser/api/views/box-layout') },
{ name: 'Button', loader: () => require('./views/button') }, { name: 'Button', loader: () => require('@electron/internal/browser/api/views/button') },
{ name: 'LabelButton', loader: () => require('./views/label-button') }, { name: 'LabelButton', loader: () => require('@electron/internal/browser/api/views/label-button') },
{ name: 'LayoutManager', loader: () => require('./views/layout-manager') }, { name: 'LayoutManager', loader: () => require('@electron/internal/browser/api/views/layout-manager') },
{ name: 'MdTextButton', loader: () => require('./views/md-text-button') }, { name: 'MdTextButton', loader: () => require('@electron/internal/browser/api/views/md-text-button') },
{ name: 'ResizeArea', loader: () => require('./views/resize-area') }, { name: 'ResizeArea', loader: () => require('@electron/internal/browser/api/views/resize-area') },
{ name: 'TextField', loader: () => require('./views/text-field') } { name: 'TextField', loader: () => require('@electron/internal/browser/api/views/text-field') }
) );
} }

View File

@@ -0,0 +1,48 @@
// TODO: Figure out a way to not duplicate this information between here and module-list
// It is currently duplicated as module-list "require"s all the browser API file and the
// remote module in the renderer process depends on that file. As a result webpack
// includes all the browser API files in the renderer process as well and we want to avoid that
// Browser side modules, please sort alphabetically.
export const browserModuleNames = [
'app',
'autoUpdater',
'BrowserView',
'BrowserWindow',
'contentTracing',
'crashReporter',
'dialog',
'globalShortcut',
'ipcMain',
'inAppPurchase',
'Menu',
'MenuItem',
'nativeTheme',
'net',
'netLog',
'Notification',
'powerMonitor',
'powerSaveBlocker',
'protocol',
'screen',
'session',
'systemPreferences',
'TopLevelWindow',
'TouchBar',
'Tray',
'View',
'webContents',
'WebContentsView'
];
if (BUILDFLAG(ENABLE_VIEW_API)) {
browserModuleNames.push(
'BoxLayout',
'Button',
'LabelButton',
'LayoutManager',
'MdTextButton',
'ResizeArea',
'TextField'
);
}

View File

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

View File

@@ -1,32 +1,32 @@
'use strict' 'use strict';
// TODO(deepak1556): Deprecate and remove standalone netLog module, // TODO(deepak1556): Deprecate and remove standalone netLog module,
// it is now a property of session module. // it is now a property of session module.
const { app, session } = require('electron') const { app, session } = require('electron');
// Fallback to default session. // Fallback to default session.
Object.setPrototypeOf(module.exports, new Proxy({}, { Object.setPrototypeOf(module.exports, new Proxy({}, {
get (target, property) { get (target, property) {
if (!app.isReady()) return if (!app.isReady()) return;
const netLog = session.defaultSession.netLog const netLog = session.defaultSession.netLog;
if (!Object.getPrototypeOf(netLog).hasOwnProperty(property)) return if (!Object.getPrototypeOf(netLog).hasOwnProperty(property)) return;
// check for properties on the prototype chain that aren't functions // check for properties on the prototype chain that aren't functions
if (typeof netLog[property] !== 'function') return netLog[property] if (typeof netLog[property] !== 'function') return netLog[property];
// Returning a native function directly would throw error. // Returning a native function directly would throw error.
return (...args) => netLog[property](...args) return (...args) => netLog[property](...args);
}, },
ownKeys () { ownKeys () {
if (!app.isReady()) return [] if (!app.isReady()) return [];
return Object.getOwnPropertyNames(Object.getPrototypeOf(session.defaultSession.netLog)) return Object.getOwnPropertyNames(Object.getPrototypeOf(session.defaultSession.netLog));
}, },
getOwnPropertyDescriptor (target) { getOwnPropertyDescriptor (target) {
return { configurable: true, enumerable: true } return { configurable: true, enumerable: true };
} }
})) }));

View File

@@ -1,16 +1,16 @@
'use strict' 'use strict';
const url = require('url') const url = require('url');
const { EventEmitter } = require('events') const { EventEmitter } = require('events');
const { Readable, Writable } = require('stream') const { Readable, Writable } = require('stream');
const { app } = require('electron') const { app } = require('electron');
const { Session } = process.electronBinding('session') const { Session } = process.electronBinding('session');
const { net, Net, _isValidHeaderName, _isValidHeaderValue } = process.electronBinding('net') const { net, Net, _isValidHeaderName, _isValidHeaderValue } = process.electronBinding('net');
const { URLLoader } = net const { URLLoader } = net;
Object.setPrototypeOf(URLLoader.prototype, EventEmitter.prototype) Object.setPrototypeOf(URLLoader.prototype, EventEmitter.prototype);
const kSupportedProtocols = new Set(['http:', 'https:']) const kSupportedProtocols = new Set(['http:', 'https:']);
// set of headers that Node.js discards duplicates for // set of headers that Node.js discards duplicates for
// see https://nodejs.org/api/http.html#http_message_headers // see https://nodejs.org/api/http.html#http_message_headers
@@ -33,27 +33,27 @@ const discardableDuplicateHeaders = new Set([
'server', 'server',
'age', 'age',
'expires' 'expires'
]) ]);
class IncomingMessage extends Readable { class IncomingMessage extends Readable {
constructor (responseHead) { constructor (responseHead) {
super() super();
this._shouldPush = false this._shouldPush = false;
this._data = [] this._data = [];
this._responseHead = responseHead this._responseHead = responseHead;
} }
get statusCode () { get statusCode () {
return this._responseHead.statusCode return this._responseHead.statusCode;
} }
get statusMessage () { get statusMessage () {
return this._responseHead.statusMessage return this._responseHead.statusMessage;
} }
get headers () { get headers () {
const filteredHeaders = {} const filteredHeaders = {};
const { rawHeaders } = this._responseHead const { rawHeaders } = this._responseHead;
rawHeaders.forEach(header => { rawHeaders.forEach(header => {
if (Object.prototype.hasOwnProperty.call(filteredHeaders, header.key) && if (Object.prototype.hasOwnProperty.call(filteredHeaders, header.key) &&
discardableDuplicateHeaders.has(header.key)) { discardableDuplicateHeaders.has(header.key)) {
@@ -63,145 +63,145 @@ class IncomingMessage extends Readable {
// keep set-cookie as an array per Node.js rules // keep set-cookie as an array per Node.js rules
// see https://nodejs.org/api/http.html#http_message_headers // see https://nodejs.org/api/http.html#http_message_headers
if (Object.prototype.hasOwnProperty.call(filteredHeaders, header.key)) { if (Object.prototype.hasOwnProperty.call(filteredHeaders, header.key)) {
filteredHeaders[header.key].push(header.value) filteredHeaders[header.key].push(header.value);
} else { } else {
filteredHeaders[header.key] = [header.value] filteredHeaders[header.key] = [header.value];
} }
} else { } else {
// for non-cookie headers, the values are joined together with ', ' // for non-cookie headers, the values are joined together with ', '
if (Object.prototype.hasOwnProperty.call(filteredHeaders, header.key)) { if (Object.prototype.hasOwnProperty.call(filteredHeaders, header.key)) {
filteredHeaders[header.key] += `, ${header.value}` filteredHeaders[header.key] += `, ${header.value}`;
} else { } else {
filteredHeaders[header.key] = header.value filteredHeaders[header.key] = header.value;
} }
} }
} }
}) });
return filteredHeaders return filteredHeaders;
} }
get httpVersion () { get httpVersion () {
return `${this.httpVersionMajor}.${this.httpVersionMinor}` return `${this.httpVersionMajor}.${this.httpVersionMinor}`;
} }
get httpVersionMajor () { get httpVersionMajor () {
return this._responseHead.httpVersion.major return this._responseHead.httpVersion.major;
} }
get httpVersionMinor () { get httpVersionMinor () {
return this._responseHead.httpVersion.minor return this._responseHead.httpVersion.minor;
} }
get rawTrailers () { get rawTrailers () {
throw new Error('HTTP trailers are not supported') throw new Error('HTTP trailers are not supported');
} }
get trailers () { get trailers () {
throw new Error('HTTP trailers are not supported') throw new Error('HTTP trailers are not supported');
} }
_storeInternalData (chunk) { _storeInternalData (chunk) {
this._data.push(chunk) this._data.push(chunk);
this._pushInternalData() this._pushInternalData();
} }
_pushInternalData () { _pushInternalData () {
while (this._shouldPush && this._data.length > 0) { while (this._shouldPush && this._data.length > 0) {
const chunk = this._data.shift() const chunk = this._data.shift();
this._shouldPush = this.push(chunk) this._shouldPush = this.push(chunk);
} }
} }
_read () { _read () {
this._shouldPush = true this._shouldPush = true;
this._pushInternalData() this._pushInternalData();
} }
} }
/** Writable stream that buffers up everything written to it. */ /** Writable stream that buffers up everything written to it. */
class SlurpStream extends Writable { class SlurpStream extends Writable {
constructor () { constructor () {
super() super();
this._data = Buffer.alloc(0) this._data = Buffer.alloc(0);
} }
_write (chunk, encoding, callback) { _write (chunk, encoding, callback) {
this._data = Buffer.concat([this._data, chunk]) this._data = Buffer.concat([this._data, chunk]);
callback() callback();
} }
data () { return this._data } data () { return this._data; }
} }
class ChunkedBodyStream extends Writable { class ChunkedBodyStream extends Writable {
constructor (clientRequest) { constructor (clientRequest) {
super() super();
this._clientRequest = clientRequest this._clientRequest = clientRequest;
} }
_write (chunk, encoding, callback) { _write (chunk, encoding, callback) {
if (this._downstream) { if (this._downstream) {
this._downstream.write(chunk).then(callback, callback) this._downstream.write(chunk).then(callback, callback);
} else { } else {
// the contract of _write is that we won't be called again until we call // the contract of _write is that we won't be called again until we call
// the callback, so we're good to just save a single chunk. // the callback, so we're good to just save a single chunk.
this._pendingChunk = chunk this._pendingChunk = chunk;
this._pendingCallback = callback this._pendingCallback = callback;
// The first write to a chunked body stream begins the request. // The first write to a chunked body stream begins the request.
this._clientRequest._startRequest() this._clientRequest._startRequest();
} }
} }
_final (callback) { _final (callback) {
this._downstream.done() this._downstream.done();
callback() callback();
} }
startReading (pipe) { startReading (pipe) {
if (this._downstream) { if (this._downstream) {
throw new Error('two startReading calls???') throw new Error('two startReading calls???');
} }
this._downstream = pipe this._downstream = pipe;
if (this._pendingChunk) { if (this._pendingChunk) {
const doneWriting = (maybeError) => { const doneWriting = (maybeError) => {
const cb = this._pendingCallback const cb = this._pendingCallback;
delete this._pendingCallback delete this._pendingCallback;
delete this._pendingChunk delete this._pendingChunk;
cb(maybeError) cb(maybeError);
} };
this._downstream.write(this._pendingChunk).then(doneWriting, doneWriting) this._downstream.write(this._pendingChunk).then(doneWriting, doneWriting);
} }
} }
} }
function parseOptions (options) { function parseOptions (options) {
if (typeof options === 'string') { if (typeof options === 'string') {
options = url.parse(options) options = url.parse(options);
} else { } else {
options = { ...options } options = { ...options };
} }
const method = (options.method || 'GET').toUpperCase() const method = (options.method || 'GET').toUpperCase();
let urlStr = options.url let urlStr = options.url;
if (!urlStr) { if (!urlStr) {
const urlObj = {} const urlObj = {};
const protocol = options.protocol || 'http:' const protocol = options.protocol || 'http:';
if (!kSupportedProtocols.has(protocol)) { if (!kSupportedProtocols.has(protocol)) {
throw new Error('Protocol "' + protocol + '" not supported') throw new Error('Protocol "' + protocol + '" not supported');
} }
urlObj.protocol = protocol urlObj.protocol = protocol;
if (options.host) { if (options.host) {
urlObj.host = options.host urlObj.host = options.host;
} else { } else {
if (options.hostname) { if (options.hostname) {
urlObj.hostname = options.hostname urlObj.hostname = options.hostname;
} else { } else {
urlObj.hostname = 'localhost' urlObj.hostname = 'localhost';
} }
if (options.port) { if (options.port) {
urlObj.port = options.port urlObj.port = options.port;
} }
} }
@@ -212,203 +212,205 @@ function parseOptions (options) {
// well, and b) possibly too restrictive for real-world usage. That's // well, and b) possibly too restrictive for real-world usage. That's
// why it only scans for spaces because those are guaranteed to create // why it only scans for spaces because those are guaranteed to create
// an invalid request. // an invalid request.
throw new TypeError('Request path contains unescaped characters') throw new TypeError('Request path contains unescaped characters');
} }
const pathObj = url.parse(options.path || '/') const pathObj = url.parse(options.path || '/');
urlObj.pathname = pathObj.pathname urlObj.pathname = pathObj.pathname;
urlObj.search = pathObj.search urlObj.search = pathObj.search;
urlObj.hash = pathObj.hash urlObj.hash = pathObj.hash;
urlStr = url.format(urlObj) urlStr = url.format(urlObj);
} }
const redirectPolicy = options.redirect || 'follow' const redirectPolicy = options.redirect || 'follow';
if (!['follow', 'error', 'manual'].includes(redirectPolicy)) { if (!['follow', 'error', 'manual'].includes(redirectPolicy)) {
throw new Error('redirect mode should be one of follow, error or manual') throw new Error('redirect mode should be one of follow, error or manual');
} }
if (options.headers != null && typeof options.headers !== 'object') { if (options.headers != null && typeof options.headers !== 'object') {
throw new TypeError('headers must be an object') throw new TypeError('headers must be an object');
} }
const urlLoaderOptions = { const urlLoaderOptions = {
method: method, method: method,
url: urlStr, url: urlStr,
redirectPolicy, redirectPolicy,
extraHeaders: options.headers || {} extraHeaders: options.headers || {},
} useSessionCookies: options.useSessionCookies || false
};
for (const [name, value] of Object.entries(urlLoaderOptions.extraHeaders)) { for (const [name, value] of Object.entries(urlLoaderOptions.extraHeaders)) {
if (!_isValidHeaderName(name)) { if (!_isValidHeaderName(name)) {
throw new Error(`Invalid header name: '${name}'`) throw new Error(`Invalid header name: '${name}'`);
} }
if (!_isValidHeaderValue(value.toString())) { if (!_isValidHeaderValue(value.toString())) {
throw new Error(`Invalid value for header '${name}': '${value}'`) throw new Error(`Invalid value for header '${name}': '${value}'`);
} }
} }
if (options.session) { if (options.session) {
if (options.session instanceof Session) { if (options.session instanceof Session) {
urlLoaderOptions.session = options.session urlLoaderOptions.session = options.session;
} else { } else {
throw new TypeError('`session` should be an instance of the Session class') throw new TypeError('`session` should be an instance of the Session class');
} }
} else if (options.partition) { } else if (options.partition) {
if (typeof options.partition === 'string') { if (typeof options.partition === 'string') {
urlLoaderOptions.partition = options.partition urlLoaderOptions.partition = options.partition;
} else { } else {
throw new TypeError('`partition` should be a string') throw new TypeError('`partition` should be a string');
} }
} }
return urlLoaderOptions return urlLoaderOptions;
} }
class ClientRequest extends Writable { class ClientRequest extends Writable {
constructor (options, callback) { constructor (options, callback) {
super({ autoDestroy: true }) super({ autoDestroy: true });
if (!app.isReady()) { if (!app.isReady()) {
throw new Error('net module can only be used after app is ready') throw new Error('net module can only be used after app is ready');
} }
if (callback) { if (callback) {
this.once('response', callback) this.once('response', callback);
} }
const { redirectPolicy, ...urlLoaderOptions } = parseOptions(options) const { redirectPolicy, ...urlLoaderOptions } = parseOptions(options);
this._urlLoaderOptions = urlLoaderOptions this._urlLoaderOptions = urlLoaderOptions;
this._redirectPolicy = redirectPolicy this._redirectPolicy = redirectPolicy;
this._started = false this._started = false;
} }
set chunkedEncoding (value) { set chunkedEncoding (value) {
if (this._started) { if (this._started) {
throw new Error('chunkedEncoding can only be set before the request is started') throw new Error('chunkedEncoding can only be set before the request is started');
} }
if (typeof this._chunkedEncoding !== 'undefined') { if (typeof this._chunkedEncoding !== 'undefined') {
throw new Error('chunkedEncoding can only be set once') throw new Error('chunkedEncoding can only be set once');
} }
this._chunkedEncoding = !!value this._chunkedEncoding = !!value;
if (this._chunkedEncoding) { if (this._chunkedEncoding) {
this._body = new ChunkedBodyStream(this) this._body = new ChunkedBodyStream(this);
this._urlLoaderOptions.body = (pipe) => { this._urlLoaderOptions.body = (pipe) => {
this._body.startReading(pipe) this._body.startReading(pipe);
} };
} }
} }
setHeader (name, value) { setHeader (name, value) {
if (typeof name !== 'string') { if (typeof name !== 'string') {
throw new TypeError('`name` should be a string in setHeader(name, value)') throw new TypeError('`name` should be a string in setHeader(name, value)');
} }
if (value == null) { if (value == null) {
throw new Error('`value` required in setHeader("' + name + '", value)') throw new Error('`value` required in setHeader("' + name + '", value)');
} }
if (this._started || this._firstWrite) { if (this._started || this._firstWrite) {
throw new Error('Can\'t set headers after they are sent') throw new Error('Can\'t set headers after they are sent');
} }
if (!_isValidHeaderName(name)) { if (!_isValidHeaderName(name)) {
throw new Error(`Invalid header name: '${name}'`) throw new Error(`Invalid header name: '${name}'`);
} }
if (!_isValidHeaderValue(value.toString())) { if (!_isValidHeaderValue(value.toString())) {
throw new Error(`Invalid value for header '${name}': '${value}'`) throw new Error(`Invalid value for header '${name}': '${value}'`);
} }
const key = name.toLowerCase() const key = name.toLowerCase();
this._urlLoaderOptions.extraHeaders[key] = value this._urlLoaderOptions.extraHeaders[key] = value;
} }
getHeader (name) { getHeader (name) {
if (name == null) { if (name == null) {
throw new Error('`name` is required for getHeader(name)') throw new Error('`name` is required for getHeader(name)');
} }
const key = name.toLowerCase() const key = name.toLowerCase();
return this._urlLoaderOptions.extraHeaders[key] return this._urlLoaderOptions.extraHeaders[key];
} }
removeHeader (name) { removeHeader (name) {
if (name == null) { if (name == null) {
throw new Error('`name` is required for removeHeader(name)') throw new Error('`name` is required for removeHeader(name)');
} }
if (this._started || this._firstWrite) { if (this._started || this._firstWrite) {
throw new Error('Can\'t remove headers after they are sent') throw new Error('Can\'t remove headers after they are sent');
} }
const key = name.toLowerCase() const key = name.toLowerCase();
delete this._urlLoaderOptions.extraHeaders[key] delete this._urlLoaderOptions.extraHeaders[key];
} }
_write (chunk, encoding, callback) { _write (chunk, encoding, callback) {
this._firstWrite = true this._firstWrite = true;
if (!this._body) { if (!this._body) {
this._body = new SlurpStream() this._body = new SlurpStream();
this._body.on('finish', () => { this._body.on('finish', () => {
this._urlLoaderOptions.body = this._body.data() this._urlLoaderOptions.body = this._body.data();
this._startRequest() this._startRequest();
}) });
} }
// TODO: is this the right way to forward to another stream? // TODO: is this the right way to forward to another stream?
this._body.write(chunk, encoding, callback) this._body.write(chunk, encoding, callback);
} }
_final (callback) { _final (callback) {
if (this._body) { if (this._body) {
// TODO: is this the right way to forward to another stream? // TODO: is this the right way to forward to another stream?
this._body.end(callback) this._body.end(callback);
} else { } else {
// end() called without a body, go ahead and start the request // end() called without a body, go ahead and start the request
this._startRequest() this._startRequest();
callback() callback();
} }
} }
_startRequest () { _startRequest () {
this._started = true this._started = true;
const stringifyValues = (obj) => { const stringifyValues = (obj) => {
const ret = {} const ret = {};
for (const k in obj) { for (const k of Object.keys(obj)) {
ret[k] = obj[k].toString() ret[k] = obj[k].toString();
} }
return ret return ret;
} };
const opts = { ...this._urlLoaderOptions, extraHeaders: stringifyValues(this._urlLoaderOptions.extraHeaders) } this._urlLoaderOptions.referrer = this._urlLoaderOptions.extraHeaders.referer || '';
this._urlLoader = new URLLoader(opts) const opts = { ...this._urlLoaderOptions, extraHeaders: stringifyValues(this._urlLoaderOptions.extraHeaders) };
this._urlLoader = new URLLoader(opts);
this._urlLoader.on('response-started', (event, finalUrl, responseHead) => { this._urlLoader.on('response-started', (event, finalUrl, responseHead) => {
const response = this._response = new IncomingMessage(responseHead) const response = this._response = new IncomingMessage(responseHead);
this.emit('response', response) this.emit('response', response);
}) });
this._urlLoader.on('data', (event, data) => { this._urlLoader.on('data', (event, data) => {
this._response._storeInternalData(Buffer.from(data)) this._response._storeInternalData(Buffer.from(data));
}) });
this._urlLoader.on('complete', () => { this._urlLoader.on('complete', () => {
if (this._response) { this._response._storeInternalData(null) } if (this._response) { this._response._storeInternalData(null); }
}) });
this._urlLoader.on('error', (event, netErrorString) => { this._urlLoader.on('error', (event, netErrorString) => {
const error = new Error(netErrorString) const error = new Error(netErrorString);
if (this._response) this._response.destroy(error) if (this._response) this._response.destroy(error);
this._die(error) this._die(error);
}) });
this._urlLoader.on('login', (event, authInfo, callback) => { this._urlLoader.on('login', (event, authInfo, callback) => {
const handled = this.emit('login', authInfo, callback) const handled = this.emit('login', authInfo, callback);
if (!handled) { if (!handled) {
// If there were no listeners, cancel the authentication request. // If there were no listeners, cancel the authentication request.
callback() callback();
} }
}) });
this._urlLoader.on('redirect', (event, redirectInfo, headers) => { this._urlLoader.on('redirect', (event, redirectInfo, headers) => {
const { statusCode, newMethod, newUrl } = redirectInfo const { statusCode, newMethod, newUrl } = redirectInfo;
if (this._redirectPolicy === 'error') { if (this._redirectPolicy === 'error') {
this._die(new Error(`Attempted to redirect, but redirect policy was 'error'`)) this._die(new Error(`Attempted to redirect, but redirect policy was 'error'`));
} else if (this._redirectPolicy === 'manual') { } else if (this._redirectPolicy === 'manual') {
let _followRedirect = false let _followRedirect = false;
this._followRedirectCb = () => { _followRedirect = true } this._followRedirectCb = () => { _followRedirect = true; };
try { try {
this.emit('redirect', statusCode, newMethod, newUrl, headers) this.emit('redirect', statusCode, newMethod, newUrl, headers);
} finally { } finally {
this._followRedirectCb = null this._followRedirectCb = null;
if (!_followRedirect && !this._aborted) { if (!_followRedirect && !this._aborted) {
this._die(new Error('Redirect was cancelled')) this._die(new Error('Redirect was cancelled'));
} }
} }
} else if (this._redirectPolicy === 'follow') { } else if (this._redirectPolicy === 'follow') {
@@ -416,61 +418,61 @@ class ClientRequest extends Writable {
// allowed but does nothing. (Perhaps it should throw an error // allowed but does nothing. (Perhaps it should throw an error
// though...? Since the redirect will happen regardless.) // though...? Since the redirect will happen regardless.)
try { try {
this._followRedirectCb = () => {} this._followRedirectCb = () => {};
this.emit('redirect', statusCode, newMethod, newUrl, headers) this.emit('redirect', statusCode, newMethod, newUrl, headers);
} finally { } finally {
this._followRedirectCb = null this._followRedirectCb = null;
} }
} else { } else {
this._die(new Error(`Unexpected redirect policy '${this._redirectPolicy}'`)) this._die(new Error(`Unexpected redirect policy '${this._redirectPolicy}'`));
} }
}) });
this._urlLoader.on('upload-progress', (event, position, total) => { this._urlLoader.on('upload-progress', (event, position, total) => {
this._uploadProgress = { active: true, started: true, current: position, total } this._uploadProgress = { active: true, started: true, current: position, total };
this.emit('upload-progress', position, total) // Undocumented, for now this.emit('upload-progress', position, total); // Undocumented, for now
}) });
this._urlLoader.on('download-progress', (event, current) => { this._urlLoader.on('download-progress', (event, current) => {
if (this._response) { if (this._response) {
this._response.emit('download-progress', current) // Undocumented, for now this._response.emit('download-progress', current); // Undocumented, for now
} }
}) });
} }
followRedirect () { followRedirect () {
if (this._followRedirectCb) { if (this._followRedirectCb) {
this._followRedirectCb() this._followRedirectCb();
} else { } else {
throw new Error('followRedirect() called, but was not waiting for a redirect') throw new Error('followRedirect() called, but was not waiting for a redirect');
} }
} }
abort () { abort () {
if (!this._aborted) { if (!this._aborted) {
process.nextTick(() => { this.emit('abort') }) process.nextTick(() => { this.emit('abort'); });
} }
this._aborted = true this._aborted = true;
this._die() this._die();
} }
_die (err) { _die (err) {
this.destroy(err) this.destroy(err);
if (this._urlLoader) { if (this._urlLoader) {
this._urlLoader.cancel() this._urlLoader.cancel();
if (this._response) this._response.destroy(err) if (this._response) this._response.destroy(err);
} }
} }
getUploadProgress () { getUploadProgress () {
return this._uploadProgress ? { ...this._uploadProgress } : { active: false } return this._uploadProgress ? { ...this._uploadProgress } : { active: false };
} }
} }
Net.prototype.request = function (options, callback) { Net.prototype.request = function (options, callback) {
return new ClientRequest(options, callback) return new ClientRequest(options, callback);
} };
net.ClientRequest = ClientRequest net.ClientRequest = ClientRequest;
module.exports = net module.exports = net;

View File

@@ -1,10 +1,10 @@
'use strict' 'use strict';
const { EventEmitter } = require('events') const { EventEmitter } = require('events');
const { Notification, isSupported } = process.electronBinding('notification') const { Notification, isSupported } = process.electronBinding('notification');
Object.setPrototypeOf(Notification.prototype, EventEmitter.prototype) Object.setPrototypeOf(Notification.prototype, EventEmitter.prototype);
Notification.isSupported = isSupported Notification.isSupported = isSupported;
module.exports = Notification module.exports = Notification;

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